Reformatted MechanicalNode.class
This commit is contained in:
parent
af32448001
commit
9bbc8e4d2c
2 changed files with 220 additions and 231 deletions
|
@ -15,8 +15,7 @@ import resonantinduction.core.ResonantInduction;
|
||||||
import universalelectricity.api.vector.Vector3;
|
import universalelectricity.api.vector.Vector3;
|
||||||
import codechicken.multipart.TMultiPart;
|
import codechicken.multipart.TMultiPart;
|
||||||
|
|
||||||
/**
|
/** A mechanical node for mechanical energy.
|
||||||
* A mechanical node for mechanical energy.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* Useful Formula:
|
* Useful Formula:
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -26,283 +25,273 @@ import codechicken.multipart.TMultiPart;
|
||||||
* Torque = r (Radius) * F (Force) * sin0 (Direction/Angle of the force applied. 90 degrees if
|
* Torque = r (Radius) * F (Force) * sin0 (Direction/Angle of the force applied. 90 degrees if
|
||||||
* optimal.)
|
* optimal.)
|
||||||
*
|
*
|
||||||
* @author Calclavia
|
* @author Calclavia */
|
||||||
*/
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public class MechanicalNode extends Node<INodeProvider, TickingGrid, MechanicalNode>
|
public class MechanicalNode extends Node<INodeProvider, TickingGrid, MechanicalNode> implements IMechanicalNode
|
||||||
implements IMechanicalNode
|
|
||||||
{
|
{
|
||||||
public double torque = 0;
|
public double torque = 0;
|
||||||
public double prevAngularVelocity, angularVelocity = 0;
|
public double prevAngularVelocity, angularVelocity = 0;
|
||||||
public float acceleration = 2f;
|
public float acceleration = 2f;
|
||||||
|
|
||||||
/**
|
/** The current rotation of the mechanical node. */
|
||||||
* The current rotation of the mechanical node.
|
public double angle = 0;
|
||||||
*/
|
public double prev_angle = 0;
|
||||||
public double angle = 0;
|
protected double maxDeltaAngle = Math.toRadians(180);
|
||||||
public double prev_angle = 0;
|
|
||||||
protected double maxDeltaAngle = Math.toRadians(180);
|
|
||||||
|
|
||||||
protected double load = 2;
|
protected double load = 2;
|
||||||
protected byte connectionMap = Byte.parseByte("111111", 2);
|
protected byte connectionMap = Byte.parseByte("111111", 2);
|
||||||
|
|
||||||
private double power = 0;
|
private double power = 0;
|
||||||
|
|
||||||
public MechanicalNode(INodeProvider parent)
|
public MechanicalNode(INodeProvider parent)
|
||||||
{
|
{
|
||||||
super(parent);
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MechanicalNode setLoad(double load)
|
public MechanicalNode setLoad(double load)
|
||||||
{
|
{
|
||||||
this.load = load;
|
this.load = load;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MechanicalNode setConnection(byte connectionMap)
|
public MechanicalNode setConnection(byte connectionMap)
|
||||||
{
|
{
|
||||||
this.connectionMap = connectionMap;
|
this.connectionMap = connectionMap;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float deltaTime)
|
public void update(float deltaTime)
|
||||||
{
|
{
|
||||||
prevAngularVelocity = angularVelocity;
|
prevAngularVelocity = angularVelocity;
|
||||||
|
|
||||||
if (!ResonantInduction.proxy.isPaused())
|
if (!ResonantInduction.proxy.isPaused())
|
||||||
{
|
{
|
||||||
if (angularVelocity >= 0)
|
if (angularVelocity >= 0)
|
||||||
{
|
{
|
||||||
angle += Math.min(angularVelocity, this.maxDeltaAngle) * deltaTime;
|
angle += Math.min(angularVelocity, this.maxDeltaAngle) * deltaTime;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
angle += Math.max(angularVelocity, -this.maxDeltaAngle) * deltaTime;
|
angle += Math.max(angularVelocity, -this.maxDeltaAngle) * deltaTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (angle % (Math.PI * 2) != angle)
|
if (angle % (Math.PI * 2) != angle)
|
||||||
{
|
{
|
||||||
revolve();
|
revolve();
|
||||||
angle = angle % (Math.PI * 2);
|
angle = angle % (Math.PI * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (world() != null && !world().isRemote)
|
if (world() != null && !world().isRemote)
|
||||||
{
|
{
|
||||||
final double acceleration = this.acceleration * deltaTime;
|
final double acceleration = this.acceleration * deltaTime;
|
||||||
|
|
||||||
/** Energy loss */
|
/** Energy loss */
|
||||||
double torqueLoss = Math.min(Math.abs(getTorque()), (Math.abs(getTorque() * getTorqueLoad()) + getTorqueLoad() / 10) * deltaTime);
|
double torqueLoss = Math.min(Math.abs(getTorque()), (Math.abs(getTorque() * getTorqueLoad()) + getTorqueLoad() / 10) * deltaTime);
|
||||||
|
|
||||||
if (torque > 0)
|
if (torque > 0)
|
||||||
{
|
{
|
||||||
torque -= torqueLoss;
|
torque -= torqueLoss;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
torque += torqueLoss;
|
torque += torqueLoss;
|
||||||
}
|
}
|
||||||
|
|
||||||
double velocityLoss = Math.min(Math.abs(getAngularVelocity()), (Math.abs(getAngularVelocity() * getAngularVelocityLoad()) + getAngularVelocityLoad() / 10) * deltaTime);
|
double velocityLoss = Math.min(Math.abs(getAngularVelocity()), (Math.abs(getAngularVelocity() * getAngularVelocityLoad()) + getAngularVelocityLoad() / 10) * deltaTime);
|
||||||
|
|
||||||
if (angularVelocity > 0)
|
if (angularVelocity > 0)
|
||||||
{
|
{
|
||||||
angularVelocity -= velocityLoss;
|
angularVelocity -= velocityLoss;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
angularVelocity += velocityLoss;
|
angularVelocity += velocityLoss;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getEnergy() <= 0)
|
if (getEnergy() <= 0)
|
||||||
{
|
{
|
||||||
angularVelocity = torque = 0;
|
angularVelocity = torque = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
power = getEnergy() / deltaTime;
|
power = getEnergy() / deltaTime;
|
||||||
|
|
||||||
synchronized (connections)
|
synchronized (connections)
|
||||||
{
|
{
|
||||||
Iterator<Entry<MechanicalNode, ForgeDirection>> it = connections.entrySet().iterator();
|
Iterator<Entry<MechanicalNode, ForgeDirection>> it = connections.entrySet().iterator();
|
||||||
|
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
Entry<MechanicalNode, ForgeDirection> entry = it.next();
|
Entry<MechanicalNode, ForgeDirection> entry = it.next();
|
||||||
|
|
||||||
ForgeDirection dir = entry.getValue();
|
ForgeDirection dir = entry.getValue();
|
||||||
MechanicalNode adjacentMech = entry.getKey();
|
MechanicalNode adjacentMech = entry.getKey();
|
||||||
|
|
||||||
/** Calculate angular velocity and torque. */
|
/** Calculate angular velocity and torque. */
|
||||||
float ratio = adjacentMech.getRatio(dir.getOpposite(), this) / getRatio(dir, adjacentMech);
|
float ratio = adjacentMech.getRatio(dir.getOpposite(), this) / getRatio(dir, adjacentMech);
|
||||||
boolean inverseRotation = inverseRotation(dir, adjacentMech) && adjacentMech.inverseRotation(dir.getOpposite(), this);
|
boolean inverseRotation = inverseRotation(dir, adjacentMech) && adjacentMech.inverseRotation(dir.getOpposite(), this);
|
||||||
|
|
||||||
int inversion = inverseRotation ? -1 : 1;
|
int inversion = inverseRotation ? -1 : 1;
|
||||||
|
|
||||||
double targetTorque = inversion * adjacentMech.getTorque() / ratio;
|
double targetTorque = inversion * adjacentMech.getTorque() / ratio;
|
||||||
double applyTorque = targetTorque * acceleration;
|
double applyTorque = targetTorque * acceleration;
|
||||||
|
|
||||||
if (Math.abs(torque + applyTorque) < Math.abs(targetTorque))
|
if (Math.abs(torque + applyTorque) < Math.abs(targetTorque))
|
||||||
{
|
{
|
||||||
torque += applyTorque;
|
torque += applyTorque;
|
||||||
}
|
}
|
||||||
else if (Math.abs(torque - applyTorque) > Math.abs(targetTorque))
|
else if (Math.abs(torque - applyTorque) > Math.abs(targetTorque))
|
||||||
{
|
{
|
||||||
torque -= applyTorque;
|
torque -= applyTorque;
|
||||||
}
|
}
|
||||||
|
|
||||||
double targetVelocity = inversion * adjacentMech.getAngularVelocity() * ratio;
|
double targetVelocity = inversion * adjacentMech.getAngularVelocity() * ratio;
|
||||||
double applyVelocity = targetVelocity * acceleration;
|
double applyVelocity = targetVelocity * acceleration;
|
||||||
|
|
||||||
if (Math.abs(angularVelocity + applyVelocity) < Math.abs(targetVelocity))
|
if (Math.abs(angularVelocity + applyVelocity) < Math.abs(targetVelocity))
|
||||||
{
|
{
|
||||||
angularVelocity += applyVelocity;
|
angularVelocity += applyVelocity;
|
||||||
}
|
}
|
||||||
else if (Math.abs(angularVelocity - applyVelocity) > Math.abs(targetVelocity))
|
else if (Math.abs(angularVelocity - applyVelocity) > Math.abs(targetVelocity))
|
||||||
{
|
{
|
||||||
angularVelocity -= applyVelocity;
|
angularVelocity -= applyVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set all current rotations */
|
/** Set all current rotations */
|
||||||
// adjacentMech.angle = Math.abs(angle) * (adjacentMech.angle >= 0 ? 1 : -1);
|
// adjacentMech.angle = Math.abs(angle) * (adjacentMech.angle >= 0 ? 1 : -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdate();
|
onUpdate();
|
||||||
prev_angle = angle;
|
prev_angle = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onUpdate()
|
protected void onUpdate()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Called when one revolution is made. */
|
||||||
* Called when one revolution is made.
|
protected void revolve()
|
||||||
*/
|
{
|
||||||
protected void revolve()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Object source, double torque, double angularVelocity)
|
public void apply(Object source, double torque, double angularVelocity)
|
||||||
{
|
{
|
||||||
this.torque += torque;
|
this.torque += torque;
|
||||||
this.angularVelocity += angularVelocity;
|
this.angularVelocity += angularVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getTorque()
|
public double getTorque()
|
||||||
{
|
{
|
||||||
return angularVelocity != 0 ? torque : 0;
|
return angularVelocity != 0 ? torque : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getAngularVelocity()
|
public double getAngularVelocity()
|
||||||
{
|
{
|
||||||
return torque != 0 ? angularVelocity : 0;
|
return torque != 0 ? angularVelocity : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getRatio(ForgeDirection dir, IMechanicalNode with)
|
public float getRatio(ForgeDirection dir, IMechanicalNode with)
|
||||||
{
|
{
|
||||||
return 0.5f;
|
return 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean inverseRotation(ForgeDirection dir, IMechanicalNode with)
|
public boolean inverseRotation(ForgeDirection dir, IMechanicalNode with)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** The energy percentage loss due to resistance in seconds. */
|
||||||
* The energy percentage loss due to resistance in seconds.
|
public double getTorqueLoad()
|
||||||
*/
|
{
|
||||||
public double getTorqueLoad()
|
return load;
|
||||||
{
|
}
|
||||||
return load;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAngularVelocityLoad()
|
public double getAngularVelocityLoad()
|
||||||
{
|
{
|
||||||
return load;
|
return load;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Recache the connections. This is the default connection implementation. */
|
||||||
* Recache the connections. This is the default connection implementation.
|
@Override
|
||||||
*/
|
public void doRecache()
|
||||||
@Override
|
{
|
||||||
public void doRecache()
|
connections.clear();
|
||||||
{
|
|
||||||
connections.clear();
|
|
||||||
|
|
||||||
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
|
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
|
||||||
{
|
{
|
||||||
TileEntity tile = position().translate(dir).getTileEntity(world());
|
TileEntity tile = position().translate(dir).getTileEntity(world());
|
||||||
|
|
||||||
if (tile instanceof INodeProvider)
|
if (tile instanceof INodeProvider)
|
||||||
{
|
{
|
||||||
MechanicalNode check = (MechanicalNode) ((INodeProvider) tile).getNode(MechanicalNode.class, dir.getOpposite());
|
MechanicalNode check = (MechanicalNode) ((INodeProvider) tile).getNode(MechanicalNode.class, dir.getOpposite());
|
||||||
|
|
||||||
if (check != null && canConnect(dir, check) && check.canConnect(dir.getOpposite(), this))
|
if (check != null && canConnect(dir, check) && check.canConnect(dir.getOpposite(), this))
|
||||||
{
|
{
|
||||||
connections.put(check, dir);
|
connections.put(check, dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public World world()
|
public World world()
|
||||||
{
|
{
|
||||||
return parent instanceof TMultiPart ? ((TMultiPart) parent).world() : parent instanceof TileEntity ? ((TileEntity) parent).getWorldObj() : null;
|
return parent instanceof TMultiPart ? ((TMultiPart) parent).world() : parent instanceof TileEntity ? ((TileEntity) parent).getWorldObj() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 position()
|
public Vector3 position()
|
||||||
{
|
{
|
||||||
return parent instanceof TMultiPart ? new Vector3(((TMultiPart) parent).x(), ((TMultiPart) parent).y(), ((TMultiPart) parent).z()) : parent instanceof TileEntity ? new Vector3((TileEntity) parent) : null;
|
return parent instanceof TMultiPart ? new Vector3(((TMultiPart) parent).x(), ((TMultiPart) parent).y(), ((TMultiPart) parent).z()) : parent instanceof TileEntity ? new Vector3((TileEntity) parent) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canConnect(ForgeDirection from, Object source)
|
public boolean canConnect(ForgeDirection from, Object source)
|
||||||
{
|
{
|
||||||
return (source instanceof MechanicalNode) && (connectionMap & (1 << from.ordinal())) != 0;
|
return (source instanceof MechanicalNode) && (connectionMap & (1 << from.ordinal())) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getEnergy()
|
public double getEnergy()
|
||||||
{
|
{
|
||||||
return getTorque() * getAngularVelocity();
|
return getTorque() * getAngularVelocity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getPower()
|
public double getPower()
|
||||||
{
|
{
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TickingGrid newGrid()
|
public TickingGrid newGrid()
|
||||||
{
|
{
|
||||||
return new TickingGrid<MechanicalNode>(this, MechanicalNode.class);
|
return new TickingGrid<MechanicalNode>(this, MechanicalNode.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(NBTTagCompound nbt)
|
public void load(NBTTagCompound nbt)
|
||||||
{
|
{
|
||||||
super.load(nbt);
|
super.load(nbt);
|
||||||
torque = nbt.getDouble("torque");
|
torque = nbt.getDouble("torque");
|
||||||
angularVelocity = nbt.getDouble("angularVelocity");
|
angularVelocity = nbt.getDouble("angularVelocity");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(NBTTagCompound nbt)
|
public void save(NBTTagCompound nbt)
|
||||||
{
|
{
|
||||||
super.save(nbt);
|
super.save(nbt);
|
||||||
nbt.setDouble("torque", torque);
|
nbt.setDouble("torque", torque);
|
||||||
nbt.setDouble("angularVelocity", angularVelocity);
|
nbt.setDouble("angularVelocity", angularVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class NodeGear implements INode, IConnector<GearNetwork>
|
||||||
public void deconstruct()
|
public void deconstruct()
|
||||||
{
|
{
|
||||||
this.rotationEffectMap.clear();
|
this.rotationEffectMap.clear();
|
||||||
|
this.connections.clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +69,7 @@ public class NodeGear implements INode, IConnector<GearNetwork>
|
||||||
@Override
|
@Override
|
||||||
public void setNetwork(GearNetwork network)
|
public void setNetwork(GearNetwork network)
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
this.network = network;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue