Added mechanical load calculation

This commit is contained in:
Calclavia 2014-11-22 18:25:59 +08:00
parent f6746410ab
commit eed96732fa
7 changed files with 37 additions and 39 deletions

View file

@ -26,7 +26,7 @@ trait TNodeMechanical extends INode with IVectorWorld
/**
* The mechanical load
* @return Torque in Newton meters per second
* @return Energy loss in joules
*/
def getLoad = 10D

View file

@ -5,10 +5,10 @@ import codechicken.multipart.{TMultiPart, TileMultipart}
import net.minecraft.tileentity.TileEntity
import net.minecraftforge.common.util.ForgeDirection
import resonant.api.grid.INodeProvider
import resonant.lib.transform.vector.{VectorWorld, Vector3}
import resonant.lib.transform.vector.Vector3
import resonant.lib.wrapper.ForgeDirectionWrapper._
import resonantinduction.core.interfaces.TNodeMechanical
import resonantinduction.mechanical.mech.gearshaft.{GearShaftNode, PartGearShaft}
import resonantinduction.mechanical.mech.gearshaft.{NodeGearShaft, PartGearShaft}
import resonantinduction.mechanical.mech.grid.NodeMechanical
/**
@ -18,7 +18,7 @@ import resonantinduction.mechanical.mech.grid.NodeMechanical
*/
class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
{
angleDisplacement = Math.PI / 12
override def angleDisplacement = if (gear.getMultiBlock.isConstructed) Math.PI / 36 else Math.PI / 12
protected def gear = getParent.asInstanceOf[PartGear]
@ -52,8 +52,8 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
val tileBehind = new Vector3(gear.tile).add(gear.placementSide).getTileEntity(world)
if (tileBehind.isInstanceOf[INodeProvider])
{
val instance: NodeMechanical = (tileBehind.asInstanceOf[INodeProvider]).getNode(classOf[NodeMechanical], gear.placementSide.getOpposite)
if (instance != null && instance != this && !(instance.getParent.isInstanceOf[PartGearShaft]) && instance.canConnect(this, gear.placementSide.getOpposite))
val instance: NodeMechanical = tileBehind.asInstanceOf[INodeProvider].getNode(classOf[NodeMechanical], gear.placementSide.getOpposite)
if (instance != null && instance != this && !instance.getParent.isInstanceOf[PartGearShaft] && instance.canConnect(this, gear.placementSide.getOpposite))
{
connect(instance, gear.placementSide)
}
@ -89,7 +89,7 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
{
val instance = checkTile.asInstanceOf[INodeProvider].getNode(classOf[NodeMechanical], gear.placementSide)
if (instance != null && instance != this && instance.canConnect(this, toDir.getOpposite) && !instance.isInstanceOf[GearShaftNode])
if (instance != null && instance != this && instance.canConnect(this, toDir.getOpposite) && !instance.isInstanceOf[NodeGearShaft])
{
connect(instance, toDir)
}
@ -129,13 +129,13 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
}
else if (otherParent.isInstanceOf[PartGear])
{
if ((otherParent.asInstanceOf[PartGear]).tile == gear.tile && !gear.getMultiBlock.isConstructed)
if (otherParent.asInstanceOf[PartGear].tile == gear.tile && !gear.getMultiBlock.isConstructed)
{
return true
}
if ((otherParent.asInstanceOf[PartGear]).placementSide != gear.placementSide)
if (otherParent.asInstanceOf[PartGear].placementSide != gear.placementSide)
{
val part = gear.tile.partMap((otherParent.asInstanceOf[PartGear]).placementSide.ordinal)
val part = gear.tile.partMap(otherParent.asInstanceOf[PartGear].placementSide.ordinal)
if (part.isInstanceOf[PartGear])
{
val sourceGear: PartGear = part.asInstanceOf[PartGear]
@ -148,11 +148,11 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
{
if (gear.getMultiBlock.isConstructed)
{
val checkPart: TMultiPart = (otherParent.asInstanceOf[PartGear]).tile.partMap(gear.placementSide.ordinal)
val checkPart: TMultiPart = otherParent.asInstanceOf[PartGear].tile.partMap(gear.placementSide.ordinal)
if (checkPart.isInstanceOf[PartGear])
{
val requiredDirection: ForgeDirection = (checkPart.asInstanceOf[PartGear]).getPosition.subtract(toVectorWorld).toForgeDirection
return (checkPart.asInstanceOf[PartGear]).isCenterMultiBlock && (otherParent.asInstanceOf[PartGear]).placementSide == requiredDirection
val requiredDirection: ForgeDirection = checkPart.asInstanceOf[PartGear].getPosition.subtract(toVectorWorld).toForgeDirection
return checkPart.asInstanceOf[PartGear].isCenterMultiBlock && otherParent.asInstanceOf[PartGear].placementSide == requiredDirection
}
}
}
@ -172,7 +172,7 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
val sourceTile: TileEntity = toVectorWorld.add(from).getTileEntity(world)
if (sourceTile.isInstanceOf[INodeProvider])
{
val sourceInstance: NodeMechanical = (sourceTile.asInstanceOf[INodeProvider]).getNode(classOf[NodeMechanical], from.getOpposite)
val sourceInstance: NodeMechanical = sourceTile.asInstanceOf[INodeProvider].getNode(classOf[NodeMechanical], from.getOpposite)
return sourceInstance == other
}
}
@ -206,9 +206,9 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
return false
}
override def inverseRotation(other: TNodeMechanical): Boolean = !other.isInstanceOf[GearShaftNode] || (other.isInstanceOf[GearShaftNode] && parent.placementSide.offset < Vector3.zero)
override def inverseRotation(other: TNodeMechanical): Boolean = !other.isInstanceOf[NodeGearShaft] || (other.isInstanceOf[NodeGearShaft] && parent.placementSide.offset < Vector3.zero)
override def radius( other: TNodeMechanical): Double =
override def radius(other: TNodeMechanical): Double =
{
val deltaPos = other.asInstanceOf[NodeMechanical].toVectorWorld - toVectorWorld
val caseX = gear.placementSide.offsetX != 0 && deltaPos.y == 0 && deltaPos.z == 0
@ -216,7 +216,7 @@ class NodeGear(parent: PartGear) extends NodeMechanical(parent: PartGear)
val caseZ = gear.placementSide.offsetZ != 0 && deltaPos.x == 0 && deltaPos.y == 0
if (caseX || caseY || caseZ)
return super.radius( other)
return super.radius(other)
if (gear.getMultiBlock.isConstructed) 1.5 else super.radius(other)
}

View file

@ -39,8 +39,8 @@ class PartGear extends PartMechanical with IMultiBlockStructure[PartGear]
if (getMultiBlock.isPrimary)
if (world != null) sendPacket(1)
// if (mechanicalNode.angularVelocity == 0)
// if (world != null) sendPacket(2)
if (mechanicalNode.angularVelocity == 0)
if (world != null) sendPacket(2)
}
mechanicalNode.onGridReconstruct = () => if (world != null && !world.isRemote) sendPacket(2)

View file

@ -8,7 +8,7 @@ import resonantinduction.core.interfaces.TNodeMechanical
import resonantinduction.mechanical.mech.gear.{NodeGear, PartGear}
import resonantinduction.mechanical.mech.grid.NodeMechanical
class GearShaftNode(parent: PartGearShaft) extends NodeMechanical(parent)
class NodeGearShaft(parent: PartGearShaft) extends NodeMechanical(parent)
{
override def getLoad: Double =
{

View file

@ -32,7 +32,7 @@ object PartGearShaft
class PartGearShaft extends PartMechanical
{
mechanicalNode = new GearShaftNode(this)
mechanicalNode = new NodeGearShaft(this)
override def preparePlacement(side: Int, itemDamage: Int)
{

View file

@ -4,7 +4,6 @@ import resonant.api.grid.IUpdate
import resonant.lib.grid.{GridNode, UpdateTicker}
import scala.collection.convert.wrapAll._
import scala.collection.mutable
/**
* A grid that manages the mechanical objects
@ -12,13 +11,6 @@ import scala.collection.mutable
*/
class MechanicalGrid extends GridNode[NodeMechanical](classOf[NodeMechanical]) with IUpdate
{
/**
* A map marking out the relative spin directions of each node.
* Updated upon recache
*/
val spinMap = mutable.WeakHashMap.empty[NodeMechanical, Boolean]
private var load = 0D
/**
@ -37,8 +29,8 @@ 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
spinMap += (node -> dir)
// 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
if (prev != null)
@ -104,9 +96,15 @@ class MechanicalGrid extends GridNode[NodeMechanical](classOf[NodeMechanical]) w
}
else
{
curr._torque += torque
curr._angularVelocity += angularVelocity * deltaTime
curr.connections.filter(!passed.contains(_)).foreach(c => recurse(deltaTime, torque, angularVelocity, passed :+ c))
//Calculate energy loss
val power = torque * angularVelocity
val netPower = power - load
val netTorque = netPower * (torque / power)
val netVelocity = netPower * (angularVelocity / power)
curr._torque += netTorque
curr._angularVelocity += netVelocity * deltaTime
curr.connections.filter(!passed.contains(_)).foreach(c => recurse(deltaTime, netTorque, netVelocity, passed :+ c))
}
}

View file

@ -50,11 +50,6 @@ class NodeMechanical(parent: INodeProvider) extends NodeGrid[NodeMechanical](par
var prevTime = System.currentTimeMillis()
var prevAngle = 0D
/**
* The amount of angle in radians displaced. This is used to align the gear teeth.
*/
var angleDisplacement = 0D
/**
* Events
*/
@ -63,6 +58,11 @@ class NodeMechanical(parent: INodeProvider) extends NodeGrid[NodeMechanical](par
@BeanProperty
var onVelocityChanged: () => Unit = () => ()
/**
* The amount of angle in radians displaced. This is used to align the gear teeth.
*/
def angleDisplacement = 0D
/**
* An arbitrary angle value computed based on velocity
* @return The angle in radians