diff --git a/src/main/scala/resonantinduction/core/interfaces/TMechanicalNode.scala b/src/main/scala/resonantinduction/core/interfaces/TNodeMechanical.scala similarity index 80% rename from src/main/scala/resonantinduction/core/interfaces/TMechanicalNode.scala rename to src/main/scala/resonantinduction/core/interfaces/TNodeMechanical.scala index 6b8133d7f..f85ba3738 100644 --- a/src/main/scala/resonantinduction/core/interfaces/TMechanicalNode.scala +++ b/src/main/scala/resonantinduction/core/interfaces/TNodeMechanical.scala @@ -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 diff --git a/src/main/scala/resonantinduction/electrical/multimeter/PartMultimeter.scala b/src/main/scala/resonantinduction/electrical/multimeter/PartMultimeter.scala index 02e0fa81a..92ea77e47 100644 --- a/src/main/scala/resonantinduction/electrical/multimeter/PartMultimeter.scala +++ b/src/main/scala/resonantinduction/electrical/multimeter/PartMultimeter.scala @@ -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) diff --git a/src/main/scala/resonantinduction/mechanical/MechanicalContent.scala b/src/main/scala/resonantinduction/mechanical/MechanicalContent.scala index 8da74e71a..3dc336f4e 100644 --- a/src/main/scala/resonantinduction/mechanical/MechanicalContent.scala +++ b/src/main/scala/resonantinduction/mechanical/MechanicalContent.scala @@ -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)) diff --git a/src/main/scala/resonantinduction/mechanical/mech/gear/NodeGear.scala b/src/main/scala/resonantinduction/mechanical/mech/gear/NodeGear.scala index f63a22da2..b61147693 100644 --- a/src/main/scala/resonantinduction/mechanical/mech/gear/NodeGear.scala +++ b/src/main/scala/resonantinduction/mechanical/mech/gear/NodeGear.scala @@ -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 = diff --git a/src/main/scala/resonantinduction/mechanical/mech/gearshaft/GearShaftNode.scala b/src/main/scala/resonantinduction/mechanical/mech/gearshaft/GearShaftNode.scala index 3579ac2d0..478c58007 100644 --- a/src/main/scala/resonantinduction/mechanical/mech/gearshaft/GearShaftNode.scala +++ b/src/main/scala/resonantinduction/mechanical/mech/gearshaft/GearShaftNode.scala @@ -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] } \ No newline at end of file diff --git a/src/main/scala/resonantinduction/mechanical/mech/grid/MechanicalGrid.scala b/src/main/scala/resonantinduction/mechanical/mech/grid/MechanicalGrid.scala index 7fda00194..bf4ee5bd9 100644 --- a/src/main/scala/resonantinduction/mechanical/mech/grid/MechanicalGrid.scala +++ b/src/main/scala/resonantinduction/mechanical/mech/grid/MechanicalGrid.scala @@ -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 diff --git a/src/main/scala/resonantinduction/mechanical/mech/grid/NodeMechanical.scala b/src/main/scala/resonantinduction/mechanical/mech/grid/NodeMechanical.scala index 52e507c9a..9b42f74ef 100644 --- a/src/main/scala/resonantinduction/mechanical/mech/grid/NodeMechanical.scala +++ b/src/main/scala/resonantinduction/mechanical/mech/grid/NodeMechanical.scala @@ -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 /** diff --git a/src/main/scala/resonantinduction/mechanical/mech/turbine/NodeTurbine.scala b/src/main/scala/resonantinduction/mechanical/mech/turbine/NodeTurbine.scala index c968d0219..a1d39edc9 100644 --- a/src/main/scala/resonantinduction/mechanical/mech/turbine/NodeTurbine.scala +++ b/src/main/scala/resonantinduction/mechanical/mech/turbine/NodeTurbine.scala @@ -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 = {