Added minor recursive implementation of MechanicalGrid

This commit is contained in:
Calclavia 2014-11-19 12:12:53 +08:00
parent e7e888f291
commit 3f03890d4e
8 changed files with 72 additions and 34 deletions

View file

@ -8,7 +8,7 @@ import resonant.lib.transform.vector.IVectorWorld
*
* @author Darkguardsman, Calclavia
*/
trait TMechanicalNode extends INode with IVectorWorld
trait TNodeMechanical extends INode with IVectorWorld
{
/**
* Gets the angular velocity of the mechanical device from a specific side
@ -31,10 +31,9 @@ trait TMechanicalNode extends INode with IVectorWorld
def getLoad = 10D
/**
* Moment of inertia = m * r * r
* Where "m" is the mass and "r" is the radius of the object.
* The radius of rotation
*/
def momentOfInertia = 2 * 0.5 * 0.5
def radius = 0.5
/**
* Does the direction flip on this side for rotation
@ -42,7 +41,7 @@ trait TMechanicalNode extends INode with IVectorWorld
* @param other - The other mechanical node
* @return boolean, true = flipped, false = not
*/
def inverseRotation(other: TMechanicalNode): Boolean = true
def inverseRotation(other: TNodeMechanical): Boolean = true
/**
* Applies rotational force and velocity to this node increasing its current rotation value

View file

@ -23,7 +23,7 @@ import resonant.lib.network.handle.IPacketReceiver
import resonant.lib.transform.vector.Vector3
import resonant.lib.utility.WrenchUtility
import resonantinduction.core.ResonantInduction
import resonantinduction.core.interfaces.TMechanicalNode
import resonantinduction.core.interfaces.TNodeMechanical
import resonantinduction.core.prefab.part.ChickenBonesWrapper._
import resonantinduction.core.prefab.part.PartFace
import resonantinduction.electrical.ElectricalContent
@ -168,7 +168,7 @@ class PartMultimeter extends PartFace with IRedstonePart with IPacketReceiver wi
if (tileEntity.isInstanceOf[INodeProvider])
{
val instance = ForgeDirection.values
.map(dir => tileEntity.asInstanceOf[INodeProvider].getNode(classOf[TMechanicalNode], dir).asInstanceOf[TMechanicalNode])
.map(dir => tileEntity.asInstanceOf[INodeProvider].getNode(classOf[TNodeMechanical], dir).asInstanceOf[TNodeMechanical])
.headOption.orNull
if (instance != null)

View file

@ -8,7 +8,7 @@ import resonant.content.loader.ContentHolder
import resonant.lib.network.discriminator.PacketAnnotationManager
import resonant.lib.recipe.UniversalRecipe
import resonant.lib.schematic.{SchematicPlate, SchematicRegistry}
import resonantinduction.core.interfaces.TMechanicalNode
import resonantinduction.core.interfaces.TNodeMechanical
import resonantinduction.core.{RICreativeTab, Reference, ResonantPartFactory}
import resonantinduction.mechanical.fluid.pipe.{ItemPipe, PartPipe, PipeMaterials}
import resonantinduction.mechanical.fluid.transport.TilePump
@ -54,7 +54,7 @@ object MechanicalContent extends ContentHolder
SchematicRegistry.register("resonantinduction.mechanical.waterTurbine", new SchematicPlate("schematic.waterTurbine.name", MechanicalContent.blockWaterTurbine))
SchematicRegistry.register("resonantinduction.mechanical.windTurbine", new SchematicPlate("schematic.windTurbine.name", MechanicalContent.blockWindTurbine))
NodeRegistry.register(classOf[TMechanicalNode], classOf[NodeMechanical])
NodeRegistry.register(classOf[TNodeMechanical], classOf[NodeMechanical])
RICreativeTab.itemStack(new ItemStack(MechanicalContent.blockGrinderWheel))

View file

@ -7,7 +7,7 @@ import net.minecraftforge.common.util.ForgeDirection
import resonant.api.grid.INodeProvider
import resonant.lib.transform.vector.Vector3
import resonant.lib.wrapper.ForgeDirectionWrapper._
import resonantinduction.core.interfaces.TMechanicalNode
import resonantinduction.core.interfaces.TNodeMechanical
import resonantinduction.mechanical.mech.gearshaft.{GearShaftNode, PartGearShaft}
import resonantinduction.mechanical.mech.grid.NodeMechanical
@ -206,9 +206,9 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
return false
}
override def inverseRotation(other: TMechanicalNode): Boolean = !other.isInstanceOf[GearShaftNode] || (other.isInstanceOf[GearShaftNode] && parent.placementSide.offset < Vector3.zero)
override def inverseRotation(other: TNodeMechanical): Boolean = !other.isInstanceOf[GearShaftNode] || (other.isInstanceOf[GearShaftNode] && parent.placementSide.offset < Vector3.zero)
override def momentOfInertia = if (gear.getMultiBlock.isConstructed) 1.5 * 1.5 else super.momentOfInertia
override def radius = if (gear.getMultiBlock.isConstructed) 1.5 * 1.5 else super.radius
/*
override def getRadius(dir: ForgeDirection, other: TMechanicalNode): Double =

View file

@ -4,7 +4,7 @@ import net.minecraftforge.common.util.ForgeDirection
import resonant.api.grid.INodeProvider
import resonant.lib.transform.vector.Vector3
import resonant.lib.wrapper.ForgeDirectionWrapper._
import resonantinduction.core.interfaces.TMechanicalNode
import resonantinduction.core.interfaces.TNodeMechanical
import resonantinduction.mechanical.mech.gear.{NodeGear, PartGear}
import resonantinduction.mechanical.mech.grid.NodeMechanical
@ -70,7 +70,7 @@ class GearShaftNode(parent: PartGearShaft) extends NodeMechanical(parent)
return from == shaft.placementSide || from == shaft.placementSide.getOpposite
}
override def inverseRotation(other: TMechanicalNode): Boolean = other.isInstanceOf[NodeGear] && other.asInstanceOf[NodeGear].parent.asInstanceOf[PartGear].placementSide.offset < Vector3.zero
override def inverseRotation(other: TNodeMechanical): Boolean = other.isInstanceOf[NodeGear] && other.asInstanceOf[NodeGear].parent.asInstanceOf[PartGear].placementSide.offset < Vector3.zero
def shaft: PartGearShaft = getParent.asInstanceOf[PartGearShaft]
}

View file

@ -49,39 +49,77 @@ class MechanicalGrid extends GridNode[NodeMechanical](classOf[NodeMechanical]) w
{
getNodes synchronized
{
getNodes.foreach(
n =>
{
n._torque = 0
n._angularVelocity = 0
}
)
getNodes.foreach(n => recurse(Seq(n)))
/*
//Find all nodes that are currently producing energy
val inputs = getNodes.filter(n => n.bufferTorque != 0)
//Calculate the total input equivalent torque
val inputTorque = inputs
.map(n => n.bufferTorque * (if (spinMap(n)) 1 else -1))
.foldLeft(0D)(_ + _)
.map(n => n.bufferTorque * (if (spinMap(n)) 1 else -1))
.foldLeft(0D)(_ + _)
val deltaTorque = if (inputTorque != 0) Math.max(Math.abs(inputTorque) - load * deltaTime, 0) * inputTorque / Math.abs(inputTorque) else 0
//Set torque and angular velocity of all nodes
getNodes.foreach(n =>
{
val prevTorque = n.torque
val prevAngularVelocity = n.angularVelocity
getNodes.foreach(
n =>
{
val prevTorque = n.torque
val prevAngularVelocity = n.angularVelocity
val inversion = if (spinMap(n)) 1 else -1
n._torque = deltaTorque * inversion
val angularAcceleration = deltaTorque / n.momentOfInertia
n._angularVelocity = angularAcceleration * deltaTime * inversion
val inversion = if (spinMap(n)) 1 else -1
n._torque = deltaTorque * inversion
val angularAcceleration = deltaTorque / n.radius
n._angularVelocity = angularAcceleration * deltaTime * inversion
if (Math.abs(n.torque - prevTorque) > 0)
n.onTorqueChanged()
if (Math.abs(n.torque - prevTorque) > 0)
n.onTorqueChanged()
if (Math.abs(n.angularVelocity - prevAngularVelocity) > 0)
n.onVelocityChanged()
if (Math.abs(n.angularVelocity - prevAngularVelocity) > 0)
n.onVelocityChanged()
//Clear buffers
n.bufferTorque = n.bufferDefaultTorque
})
//Clear buffers
n.bufferTorque = n.bufferDefaultTorque
})
*/
}
}
def recurse(passed: Seq[NodeMechanical])
{
val curr = passed(passed.size - 1)
if (passed.size > 1)
{
val prev = passed(passed.size - 2)
val ratio = curr.radius / prev.radius
val invert = if (curr.inverseRotation(prev)) 1 else -1
curr._torque += prev.torque * ratio * invert
curr._angularVelocity += prev.angularVelocity / ratio * invert
}
else
{
curr._torque += curr.bufferTorque
curr._angularVelocity += curr.bufferAngularVelocity
curr.bufferTorque = 0
curr.bufferAngularVelocity = 0
}
if (curr.power > 0)
curr.connections.foreach(c => recurse(passed :+ c))
}
override def continueUpdate = getNodes.size > 0
override def canUpdate = getNodes.size > 0

View file

@ -4,7 +4,7 @@ import resonant.api.grid.INodeProvider
import resonant.lib.grid.GridNode
import resonant.lib.grid.node.NodeGrid
import resonant.lib.transform.vector.IVectorWorld
import resonantinduction.core.interfaces.TMechanicalNode
import resonantinduction.core.interfaces.TNodeMechanical
import resonantinduction.core.prefab.node.TMultipartNode
import scala.beans.BeanProperty
@ -14,7 +14,7 @@ import scala.beans.BeanProperty
*
* @author Calclavia, Darkguardsman
*/
class NodeMechanical(parent: INodeProvider) extends NodeGrid[NodeMechanical](parent) with TMultipartNode[NodeMechanical] with TMechanicalNode with IVectorWorld
class NodeMechanical(parent: INodeProvider) extends NodeGrid[NodeMechanical](parent) with TMultipartNode[NodeMechanical] with TNodeMechanical with IVectorWorld
{
protected[grid] var _torque = 0D
protected[grid] var _angularVelocity = 0D
@ -39,6 +39,7 @@ class NodeMechanical(parent: INodeProvider) extends NodeGrid[NodeMechanical](par
* Buffer values used by the grid to transfer mechanical energy.
*/
protected[grid] var bufferTorque = 0D
protected[grid] var bufferAngularVelocity = 0D
var bufferDefaultTorque = 0D
/**

View file

@ -22,7 +22,7 @@ class NodeTurbine(parent: TileTurbine) extends NodeMechanical(parent)
* Moment of inertia = m * r * r
* Where "m" is the mass and "r" is the radius of the object.
*/
override def momentOfInertia = parent.multiBlockRadius * parent.multiBlockRadius
override def radius = parent.multiBlockRadius * parent.multiBlockRadius
def turbine: TileTurbine =
{