use of org.valkyrienskies.mod.common.physics.PhysicsCalculations in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class WaterForcesTask method call.
/**
* Computes the force and torque resulting from the water collisions handled by this task.
*/
@Override
public Void call() {
final BlockPos.MutableBlockPos currentPos = new BlockPos.MutableBlockPos();
final ShipTransform physicsTransform = parent.getShipTransformationManager().getCurrentPhysicsTransform();
final PhysicsCalculations physicsEngine = parent.getPhysicsCalculations();
// Vector objects reused in this method.
final Vector3d temp0 = new Vector3d();
final Vector3d temp1 = new Vector3d();
final Vector3d temp2 = new Vector3d();
final Vector3d temp3 = new Vector3d();
final Vector3d temp4 = new Vector3d();
final Vector3d temp5 = new Vector3d();
final Vector3d temp6 = new Vector3d();
final Vector3d temp7 = new Vector3d();
final Vector3d temp8 = new Vector3d();
final Vector3d temp9 = new Vector3d();
for (int index = minHitIndex; index <= maxHitIndex; index++) {
final int waterHitPosHash = waterHitsToCheck.get(index);
SpatialDetector.setPosWithRespectTo(waterHitPosHash, colliderCenter, currentPos);
final Vector3dc waterPosInShipSpace = physicsTransform.transformPositionNew(JOML.convertDouble(currentPos, temp0).add(.5, .5, .5), TransformType.GLOBAL_TO_SUBSPACE);
final int minX = (int) Math.floor(waterPosInShipSpace.x() - .5);
final int minY = (int) Math.floor(waterPosInShipSpace.y() - .5);
final int minZ = (int) Math.floor(waterPosInShipSpace.z() - .5);
final int maxX = (int) Math.ceil(waterPosInShipSpace.x() + .5);
final int maxY = (int) Math.ceil(waterPosInShipSpace.y() + .5);
final int maxZ = (int) Math.ceil(waterPosInShipSpace.z() + .5);
final Vector3dc waterPosInWorld = JOML.convertDouble(currentPos, temp1).add(.5, .5, .5);
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
final Chunk chunk = parent.getChunkClaim().containsChunk(x >> 4, z >> 4) ? parent.getChunkAt(x >> 4, z >> 4) : null;
if (chunk == null)
continue;
for (int y = minY; y <= maxY; y++) {
final ExtendedBlockStorage blockStorage = chunk.storageArrays[y >> 4];
if (blockStorage != null) {
final IBitOctree terrainOctree = ((ITerrainOctreeProvider) blockStorage.data).getSolidOctree();
if (terrainOctree.get(x & 15, y & 15, z & 15)) {
// Assume both the water block and terrain block are spheres, then compute the volume
// that overlaps
final Vector3dc shipSolidBlockPosInWorld = physicsTransform.transformPositionNew(temp2.set(x + .5, y + .5, z + .5), TransformType.SUBSPACE_TO_GLOBAL);
final double volumeDisplaced = calculateAABBOverlap(waterPosInWorld.x() - shipSolidBlockPosInWorld.x(), waterPosInWorld.y() - shipSolidBlockPosInWorld.y(), waterPosInWorld.z() - shipSolidBlockPosInWorld.z());
if (volumeDisplaced <= 0) {
// No intersection
continue;
}
// Collision position is average of ship solid block pos and water pos
final Vector3dc collisionPosInWorld = shipSolidBlockPosInWorld.add(waterPosInWorld, temp3).mul(.5);
final Vector3dc buoyancyForce = temp4.set(0, volumeDisplaced * GRAVITY_ACCELERATION * MASS_OF_CUBIC_METER_OF_WATER, 0);
final Vector3dc collisionPosRelativeToShipCenterInWorld = temp5.set(collisionPosInWorld).sub(physicsTransform.getPosX(), physicsTransform.getPosY(), physicsTransform.getPosZ());
addForceAtPoint(collisionPosRelativeToShipCenterInWorld, buoyancyForce, temp7);
{
// Compute water damping force
final Vector3dc velocity = physicsEngine.getVelocityAtPoint(collisionPosRelativeToShipCenterInWorld, temp9);
if (!isVectorLengthZero(velocity)) {
// TODO: This is WRONG, but it'll do for now
// The distance between the water block and the solid block its pushing upwards
double distance = waterPosInWorld.distance(shipSolidBlockPosInWorld);
final double area = Math.PI * (SPHERE_RADIUS - (distance * .5)) * (SPHERE_RADIUS - (distance * .5));
final double velocitySquared = velocity.lengthSquared();
// Drag formula from https://en.wikipedia.org/wiki/Drag_(physics)
final double forceMagnitude = (.5) * DENSITY_OF_WATER * velocitySquared * DRAG_COEFFICIENT_OF_WATER * area;
final Vector3dc dragForce = temp6.set(velocity).normalize().mul(-forceMagnitude);
addForceAtPoint(collisionPosRelativeToShipCenterInWorld, dragForce, temp8);
}
}
}
}
}
}
}
}
return null;
}
use of org.valkyrienskies.mod.common.physics.PhysicsCalculations in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class WaterForcesTask method addForcesToShip.
/**
* Adds the computed force and torque to the parent ship
*/
public void addForcesToShip() {
final PhysicsCalculations physicsEngine = parent.getPhysicsCalculations();
physicsEngine.addForceAndTorque(addedForce, addedTorque);
}
use of org.valkyrienskies.mod.common.physics.PhysicsCalculations in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class MainCommand method teleportShipToPosition.
private static void teleportShipToPosition(final ShipData ship, final Vec3d position, final ICommandSender sender) {
try {
final World world = sender.getEntityWorld();
final WorldServerShipManager shipManager = ValkyrienUtils.getServerShipManager(world);
final PhysicsObject shipObject = shipManager.getPhysObjectFromUUID(ship.getUuid());
// Create the new ship transform that moves the ship to this position
final ShipTransform shipTransform = ship.getShipTransform();
final ShipTransform newTransform = new ShipTransform(JOML.convert(position), shipTransform.getCenterCoord());
if (shipObject != null) {
// The ship already exists in the world, so we need to update the physics transform as well
final PhysicsCalculations physicsCalculations = shipObject.getPhysicsCalculations();
physicsCalculations.setForceToUseGameTransform(true);
// Also update the transform in the ShipTransformationManager
shipObject.setForceToUseShipDataTransform(true);
shipObject.setTicksSinceShipTeleport(0);
}
// Update the ship transform of the ship data.
ship.setPhysicsEnabled(false);
ship.setPrevTickShipTransform(newTransform);
ship.setShipTransform(newTransform);
System.out.println(String.format("Teleporting ship %s to %s", ship.getName(), position.toString()));
} catch (final Exception e) {
e.printStackTrace();
}
}
Aggregations