Search in sources :

Example 1 with AxisAngle4d

use of org.joml.AxisAngle4d in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.

the class PhysObjectRenderManager method applyRenderTransform.

private void applyRenderTransform(double partialTicks, boolean inverse) {
    Vector3dc centerOfRotation = parent.getCenterCoord();
    Entity player = Objects.requireNonNull(Minecraft.getMinecraft().getRenderViewEntity());
    double p0 = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTicks;
    double p1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTicks;
    double p2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTicks;
    ShipTransform renderTransform = parent.getShipTransformationManager().getRenderTransform();
    Vector3d renderPos = renderTransform.getSubspaceToGlobal().transformPosition(centerOfRotation, new Vector3d());
    // Offset pos is used to prevent floating point errors when rendering stuff thats very far away.
    double offsetX = offsetPos.getX() - centerOfRotation.x();
    double offsetY = offsetPos.getY() - centerOfRotation.y();
    double offsetZ = offsetPos.getZ() - centerOfRotation.z();
    if (inverse) {
        AxisAngle4d rotation = new AxisAngle4d().set(renderTransform.getGlobalToSubspace());
        GL11.glTranslated(-offsetX, -offsetY, -offsetZ);
        GL11.glRotated(Math.toDegrees(rotation.angle), rotation.x, rotation.y, rotation.z);
        GL11.glTranslated(p0 - renderPos.x, p1 - renderPos.y, p2 - renderPos.z);
    } else {
        AxisAngle4d rotation = new AxisAngle4d().set(renderTransform.getSubspaceToGlobal());
        GL11.glTranslated(-p0 + renderPos.x, -p1 + renderPos.y, -p2 + renderPos.z);
        GL11.glRotated(Math.toDegrees(rotation.angle), rotation.x, rotation.y, rotation.z);
        GL11.glTranslated(offsetX, offsetY, offsetZ);
    }
}
Also used : Vector3dc(org.joml.Vector3dc) Entity(net.minecraft.entity.Entity) ShipTransform(org.valkyrienskies.mod.common.ships.ship_transform.ShipTransform) Vector3d(org.joml.Vector3d) AxisAngle4d(org.joml.AxisAngle4d)

Example 2 with AxisAngle4d

use of org.joml.AxisAngle4d 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);
}
Also used : Quaterniondc(org.joml.Quaterniondc) Vector3d(org.joml.Vector3d) AxisAngle4d(org.joml.AxisAngle4d)

Example 3 with AxisAngle4d

use of org.joml.AxisAngle4d in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.

the class TileEntityCaptainsChair method processCalculationsForControlMessageAndApplyCalculations.

private void processCalculationsForControlMessageAndApplyCalculations(PhysicsObject controlledShip, PilotControlsMessage message, IBlockState state) {
    BlockPos chairPosition = getPos();
    if (controlledShip.isShipAligningToGrid()) {
        return;
    }
    double pilotPitch = 0D;
    double pilotYaw = ((BlockCaptainsChair) state.getBlock()).getChairYaw(state, chairPosition);
    double pilotRoll = 0D;
    Matrix3d pilotRotationMatrix = new Matrix3d();
    pilotRotationMatrix.rotateXYZ(Math.toRadians(pilotPitch), Math.toRadians(pilotYaw), Math.toRadians(pilotRoll));
    Vector3d playerDirection = new Vector3d(1, 0, 0);
    pilotRotationMatrix.transform(playerDirection);
    Vector3d upDirection = new Vector3d(0, 1, 0);
    Vector3d downDirection = new Vector3d(0, -1, 0);
    Vector3d idealAngularDirection = new Vector3d();
    Vector3d idealLinearVelocity = new Vector3d();
    Vector3d shipUp = new Vector3d(0, 1, 0);
    Vector3d shipUpPosIdeal = new Vector3d(0, 1, 0);
    if (message.airshipForward_KeyDown) {
        idealLinearVelocity.add(playerDirection);
    }
    if (message.airshipBackward_KeyDown) {
        idealLinearVelocity.sub(playerDirection);
    }
    controlledShip.getShipTransformationManager().getCurrentTickTransform().transformDirection(idealLinearVelocity, TransformType.SUBSPACE_TO_GLOBAL);
    controlledShip.getShipTransformationManager().getCurrentTickTransform().transformDirection(shipUp, TransformType.SUBSPACE_TO_GLOBAL);
    if (message.airshipUp_KeyDown) {
        idealLinearVelocity.add(upDirection.mul(.5, new Vector3d()));
    }
    if (message.airshipDown_KeyDown) {
        idealLinearVelocity.add(downDirection.mul(.5, new Vector3d()));
    }
    double sidePitch = 0;
    if (message.airshipRight_KeyDown) {
        idealAngularDirection.sub(shipUp);
        sidePitch -= 10;
    }
    if (message.airshipLeft_KeyDown) {
        idealAngularDirection.add(shipUp);
        sidePitch += 10;
    }
    Vector3d sidesRotationAxis = new Vector3d(playerDirection);
    controlledShip.getShipTransformationManager().getCurrentTickTransform().transformDirection(sidesRotationAxis, TransformType.SUBSPACE_TO_GLOBAL);
    AxisAngle4d rotationSidesTransform = new AxisAngle4d(Math.toRadians(sidePitch), sidesRotationAxis.x, sidesRotationAxis.y, sidesRotationAxis.z);
    rotationSidesTransform.transform(shipUpPosIdeal);
    idealAngularDirection.mul(2);
    // The vector that points in the direction of the normal of the plane that
    // contains shipUp and shipUpPos. This is our axis of rotation.
    Vector3d shipUpRotationVector = shipUp.cross(shipUpPosIdeal, new Vector3d());
    // This isnt quite right, but it handles the cases quite well.
    double shipUpTheta = shipUp.angle(shipUpPosIdeal) + Math.PI;
    shipUpRotationVector.mul(shipUpTheta);
    idealAngularDirection.add(shipUpRotationVector);
    idealLinearVelocity.mul(20);
    // Move the ship faster if the player holds the sprint key.
    if (message.airshipSprinting) {
        idealLinearVelocity.mul(2);
    }
    double lerpFactor = .2;
    Vector3d linearMomentumDif = controlledShip.getPhysicsCalculations().getLinearVelocity().sub(idealLinearVelocity, new Vector3d());
    Vector3d angularVelocityDif = controlledShip.getPhysicsCalculations().getAngularVelocity().sub(idealAngularDirection, new Vector3d());
    linearMomentumDif.mul(lerpFactor);
    angularVelocityDif.mul(lerpFactor);
    controlledShip.getPhysicsCalculations().getLinearVelocity().sub(linearMomentumDif);
    controlledShip.getPhysicsCalculations().getAngularVelocity().sub(angularVelocityDif);
}
Also used : Matrix3d(org.joml.Matrix3d) Vector3d(org.joml.Vector3d) BlockPos(net.minecraft.util.math.BlockPos) AxisAngle4d(org.joml.AxisAngle4d) BlockCaptainsChair(org.valkyrienskies.mod.common.block.BlockCaptainsChair)

Example 4 with AxisAngle4d

use of org.joml.AxisAngle4d 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();
}
Also used : Vector3dc(org.joml.Vector3dc) Quaterniondc(org.joml.Quaterniondc) Vector3d(org.joml.Vector3d) Quaterniond(org.joml.Quaterniond) AxisAngle4d(org.joml.AxisAngle4d)

Aggregations

AxisAngle4d (org.joml.AxisAngle4d)4 Vector3d (org.joml.Vector3d)4 Quaterniondc (org.joml.Quaterniondc)2 Vector3dc (org.joml.Vector3dc)2 Entity (net.minecraft.entity.Entity)1 BlockPos (net.minecraft.util.math.BlockPos)1 Matrix3d (org.joml.Matrix3d)1 Quaterniond (org.joml.Quaterniond)1 BlockCaptainsChair (org.valkyrienskies.mod.common.block.BlockCaptainsChair)1 ShipTransform (org.valkyrienskies.mod.common.ships.ship_transform.ShipTransform)1