Skip to content

Instantly share code, notes, and snippets.

@a-type
Last active August 14, 2021 13:03
Show Gist options
  • Save a-type/94d7a81be569967a296b01949d1cbed6 to your computer and use it in GitHub Desktop.
Save a-type/94d7a81be569967a296b01949d1cbed6 to your computer and use it in GitHub Desktop.
react-three-fiber spaceship controls (hacky)
// various tmp vars to avoid allocation in frame loop
const frameMovement = new Vector3();
const frameRotation = new Euler();
const tempQuat = new Quaternion();
const tempQuat2 = new Quaternion();
const tempForward = new Vector3();
const tempRight = new Vector3();
const tempUp = new Vector3();
function useShipControls(api: RAPIER.RigidBody) {
const controlStateRef = useFlightControls();
useFrame(() => {
// this is euler
const rotation = api.rotation();
// get ortho axes
tempForward.set(0, 0, 1);
// copy euler rotation to quaternion
tempQuat.set(rotation.x, rotation.y, rotation.z, rotation.w);
tempForward.applyQuaternion(tempQuat);
tempRight.set(1, 0, 0);
tempRight.applyQuaternion(tempQuat);
tempUp.crossVectors(tempForward, tempRight);
// contains up-to-date flags for directional movement input (pitch, yaw, roll) and thrust (+/-)
const controlState = controlStateRef.current;
// reset frame vector
frameMovement.set(0, 0, 0);
if (controlState.thrust) {
frameMovement.z += THRUST_FORCE;
}
if (controlState.brake) {
frameMovement.z -= THRUST_FORCE;
}
// already set above - uncomment if code changees so tempQuat is not rotation anymore
// tempQuat.set(rotation.x, rotation.y, rotation.z, rotation.w);
// rotate thrust vector to local forward
frameMovement.applyQuaternion(tempQuat);
api.applyForce(frameMovement, true);
// reset frame vector
frameRotation.set(0, 0, 0);
if (controlState.pitchForward) {
frameRotation.x -= ROTATE_FORCE;
}
if (controlState.pitchBackward) {
frameRotation.x += ROTATE_FORCE;
}
if (controlState.yawLeft) {
frameRotation.y -= ROTATE_FORCE;
}
if (controlState.yawRight) {
frameRotation.y += ROTATE_FORCE;
}
if (controlState.rollLeft) {
frameRotation.z -= ROTATE_FORCE;
}
if (controlState.rollRight) {
frameRotation.z += ROTATE_FORCE;
}
// TODO: fix a lot of this guesswork...
tempQuat.setFromAxisAngle(tempForward, frameRotation.z);
tempQuat2.setFromAxisAngle(tempUp, -frameRotation.y);
tempQuat.multiply(tempQuat2);
tempQuat2.setFromAxisAngle(tempRight, -frameRotation.x);
tempQuat.multiply(tempQuat2);
frameRotation.setFromQuaternion(tempQuat);
api.applyTorque(frameRotation, true);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment