### Basic Usage Example Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Demonstrates the fundamental setup of a react-three-fiber scene with react-three-rapier physics. It includes the Physics component, a RigidBody with a Torus, and a CuboidCollider for the ground. Ensure Suspense is used for lazy initialization. ```tsx import { Box, Torus } from "@react-three/drei"; import { Canvas } from "@react-three/fiber"; import { Physics, RigidBody, CuboidCollider } from "@react-three/rapier"; const App = () => { return ( ); }; ``` -------------------------------- ### InstancedRigidBodies: New Setup Source: https://github.com/pmndrs/react-three-rapier/wiki/0.12.x-to-0.13.x-Migration-guide Demonstrates the new setup for InstancedRigidBodies using an 'instances' prop for individual instance properties and 'colliderNodes' for shapes. Each instance requires a 'key'. ```tsx const instances = Array.from({length: COUNT}).map((_, index) => ({ key: 'instance_' + index, position: [1,2,3], rotation: [1,2,3], scale: [1,1,1], restitution: Math.random(), })) , ]}> ... ``` -------------------------------- ### InstancedRigidBodies: Previous Setup Source: https://github.com/pmndrs/react-three-rapier/wiki/0.12.x-to-0.13.x-Migration-guide Shows the previous method of setting up InstancedRigidBodies using separate arrays for positions, rotations, and scales. ```tsx const positions = Array.from({length: COUNT}).map(() => [1, 2, 3]) const rotations = Array.from({length: COUNT}).map(() => [3,2,1]) const scales = Array.from({length: COUNT}).map(() => [1,1,1]) ... ``` -------------------------------- ### Physics Component Setup Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Illustrates the root Physics component for a react-three-rapier world. It requires wrapping in Suspense and allows configuration of gravity, interpolation, and colliders. Refer to PhysicsProps for all available options. ```tsx const Scene = () => { return ( ... ); }; ``` -------------------------------- ### Fixed Joint Example Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Demonstrates how to create a fixed joint between two rigid bodies. Requires local space positions and orientations for both bodies. ```tsx const JointedThing = () => { const bodyA = useRef(null); const bodyB = useRef(null); const joint = useFixedJoint(bodyA, bodyB, [ // Position of the joint in bodyA's local space [0, 0, 0], // Orientation of the joint in bodyA's local space [0, 0, 0, 1], // Position of the joint in bodyB's local space [0, 0, 0], // Orientation of the joint in bodyB's local space [0, 0, 0, 1] ]); return ( ); }; ``` -------------------------------- ### Revolute Joint Example Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Shows how to implement a revolute joint, allowing rotation along one axis while restricting other movements. Requires local space positions and the joint axis. ```tsx const JointedThing = () => { const bodyA = useRef(null); const bodyB = useRef(null); const joint = useRevoluteJoint(bodyA, bodyB, [ // Position of the joint in bodyA's local space [0, 0, 0], // Position of the joint in bodyB's local space [0, 0, 0], // Axis of the joint, expressed in the local-space of // the rigid-bodies it is attached to. Cannot be [0,0,0]. [0, 1, 0] ]); return ( ); }; ``` -------------------------------- ### Prismatic Joint Example Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Provides an example of a prismatic joint, enabling translation along one axis while preventing other relative motions. Requires local space positions and the joint axis. ```tsx const JointedThing = () => { const bodyA = useRef(null); const bodyB = useRef(null); const joint = usePrismaticJoint(bodyA, bodyB, [ // Position of the joint in bodyA's local space [0, 0, 0], // Position of the joint in bodyB's local space [0, 0, 0], // Axis of the joint, expressed in the local-space of // the rigid-bodies it is attached to. Cannot be [0,0,0]. [0, 1, 0] ]); return ( ); }; ``` -------------------------------- ### RigidBodyApi Changes: Get and Set Translation Source: https://github.com/pmndrs/react-three-rapier/wiki/0.12.x-to-0.13.x-Migration-guide Demonstrates how to access translation and raw instances, and set translation for RigidBodies. Previously used RigidBodyApi, now uses direct RapierRigidBody reference and vec3 helper for conversions. ```tsx import { RigidBodyApi } from '@react-three/rapier' ... const ref = useRef() useEffect(() => { if (ref.current) { // get translation const position = ref.current.translation() // Three.Vector3 // get raw instance const instance = ref.current.raw(); // Rapier.RigidBody // set translation ref.current.setTranslation({x: 0, y: 10, z: 0}) } }, []) ``` ```tsx import { vec3, RapierRigidBody } from '@react-three/rapier' ... const ref = useRef() useEffect(() => { if (ref.current) { // get translation const translation = ref.current.translation() // Rapier.Vector const position = vec3(translation) // Three.Vector3 // get raw instance const instance = ref.current; // Rapier.RigidBody // set translation ref.current.setTranslation({x: 0, y: 10, z: 0}, true) } }, []) ``` -------------------------------- ### Spherical Joint Example Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Illustrates the creation of a spherical joint between two rigid bodies, preventing relative translational motion. Requires local space positions for both bodies. ```tsx const JointedThing = () => { const bodyA = useRef(null); const bodyB = useRef(null); const joint = useSphericalJoint(bodyA, bodyB, [ // Position of the joint in bodyA's local space [0, 0, 0], // Position of the joint in bodyB's local space [0, 0, 0] ]); return ( ); }; ``` -------------------------------- ### Configure Revolute Joint Motor Velocity Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Example of configuring the motor velocity for a revolute joint. Requires the joint ref and motor parameters. ```tsx const WheelJoint = ({ bodyA, bodyB }) => { const joint = useRevoluteJoint(bodyA, bodyB, [ [0, 0, 0], [0, 0, 0], [0, 0, 0] ]); useFrame(() => { if (joint.current) { joint.current.configureMotorVelocity(10, 2); } }, []); return null; }; ``` -------------------------------- ### Generate ConvexHull Colliders for All Meshes in a RigidBody Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Use the 'colliders' prop on the component to set the default collider type for all RigidBodies within the scene. This example sets the default to 'hull'. ```tsx const Scene = () => ( ); ``` -------------------------------- ### Create Compound Shapes with Custom BallColliders Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Manually create and attach Collider components to a RigidBody to form compound shapes. This example demonstrates a compound shape made of two custom BallColliders. ```tsx const Scene = () => (<> {/* Make a compound shape with two custom BallColliders */} {/* Make a compound shape with two custom BallColliders, an automatic BallCollider, Two automatic MeshColliders, based on two different shape types */} <>) ``` -------------------------------- ### World Snapshotting and Restoration Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Demonstrates how to serialize the physics world into a `Uint8Array` snapshot using `world.takeSnapshot()` and restore it using `rapier.World.restoreSnapshot()`. This is useful for saving and loading game states, but requires the world structure to remain identical. ```tsx import { useRapier } from '@react-three/rapier'; const SnapshottingComponent = () => { const { world, setWorld, rapier } = useRapier(); const worldSnapshot = useRef(); // Store the snapshot const takeSnapshot = () => { const snapshot = world.takeSnapshot() worldSnapshot.current = snapshot } // Create a new World from the snapshot, and replace the current one const restoreSnapshot = () => { setWorld(rapier.World.restoreSnapshot(worldSnapshot.current)) } return <> ... ... ... ... ... } ``` -------------------------------- ### Using the Attractor Component Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier-addons/README.md Demonstrates how to use the Attractor component with different configurations for strength, range, type, and collision groups. ```tsx import { Attractor } from "@react-three/rapier-addons" // Standard attractor // An attractor with negative strength, repels RigidBodies // You can also assign InteractionGroups. // An attractor belonging to group 0 only affecting bodies in group 2, and 3 ``` -------------------------------- ### Migrating from WorldApi to Proxied World Instance Source: https://github.com/pmndrs/react-three-rapier/wiki/0.15.x-to-1.x.x-Migration-guide Before: Accessing the WorldApi. Now: Accessing the proxied singleton world instance directly. ```tsx import { useRapier } from "@react-three/rapier"; const Component = () => { const { world } = useRapier(); useEffect(() => { // Access to the WorldApi (limited) world.raw().bodies.forEach(() => { // Do something }); // Access the raw Rapier World instance const rawWorldInstance = world.raw(); rawWorldInstance.raw().setGravity(new Vector3(0, -9.81, 0)); }, []); }; ``` ```tsx import { useRapier } from "@react-three/rapier"; const Component = () => { const { world } = useRapier(); useEffect(() => { // Access the Rapier World instance directly world.bodies.forEach(() => { // Do something }); world.setGravity(new Vector3(0, -9.81, 0)); }, []); }; ``` -------------------------------- ### Using Attractor Component with Addons Package (Current) Source: https://github.com/pmndrs/react-three-rapier/wiki/0.14.x-to-0.15.x-Migration-guide Illustrates the current method of using the `Attractor` component, which is now imported from the separate `@react-three/rapier-addons` package. ```tsx import { Physics } from '@react-three/rapier' import { Attractor } from '@react-three/rapier-addons' ``` -------------------------------- ### Using Attractor Component in React Three Rapier (Previous) Source: https://github.com/pmndrs/react-three-rapier/wiki/0.14.x-to-0.15.x-Migration-guide Demonstrates the previous approach of importing and using the `Attractor` component directly from the main `@react-three/rapier` package. ```tsx import { Physics, Attractor } from '@react-three/rapier' ``` -------------------------------- ### Configure Fixed Physics Time Step Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Set the `timeStep` prop on the `` component to control the simulation's frame rate. A value of `1 / 30` will simulate at 30 FPS. ```tsx {/* ... */} ``` -------------------------------- ### Spring Joint Implementation Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Shows how to use the useSpringJoint hook to apply a force proportional to the distance between two bodies. Requires calculating stiffness and damping based on mass and desired properties. ```tsx const JointedThing = () => { const bodyA = useRef(null); const bodyB = useRef(null); const mass = 1; const springRestLength = 0; const stiffness = 1.0e3; const criticalDamping = 2.0 * Math.sqrt(stiffness * mass); const dampingRatio = props.jointNum / (props.total / 2); const damping = dampingRatio * criticalDamping; const joint = useSpringJoint(bodyA, bodyB, [ // Position of the joint in bodyA's local space [0, 0, 0], // Position of the joint in bodyB's local space [0, 0, 0], // Spring rest length springRestLength, // Spring stiffness stiffness, // Spring damping damping ]); return ( ); }; ``` -------------------------------- ### Converting Rapier Vectors and Quaternions Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Use helper functions like `vec3`, `quat`, and `euler` for type conversions between Rapier and Three.js. Setting values can be done directly with Three.js types. ```tsx import { RapierRigidBody, quat, vec3, euler } from "@react-three/rapier"; const Scene = () => { const rigidBody = useRef(null); useEffect(() => { if (rigidBody.current) { const position = vec3(rigidBody.current.translation()); const quaternion = quat(rigidBody.current.rotation()); const eulerRot = euler().setFromQuaternion( quat(rigidBody.current.rotation()) ); // While Rapier's return types need conversion, setting values can be done directly with Three.js types rigidBody.current.setTranslation(position, true); rigidBody.current.setRotation(quaternion, true); rigidBody.current.setAngvel({ x: 0, y: 2, z: 0 }, true); } }, []); return ( ); }; ``` -------------------------------- ### Physics Component Prop Changes Source: https://github.com/pmndrs/react-three-rapier/wiki/1.2.1-to-1.3.0-Migration-guide This snippet shows the changes in props for the `` component to match new world initiation properties in Rapier 0.12.0. Direct alternatives for all old parameters may not exist. ```diff - maxStabilizationIterations?: number - maxVelocityFrictionIterations?: number - maxVelocityIterations?: number + allowedLinearError?: number + numSolverIterations?: number + numAdditionalFrictionIterations?: number + numInternalPgsIterations?: number + minIslandSize?: number + maxCcdSubsteps?: number ``` -------------------------------- ### Using Debug Component in React Three Rapier (Previous) Source: https://github.com/pmndrs/react-three-rapier/wiki/0.14.x-to-0.15.x-Migration-guide Illustrates the previous method of enabling debug mode using the `` component within the `` component. ```tsx import { Physics, Debug } from '@react-three/rapier' ... ``` -------------------------------- ### Rope Joint Implementation Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Demonstrates how to use the useRopeJoint hook to limit the maximum distance between two rigid bodies. Requires two refs for the bodies and an array of joint parameters. ```tsx const JointedThing = () => { const bodyA = useRef(null); const bodyB = useRef(null); const joint = useRopeJoint(bodyA, bodyB, [ // Position of the joint in bodyA's local space [0, 0, 0], // Position of the joint in bodyB's local space [0, 0, 0], // The max distance between the two bodies / length of the rope 1 ]); return ( ); }; ``` -------------------------------- ### Configure Variable Physics Time Step Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Set the `timeStep` prop to the string 'vary' to allow the simulation's time step to adjust to each frame's delta time. This can cause instability and non-deterministic behavior. ```tsx {/* ... */} ``` -------------------------------- ### Manual Physics Stepping Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Manually steps the physics simulation by calling the `step` method from the `useRapier` hook. Useful for controlling the simulation's update rate independently. ```tsx const { step } = useRapier(); step(1 / 60); ``` -------------------------------- ### Enabling Debug Mode in React Three Rapier (Current) Source: https://github.com/pmndrs/react-three-rapier/wiki/0.14.x-to-0.15.x-Migration-guide Shows the current method for enabling debug mode by passing the `debug` prop directly to the `` component. ```tsx import { Physics } from '@react-three/rapier' ... ``` -------------------------------- ### Physics Debugging with React Three Rapier Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Enable live visualization of all colliders in a scene by setting the 'debug' prop to true on the component. This is useful for verifying collision shapes and interactions. ```tsx import { Box, Sphere } from "@react-three/drei"; import { RigidBody } from "@react-three/rapier"; const Scene = () => { return ( ); }; ``` -------------------------------- ### Applying Forces and Torques to RigidBody Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Access a RigidBody's ref to apply impulses, continuous forces, and torques. Ensure the ref is available before calling methods. ```tsx import { RigidBody, RapierRigidBody } from "@react-three/rapier"; const Scene = () => { const rigidBody = useRef(null); useEffect(() => { if (rigidBody.current) { // A one-off "push" rigidBody.current.applyImpulse({ x: 0, y: 10, z: 0 }, true); // A continuous force rigidBody.current.addForce({ x: 0, y: 10, z: 0 }, true); // A one-off torque rotation rigidBody.current.applyTorqueImpulse({ x: 0, y: 10, z: 0 }, true); // A continuous torque rigidBody.current.addTorque({ x: 0, y: 10, z: 0 }, true); } }, []); return ( ); }; ``` -------------------------------- ### Workaround for Contact Force Events Source: https://github.com/pmndrs/react-three-rapier/wiki/1.2.1-to-1.3.0-Migration-guide If you are using contact force events and observe new behavior or differing magnitudes after updating, set `numSolverIterations` to `1` as a workaround. ```tsx ... ``` -------------------------------- ### Instanced Rigid Bodies with Single Collider Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Wrap a single Three.InstancedMesh in InstancedRigidBodies to generate individual rigid bodies for each instance. Colliders can be defined globally for all instances. Access and manipulate individual instances via the ref. ```tsx import { InstancedRigidBodies, RapierRigidBody } from "@react-three/rapier"; const COUNT = 1000; const Scene = () => { const rigidBodies = useRef(null); useEffect(() => { if (!rigidBodies.current) { return; } // You can access individual instanced by their index rigidBodies.current[40].applyImpulse({ x: 0, y: 10, z: 0 }, true); rigidBodies.current.at(100).applyImpulse({ x: 0, y: 10, z: 0 }, true); // Or update all instances rigidBodies.current.forEach((api) => { api.applyImpulse({ x: 0, y: 10, z: 0 }, true); }); }, []); // We can set the initial positions, and rotations, and scales, of // the instances by providing an array of InstancedRigidBodyProps // which is the same as RigidBodyProps, but with an additional "key" prop. const instances = useMemo(() => { const instances: InstancedRigidBodyProps[] = []; for (let i = 0; i < COUNT; i++) { instances.push({ key: "instance_" + Math.random(), position: [Math.random() * 10, Math.random() * 10, Math.random() * 10], rotation: [Math.random(), Math.random(), Math.random()] }); } return instances; }, []); return ( ); }; ``` -------------------------------- ### Configure Collider Interaction Groups Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Use `interactionGroups` to generate bitmasks for collider group memberships and interactions. The first argument specifies the collider's group(s), and the second specifies the groups it should interact with. ```tsx ``` ```tsx ``` ```tsx ``` -------------------------------- ### On-Demand Rendering with Independent Physics Loop Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Configures the physics simulation to run in its own `requestAnimationFrame` loop, updating the canvas only when active bodies change. This is achieved by setting `updateLoop="independent"` on the `` component and using `frameloop="demand"` on the ``. ```tsx ... ``` -------------------------------- ### RigidBody Component Usage Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Shows how to integrate a mesh into the physics world using the RigidBody component. By default, it automatically generates colliders based on the mesh shape. Consult RigidBodyProps for detailed configuration. ```tsx const RigidBodyMesh = () => ( ); ``` -------------------------------- ### Collider Ref Changes Source: https://github.com/pmndrs/react-three-rapier/wiki/0.12.x-to-0.13.x-Migration-guide Shows the change in how collider instances are accessed. Previously, refs returned an array; now they directly provide the Rapier.Collider instance. ```tsx const colliders = useRef() useEffect(() => { const collider = colliders.current[0] // Rapier.Collider }, []) return ``` ```tsx import { RapierCollider } from '@react-three/rapier' ... const collider = useRef() useEffect(() => { const collider = colliders.current // Rapier.Collider }, []) return ``` -------------------------------- ### Correct Usage of World Instance in React Three Rapier Source: https://github.com/pmndrs/react-three-rapier/wiki/0.15.x-to-1.x.x-Migration-guide Avoid accessing world properties and methods outside of useEffect for proper synchronization with the React component lifecycle. ```tsx // bad const Component = () => { const {world} = useRapier() world.setGravity(...) return null } ``` ```tsx // good const Component = () => { const {world} = useRapier() useEffect(() => { world.setGravity(...) }, []) return null } ``` -------------------------------- ### Implement Sensor Collider for Intersection Detection Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Use the `sensor` prop on a collider to make it non-physical. Attach `onIntersectionEnter` and `onIntersectionExit` event handlers to detect when other colliders enter or leave its bounds. ```tsx console.log("Goal!")} /> ``` -------------------------------- ### Create Compound Shapes with Custom BallColliders Source: https://github.com/pmndrs/react-three-rapier/blob/main/readme.md Demonstrates creating a compound collider shape by manually adding multiple BallColliders to a single RigidBody. This allows for complex collision shapes not easily represented by a single primitive. ```tsx const Scene = () => (<> {/* Make a compound shape with two custom BallColliders */} {/* Make a compound shape with two custom BallColliders, an automatic BallCollider, Two automatic MeshColliders, based on two different shape types */} <>) ``` -------------------------------- ### RigidBody Collision Events Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Subscribe to collision events like `onSleep`, `onWake`, and `onCollisionEnter` directly on a RigidBody component. The `onCollisionEnter` callback provides detailed information about the collision manifold and involved bodies. ```tsx const RigidBottle = () => { const [isAsleep, setIsAsleep] = useState(false); return ( setIsAsleep(true)} onWake={() => setIsAsleep(false)} name="Bally McBallFace" onCollisionEnter={({ manifold, target, other }) => { console.log( "Collision at world position ", manifold.solverContactPoint(0) ); if (other.rigidBodyObject) { console.log( // this rigid body's Object3D target.rigidBodyObject.name, " collided with ", // the other rigid body's Object3D other.rigidBodyObject.name ); } }}> ); }; ``` -------------------------------- ### Handle Contact Force Events on RigidBody Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Attach an `onContactForce` event handler to a `` to receive information about collision forces. The payload includes details like total force, magnitude, and direction. ```tsx { console.log(`The total force generated was: ${payload.totalForce}`); }} > ``` -------------------------------- ### Generate ConvexHull Colliders Including Invisible Meshes Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Use the 'includeInvisible' flag on a RigidBody to ensure that invisible meshes within its hierarchy are also considered when generating automatic colliders, such as ConvexHull colliders. ```tsx ``` -------------------------------- ### Attach Custom CuboidCollider to RigidBody within a Group Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Demonstrates attaching a custom CuboidCollider to a RigidBody that is part of a transformed group. This shows how RigidBodies and their colliders behave within a transformed parent object. ```tsx import { Box } from "@react-three/drei"; import { RigidBody, CuboidCollider } from "@react-three/rapier"; const Scene = () => ( ); ``` -------------------------------- ### Turn Off Global Auto-Generation, Apply Local Auto-Generation Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Disable automatic collider generation globally with 'colliders={false}' on and then enable specific collider types locally on individual components. This allows fine-grained control over collider generation per RigidBody. ```tsx const Scene = () => ( {/* Use an automatic CuboidCollider for all meshes inside this RigidBody */} {/* Use an automatic BallCollider for all meshes inside this RigidBody */} ); ``` -------------------------------- ### Joint Hooks Ref Changes Source: https://github.com/pmndrs/react-three-rapier/wiki/0.12.x-to-0.13.x-Migration-guide Illustrates the update in joint hooks, which now return a RefObject containing the Rapier instance instead of a JointApi proxy. ```tsx const joint = usePrismaticJoint(bodyA, bodyB, [[0,0,0],[0,0,0],[0,0,0]]) // JointApi useEffect(() => { // get raw instance const rawJoint = joint.raw() // Rapier.PrismaticImpulseJoint // Access joint api joint.raw().configureMotor(2, 2, 10, 5); }, []) ``` ```tsx const joint = usePrismaticJoint() // ObjectRef useEffect(() => { // get raw instance const rawJoint = joint.current // Rapier.PrismaticImpulseJoint // Access joint api joint.current.configureMotor(2, 2, 10, 5); }, []) ``` -------------------------------- ### Handle Contact Force Events on Collider Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md You can also attach `onContactForce` directly to collider components to handle collision force events for that specific collider. ```tsx { /* ... */ }} /> ``` -------------------------------- ### Instanced Rigid Bodies with Compound Colliders Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Define compound colliders for instanced meshes by providing an array of Collider components to the 'colliderNodes' prop. This allows each instance to have a complex collision shape. ```tsx import { InstancedRigidBodies, BoxCollider, SphereCollider } from "@react-three/rapier"; const COUNT = 500; const Scene = () => { const instances = useMemo(() => { const instances: InstancedRigidBodyProps[] = []; for (let i = 0; i < COUNT; i++) { instances.push({ key: "instance_" + Math.random(), position: [Math.random() * 10, Math.random() * 10, Math.random() * 10], rotation: [Math.random(), Math.random(), Math.random()] }); } return instances; }, []); return ( , ]} > ); }; ``` -------------------------------- ### Disable Global Auto-Colliders, Enable Local Source: https://github.com/pmndrs/react-three-rapier/blob/main/readme.md Turns off automatic collider generation for all RigidBodies by default, but allows specific RigidBodies to generate colliders using the 'cuboid' or 'ball' types. This provides fine-grained control over collider generation. ```tsx const Scene = () => ( {/* Use an automatic CuboidCollider for all meshes inside this RigidBody */} {/* Use an automatic BallCollider for all meshes inside this RigidBody */} ); ``` -------------------------------- ### One-Way Platform Collision Filtering Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Filters contact pairs to allow collisions only when a ball is moving downwards and above a platform. Requires caching body states before the physics step using `useBeforePhysicsStep`. ```tsx import { useRapier, useBeforePhysicsStep, useFilterContactPair } from "@react-three/rapier"; const OneWayPlatform = () => { const platformRef = useRef(null); const ballRef = useRef(null); const colliderRef = useRef(null); // Cache for storing body states before physics step const bodyStateCache = useRef(new Map()); const { rapier } = useRapier(); // Cache body states BEFORE the physics step useBeforePhysicsStep(() => { if (platformRef.current && ballRef.current) { const ballPos = ballRef.current.translation(); const ballVel = ballRef.current.linvel(); bodyStateCache.current.set(ballRef.current.handle, { position: ballPos, velocity: ballVel }); } }); // Filter collisions using cached data useFilterContactPair((collider1, collider2, body1, body2) => { const ballState = bodyStateCache.current.get(body1); if (!ballState) return null; // Let other hooks or default behavior handle it // Allow collision only if ball is moving down and above platform if (ballState.velocity.y < 0 && ballState.position.y > 0) { return rapier.SolverFlags.COMPUTE_IMPULSE; // Process collision } return rapier.SolverFlags.EMPTY; // Ignore collision }); useEffect(() => { // Enable active hooks on the collider (required for filtering) colliderRef.current?.setActiveHooks(rapier.ActiveHooks.FILTER_CONTACT_PAIRS); }, []); return ( <> ); }; ``` -------------------------------- ### Attractor Component Props Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier-addons/README.md Defines the properties for the Attractor component, including position, strength, range, gravity type, and collision group filtering. ```typescript type AttractorProps = { /** * The relative position of this attractor */ position?: Object3DProps["position"]; /** * The strength of the attractor. * Positive values attract, negative values repel. * * @defaultValue 1 */ strength?: number; /** * The range of the attractor. Will not affect objects outside of this range. * * @defaultValue 10 * @min 0 */ range?: number; /** * The type of gravity to use. * - static: The gravity is constant and does not change over time. * - linear: The gravity is linearly interpolated the closer the object is to the attractor. * - newtonian: The gravity is calculated using the newtonian gravity formula. * @defaultValue "static" */ type?: string; /** * The mass of the attractor. Used when type is `newtonian`. * @defaultValue 6.673e-11 */ gravitationalConstant?: number; /** * The collision groups that this attractor will apply effects to. If a RigidBody contains one or more colliders that are in one of the mask group, it will be affected by this attractor. * If not specified, the attractor will apply effects to all RigidBodies. */ collisionGroups?: InteractionGroups; }; ``` -------------------------------- ### Collider Collision Events Source: https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/readme.md Subscribe to collision events like `onCollisionEnter` and `onCollisionExit` on individual Collider components. The payload object contains details about the collision targets and manifold. ```tsx { /* ... */ }} onCollisionExit={(payload) => { /* ... */ }} /> ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.