Last active
August 14, 2021 13:03
-
-
Save a-type/94d7a81be569967a296b01949d1cbed6 to your computer and use it in GitHub Desktop.
react-three-fiber spaceship controls (hacky)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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