Some rework on mechanical torque
This commit is contained in:
parent
7f7bd3e696
commit
08977ccbfb
7 changed files with 47 additions and 77 deletions
|
@ -51,9 +51,7 @@ trait TMechanicalNode extends INode with IVectorWorld
|
|||
/**
|
||||
* Applies rotational force and velocity to this node increasing its current rotation value
|
||||
*
|
||||
* @param source - The source object that is applying this force
|
||||
* @param torque - force at an angle
|
||||
* @param angularVelocity - speed of rotation
|
||||
*/
|
||||
def rotate(source: AnyRef, torque: Double, angularVelocity: Double)
|
||||
def rotate(torque: Double)
|
||||
}
|
|
@ -48,7 +48,7 @@ class TileMotor extends TileAdvanced(Material.iron) with TElectric with TSpatial
|
|||
|
||||
if (mechRatio > 0)
|
||||
{
|
||||
mechNode.rotate(this, deltaPower * mechRatio, deltaPower / mechRatio)
|
||||
mechNode.rotate(deltaPower)
|
||||
//TODO: Resist DC energy
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ import resonantinduction.mechanical.mech.grid.NodeMechanical
|
|||
*
|
||||
* @author Calclavia, Edited by: Darkguardsman
|
||||
*/
|
||||
class GearNode(parent: PartGear) extends NodeMechanical(parent: PartGear)
|
||||
class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
|
||||
{
|
||||
angleDisplacement = Math.PI / 12
|
||||
|
||||
protected def gear = getParent.asInstanceOf[PartGear]
|
||||
|
||||
override def getTorqueLoad: Double =
|
||||
override def getLoad: Double =
|
||||
{
|
||||
return gear.tier match
|
||||
{
|
|
@ -35,7 +35,7 @@ class PartGear extends PartMechanical with IMultiBlockStructure[PartGear]
|
|||
var multiBlock: GearMultiBlockHandler = null
|
||||
|
||||
//Constructor
|
||||
mechanicalNode = new GearNode(this)
|
||||
mechanicalNode = new NodeGear(this)
|
||||
mechanicalNode.onVelocityChanged = () =>
|
||||
{
|
||||
if (getMultiBlock.isPrimary)
|
||||
|
@ -53,7 +53,7 @@ class PartGear extends PartMechanical with IMultiBlockStructure[PartGear]
|
|||
{
|
||||
if (manualCrankTime > 0)
|
||||
{
|
||||
mechanicalNode.rotate(this, if (isClockwiseCrank) 50 else -50, if (isClockwiseCrank) 0.05f else -0.05f)
|
||||
mechanicalNode.rotate(if (isClockwiseCrank) 50 else -50)
|
||||
manualCrankTime -= 0.1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ import resonant.api.grid.INodeProvider
|
|||
import resonant.lib.transform.vector.Vector3
|
||||
import resonant.lib.wrapper.ForgeDirectionWrapper._
|
||||
import resonantinduction.core.interfaces.TMechanicalNode
|
||||
import resonantinduction.mechanical.mech.gear.{GearNode, PartGear}
|
||||
import resonantinduction.mechanical.mech.gear.{NodeGear, PartGear}
|
||||
import resonantinduction.mechanical.mech.grid.NodeMechanical
|
||||
|
||||
class GearShaftNode(parent: PartGearShaft) extends NodeMechanical(parent)
|
||||
{
|
||||
override def getTorqueLoad: Double =
|
||||
override def getLoad: Double =
|
||||
{
|
||||
return shaft.tier match
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ class GearShaftNode(parent: PartGearShaft) extends NodeMechanical(parent)
|
|||
return from == shaft.placementSide || from == shaft.placementSide.getOpposite
|
||||
}
|
||||
|
||||
override def inverseRotation(other: TMechanicalNode): Boolean = other.isInstanceOf[GearNode] && other.asInstanceOf[GearNode].parent.asInstanceOf[PartGear].placementSide.offset < Vector3.zero
|
||||
override def inverseRotation(other: TMechanicalNode): Boolean = other.isInstanceOf[NodeGear] && other.asInstanceOf[NodeGear].parent.asInstanceOf[PartGear].placementSide.offset < Vector3.zero
|
||||
|
||||
def shaft: PartGearShaft = getParent.asInstanceOf[PartGearShaft]
|
||||
}
|
|
@ -19,13 +19,7 @@ class MechanicalGrid extends GridNode[NodeMechanical](classOf[NodeMechanical]) w
|
|||
*/
|
||||
val spinMap = mutable.WeakHashMap.empty[NodeMechanical, Boolean]
|
||||
|
||||
/**
|
||||
* The power of the mechanical grid
|
||||
* Unit: Watts or Joules per second
|
||||
*/
|
||||
private var _power = 0D
|
||||
|
||||
def power = _power
|
||||
private var friction = 0D
|
||||
|
||||
/**
|
||||
* Rebuild the node list starting from the first node and recursively iterating through its connections.
|
||||
|
@ -34,6 +28,8 @@ class MechanicalGrid extends GridNode[NodeMechanical](classOf[NodeMechanical]) w
|
|||
{
|
||||
super.reconstruct(first)
|
||||
UpdateTicker.addUpdater(this)
|
||||
|
||||
friction = getNodes.map(n => n.getLoad).foldLeft(0D)(_ + _)
|
||||
}
|
||||
|
||||
override protected def populateNode(node: NodeMechanical, prev: NodeMechanical)
|
||||
|
@ -41,7 +37,7 @@ class MechanicalGrid extends GridNode[NodeMechanical](classOf[NodeMechanical]) w
|
|||
super.populateNode(node, prev)
|
||||
|
||||
//TODO: Check if gears are LOCKED (when two nodes obtain undesirable spins)
|
||||
val dir = if (prev != null) (if (node.inverseRotation(prev)) !spinMap(prev) else spinMap(prev)) else false
|
||||
val dir = if (prev != null) if (node.inverseRotation(prev)) !spinMap(prev) else spinMap(prev) else false
|
||||
spinMap += (node -> dir)
|
||||
|
||||
//Set mechanical node's initial angle
|
||||
|
@ -54,59 +50,36 @@ class MechanicalGrid extends GridNode[NodeMechanical](classOf[NodeMechanical]) w
|
|||
getNodes synchronized
|
||||
{
|
||||
//Find all nodes that are currently producing energy
|
||||
val inputs = getNodes.filter(n => n.bufferTorque != 0 && n.bufferAngle != 0)
|
||||
val inputs = getNodes.filter(n => n.bufferTorque != 0)
|
||||
|
||||
//Calculate the total input equivalent torque and angular velocity
|
||||
val input = inputs
|
||||
.map(
|
||||
n =>
|
||||
{
|
||||
val inversion = if (spinMap(n)) 1 else -1
|
||||
(n.bufferTorque * n.ratio * inversion, n.bufferAngle / deltaTime / n.ratio * inversion)
|
||||
})
|
||||
.foldLeft((0D, 0D))((b, a) => (a._1 + b._1, a._2 + b._2))
|
||||
//Calculate the total input equivalent torque
|
||||
val inputTorque = inputs
|
||||
.map(n => n.bufferTorque * (if (spinMap(n)) 1 else -1))
|
||||
.foldLeft(0D)(_ + _)
|
||||
|
||||
var delta = (0D, 0D)
|
||||
|
||||
if (input._1 != 0 && input._2 != 0)
|
||||
{
|
||||
//Calculate the total resistance of all nodes
|
||||
//TODO: Cache this
|
||||
val resistance = getNodes.view
|
||||
.map(n => (n.getTorqueLoad, n.getAngularVelocityLoad))
|
||||
.foldLeft((0D, 0D))((b, a) => (a._1 + b._1, a._2 + b._2))
|
||||
|
||||
//Calculate the total change in torque and angular velocity
|
||||
delta = (input._1 - input._1 * resistance._1 / getNodes.size(), input._2 - input._2 * resistance._2 / getNodes.size())
|
||||
}
|
||||
|
||||
//Calculate power
|
||||
_power = delta._1 * delta._2
|
||||
val deltaTorque = inputTorque - friction * inputTorque
|
||||
|
||||
//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 = delta._1 * n.ratio * inversion
|
||||
n.angularVelocity = delta._2 / n.ratio * inversion
|
||||
val inversion = if (spinMap(n)) 1 else -1
|
||||
n.torque = deltaTorque * inversion
|
||||
val angularAcceleration = deltaTorque / n.momentOfInertia
|
||||
n.angularVelocity = angularAcceleration * deltaTime * inversion
|
||||
|
||||
if (Math.abs(prevTorque - n.torque) >= 0.1)
|
||||
n.onTorqueChanged()
|
||||
if (Math.abs(prevTorque - n.torque) >= 0.1)
|
||||
n.onTorqueChanged()
|
||||
|
||||
if (Math.abs(prevAngularVelocity - n.angularVelocity) >= 0.1)
|
||||
n.onVelocityChanged()
|
||||
|
||||
})
|
||||
if (Math.abs(prevAngularVelocity - n.angularVelocity) >= 0.1)
|
||||
n.onVelocityChanged()
|
||||
})
|
||||
|
||||
//Clear buffers
|
||||
inputs.foreach(n =>
|
||||
{
|
||||
n.bufferTorque = 0
|
||||
n.bufferAngle = 0
|
||||
})
|
||||
inputs.foreach(_.bufferTorque = 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ import resonant.lib.transform.vector.IVectorWorld
|
|||
import resonantinduction.core.interfaces.TMechanicalNode
|
||||
import resonantinduction.core.prefab.node.TMultipartNode
|
||||
|
||||
import scala.beans.BeanProperty
|
||||
|
||||
/**
|
||||
* Prefab node for the mechanical system used by almost ever mechanical object in Resonant Induction. Handles connections to other tiles, and shares power with them
|
||||
*
|
||||
|
@ -22,12 +24,11 @@ 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 bufferAngle = 0D
|
||||
|
||||
/**
|
||||
* A percentage value indicating how much friction the node has.
|
||||
* A percentage value indicating how much friction the loss.
|
||||
*/
|
||||
var load = 0.2
|
||||
var load = 0.1D
|
||||
|
||||
/**
|
||||
* Angle calculations
|
||||
|
@ -43,7 +44,9 @@ class NodeMechanical(parent: INodeProvider) extends NodeGrid[NodeMechanical](par
|
|||
/**
|
||||
* Events
|
||||
*/
|
||||
@BeanProperty
|
||||
var onTorqueChanged: () => Unit = () => ()
|
||||
@BeanProperty
|
||||
var onVelocityChanged: () => Unit = () => ()
|
||||
|
||||
/**
|
||||
|
@ -64,27 +67,23 @@ class NodeMechanical(parent: INodeProvider) extends NodeGrid[NodeMechanical](par
|
|||
|
||||
}
|
||||
|
||||
@deprecated
|
||||
override def getRadius(dir: ForgeDirection, `with`: TMechanicalNode): Double = 0.5
|
||||
//Moment of inertia = m * r ^ 2
|
||||
def momentOfInertia = 1d
|
||||
|
||||
override def rotate(from: AnyRef, torque: Double, angle: Double)
|
||||
def getLoad = load
|
||||
|
||||
override def rotate(torque: Double)
|
||||
{
|
||||
bufferTorque += torque
|
||||
bufferAngle += angle
|
||||
}
|
||||
|
||||
/**
|
||||
* The percentage of torque loss every second
|
||||
*/
|
||||
def getTorqueLoad: Double = load
|
||||
|
||||
/**
|
||||
* The percentage of angular velocity loss every second
|
||||
*/
|
||||
def getAngularVelocityLoad: Double = load
|
||||
def getAngularVelocityLoad: Double = getLoad
|
||||
|
||||
//TODO: Create new grids automatically?
|
||||
def power: Double = if (getMechanicalGrid != null) getMechanicalGrid.power else 0
|
||||
def power: Double = torque * angularVelocity
|
||||
|
||||
def getMechanicalGrid: MechanicalGrid = super.grid.asInstanceOf[MechanicalGrid]
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue