Skip to content

Instantly share code, notes, and snippets.

@neftaly
Last active May 7, 2023 05:59
Show Gist options
  • Save neftaly/f298d44dd7709d69c5a8af65e7b4511c to your computer and use it in GitHub Desktop.
Save neftaly/f298d44dd7709d69c5a8af65e7b4511c to your computer and use it in GitHub Desktop.
react-three-rapier scene query
import { Quaternion, Euler } from 'three'
// Reusuable objects to save on GC
const quaternion = new Quaternion()
const euler = new Euler()
// TODO: Do we need to do this or will Rapier just accept a Three quaternion?
const rotationToQuaternion = (rotation) => {
const { w, x, y, z } = quaternion.setFromEuler(euler.set(...rotation))
return { w, x, y, z }
}
// Cast downward ray from origin & get list of pieces (sorted by Y position)
// TODO: If we make direction a prop can this be used to castShape in any direction?
export const castShapeDown = (
{ world },
{ shape, position, rotation, distance = 10000 },
predicate
) =>
world.raw().castShape(
{ x: position[0], y: distance, z: position[2] },
rotationToQuaternion(rotation), // quaternion.setFromEuler(euler.set(...rotation))
{ x: 0, y: -1, z: 0 },
shape,
distance + 1, // TODO: is it necessary to do +1?
false, // firstHitOnly
undefined,
undefined,
undefined,
undefined,
(...args) => predicate(...args)
)
const rapier = useRapier()
const hit = castShapeDown(
rapier,
{
shape: new rapier.rapier.Cuboid(1, 1, 1),
position,
rotation
},
(match) => {
const id = rapier.rigidBodyStates.get(match.handle)?.object?.userData
?.pieceId
if (!id) return false
console.log('shapeCast', id, match)
return true
}
)
<Physics gravity={[0, 0, 0]}>
<RigidBody
key={id}
userData={{ pieceId: id }}
transformState={false}
type="fixed"
position={position}
rotation={rotation}>
<mesh />
</RigidBody>
...
</Physics>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment