use of org.joml.Quaterniondc in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class PhysicsCalculations method calculateForcesDeconstruction.
private void calculateForcesDeconstruction(double physTickTimeDelta) {
applyAirDrag();
Quaterniondc inverseCurrentRotation = parent.getShipTransformationManager().getCurrentPhysicsTransform().rotationQuaternion(TransformType.GLOBAL_TO_SUBSPACE);
AxisAngle4d idealAxisAngle = new AxisAngle4d(inverseCurrentRotation);
if (idealAxisAngle.angle < EPSILON) {
// We already have the perfect orientation, nothing left to do.
return;
}
// Normalizes the axis, not the angle.
idealAxisAngle.normalize();
double angleBetweenIdealAndActual = idealAxisAngle.angle;
// optimal to rotate in the opposite direction instead.
if (angleBetweenIdealAndActual > Math.PI) {
angleBetweenIdealAndActual = 2 * Math.PI - angleBetweenIdealAndActual;
}
// Number of seconds we'd expect this angular velocity to convert us onto the grid orientation.
double timeStep = 1D;
double idealAngularVelocityMultiple = angleBetweenIdealAndActual / timeStep;
Vector3d idealAngularVelocity = new Vector3d(idealAxisAngle.x, idealAxisAngle.y, idealAxisAngle.z);
idealAngularVelocity.mul(idealAngularVelocityMultiple);
Vector3d angularVelocityDif = idealAngularVelocity.sub(getAngularVelocity(), new Vector3d());
// Larger values converge faster, but sacrifice collision accuracy
angularVelocityDif.mul(physTickTimeDelta);
getAngularVelocity().add(angularVelocityDif);
}
use of org.joml.Quaterniondc in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class PhysicsCalculations method integrateAngularVelocity.
/**
* Implementation is based on https://gafferongames.com/post/physics_in_3d/
*/
private void integrateAngularVelocity() {
// The body angular velocity vector, in World coordinates
if (angularVelocity.lengthSquared() < .001) {
// Angular velocity is zero, so the rotation hasn't changed.
return;
}
// If a ship is rotating too fast, then clamp its max rotational speed
if (angularVelocity.lengthSquared() > VSConfig.shipMaxAngularSpeed * VSConfig.shipMaxAngularSpeed) {
angularVelocity.normalize().mul(VSConfig.shipMaxAngularSpeed);
}
Vector3dc angularVelInBody = new Vector3d(angularVelocity);
AxisAngle4d axisAngle4d = new AxisAngle4d(angularVelInBody.length() * getPhysicsTimeDeltaPerPhysTick(), angularVelInBody.x(), angularVelInBody.y(), angularVelInBody.z());
axisAngle4d.normalize();
// Take the product of the current rotation with the change in rotation that results from
// the angular velocity. Then change our pitch/yaw/roll based on the result.
Quaterniondc rotationQuat = new Quaterniond(axisAngle4d);
physRotation = physRotation.premul(rotationQuat, new Quaterniond()).normalize();
}
use of org.joml.Quaterniondc in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class ShipTransformationManager method updateRenderTransform.
public void updateRenderTransform(double partialTick) {
if (partialTick == 0) {
renderTransform = prevTickTransform;
return;
} else if (partialTick == 1) {
renderTransform = currentTickTransform;
return;
}
ShipTransform prev = prevTickTransform;
ShipTransform cur = currentTickTransform;
Vector3dc shipCenter = parent.getCenterCoord();
Vector3d prevPos = new Vector3d(shipCenter);
Vector3d curPos = new Vector3d(shipCenter);
prev.transformPosition(prevPos, TransformType.SUBSPACE_TO_GLOBAL);
cur.transformPosition(curPos, TransformType.SUBSPACE_TO_GLOBAL);
Vector3d deltaPos = curPos.sub(prevPos, new Vector3d());
deltaPos.mul(partialTick);
Vector3d partialPos = new Vector3d(prevPos);
// Now partialPos is complete
partialPos.add(deltaPos);
Quaterniondc prevRot = prev.rotationQuaternion(TransformType.SUBSPACE_TO_GLOBAL);
Quaterniondc curRot = cur.rotationQuaternion(TransformType.SUBSPACE_TO_GLOBAL);
Quaterniondc partialRot = prevRot.slerp(curRot, partialTick, new Quaterniond()).normalize();
// Put it all together to get the render transform.
renderTransform = new ShipTransform(partialPos.x, partialPos.y, partialPos.z, partialRot, parent.getCenterCoord());
}
Aggregations