From 1517acb1943ea463bdeb0d2978b1bf5e2ae1af4c Mon Sep 17 00:00:00 2001 From: tito <92818759+0xtito@users.noreply.github.com> Date: Tue, 13 Feb 2024 14:35:29 -0500 Subject: [PATCH 01/11] feat: continuation of update @dimforge/rapier3d-compat to 0.12.0 + optimizations (#619) --- .changeset/cold-apples-drop.md | 12 ++ .changeset/pre.json | 10 ++ demo/src/App.tsx | 30 +++-- demo/src/examples/cradle/CradleExample.tsx | 9 +- .../examples/rope-joint/RopeJointExample.tsx | 120 ++++++++++++++++++ demo/src/examples/spring/SpringExample.tsx | 113 +++++++++++++++++ packages/react-three-rapier/package.json | 2 +- packages/react-three-rapier/readme.md | 95 +++++++++++++- .../src/components/Physics.tsx | 90 ++++++++----- .../react-three-rapier/src/hooks/joints.ts | 104 ++++++++++----- packages/react-three-rapier/src/types.ts | 51 ++++++-- .../src/utils/utils-rigidbody.ts | 5 +- .../react-three-rapier/src/utils/utils.ts | 45 +++---- .../tests/__snapshots__/physics.test.tsx.snap | 12 +- .../react-three-rapier/tests/physics.test.tsx | 4 +- yarn.lock | 8 +- 16 files changed, 579 insertions(+), 131 deletions(-) create mode 100644 .changeset/cold-apples-drop.md create mode 100644 .changeset/pre.json create mode 100644 demo/src/examples/rope-joint/RopeJointExample.tsx create mode 100644 demo/src/examples/spring/SpringExample.tsx diff --git a/.changeset/cold-apples-drop.md b/.changeset/cold-apples-drop.md new file mode 100644 index 00000000..f76e9aa0 --- /dev/null +++ b/.changeset/cold-apples-drop.md @@ -0,0 +1,12 @@ +--- +"@react-three/rapier": minor +--- + +feat: update @dimforge/rapier3d-compat to 0.12.0 (@0xtito, @isaac-mason) + +- Change Physics component props to match the new rapier version's integration parameter changes. + - There aren't direct alternatives for all old parameters. See the Physics component docs for more information on the new parameters: https://pmndrs.github.io/react-three-rapier/interfaces/PhysicsProps.html +- Add `additionalSolverIterations` prop to `RigidBodyOptions`. + - See: https://pmndrs.github.io/react-three-rapier/interfaces/RigidBodyOptions.html#additionalSolverIterations +- Add `useSpringJoint` +- Add `useRopeJoint` \ No newline at end of file diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000..52595472 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,10 @@ +{ + "mode": "pre", + "tag": "canary", + "initialVersions": { + "demo": "0.0.0", + "@react-three/rapier": "1.2.1", + "@react-three/rapier-addons": "3.0.3" + }, + "changesets": [] +} diff --git a/demo/src/App.tsx b/demo/src/App.tsx index e4699111..824ef213 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -1,15 +1,14 @@ import { Box, Environment, OrbitControls } from "@react-three/drei"; import { Canvas } from "@react-three/fiber"; -import { Physics, RigidBody, useRapier } from "@react-three/rapier"; +import { Physics, RigidBody } from "@react-three/rapier"; import { Perf } from "r3f-perf"; import { - createContext, ReactNode, + StrictMode, Suspense, + createContext, useContext, - useState, - StrictMode, - useEffect + useState } from "react"; import { NavLink, NavLinkProps, Route, Routes } from "react-router-dom"; import { AllCollidersExample } from "./examples/all-colliders/AllCollidersExample"; @@ -24,21 +23,23 @@ import { ComponentsExample } from "./examples/components/ComponentsExample"; import { ContactForceEventsExample } from "./examples/contact-force-events/ContactForceEventsExample"; import { CradleExample } from "./examples/cradle/CradleExample"; import { Damping } from "./examples/damping/DampingExample"; +import { DynamicTypeChangeExample } from "./examples/dynamic-type-change/DynamicTypeChangeExample"; +import { ImmutablePropsExample } from "./examples/immutable-props/ImmutablePropsExample"; import { InstancedMeshes } from "./examples/instanced-meshes/InstancedMeshesExample"; import { InstancedMeshesCompound } from "./examples/instances-meshes-compound/InstancedMeshesCompoundExample"; import { Joints } from "./examples/joints/JointsExample"; import { Kinematics } from "./examples/kinematics/KinematicsExample"; +import { LockedTransformsExample } from "./examples/locked-transforms/LockedTransformsExample"; import { ManualStepExample } from "./examples/manual-step/ManualStepExamples"; import { MeshColliderTest } from "./examples/mesh-collider-test/MeshColliderExample"; -import { SensorsExample } from "./examples/sensors/SensorsExample"; -import Shapes from "./examples/plinko/ShapesExample"; -import { Transforms } from "./examples/transforms/TransformsExample"; -import { LockedTransformsExample } from "./examples/locked-transforms/LockedTransformsExample"; import { PerformanceExample } from "./examples/performance/PeformanceExample"; -import { DynamicTypeChangeExample } from "./examples/dynamic-type-change/DynamicTypeChangeExample"; +import Shapes from "./examples/plinko/ShapesExample"; +import { RopeJointExample } from "./examples/rope-joint/RopeJointExample"; +import { SensorsExample } from "./examples/sensors/SensorsExample"; +import { SnapshotExample } from "./examples/snapshot/SnapshotExample"; +import { SpringExample } from "./examples/spring/SpringExample"; import { StutteringExample } from "./examples/stuttering/StutteringExample"; -import { ImmutablePropsExample } from "./examples/immutable-props/ImmutablePropsExample"; -import { SnapshotExample } from './examples/snapshot/SnapshotExample'; +import { Transforms } from "./examples/transforms/TransformsExample"; const demoContext = createContext<{ setDebug?(f: boolean): void; @@ -116,7 +117,9 @@ const routes: Record = { "dynamic-type-changes": , stuttering: , "immutable-props": , - snapshot: + snapshot: , + spring: , + "rope-joint": }; export const App = () => { @@ -149,7 +152,6 @@ export const App = () => { interpolate={interpolate} debug={debug} timeStep={1 / 60} - // erp={0.2} > { @@ -20,12 +19,6 @@ const Rod = (props: RigidBodyOptions) => { [0, 0, 0] ]); - const { world } = useRapier(); - - useEffect(() => { - world.maxStabilizationIterations = 10; - }, []); - return ( diff --git a/demo/src/examples/rope-joint/RopeJointExample.tsx b/demo/src/examples/rope-joint/RopeJointExample.tsx new file mode 100644 index 00000000..968a3b05 --- /dev/null +++ b/demo/src/examples/rope-joint/RopeJointExample.tsx @@ -0,0 +1,120 @@ +import { Sphere, Box } from "@react-three/drei"; +import { + BallCollider, + RapierRigidBody, + RigidBody, + RigidBodyOptions, + useRopeJoint +} from "@react-three/rapier"; +import { useRef } from "react"; +import { Demo } from "../../App"; +import { Vector3 } from "@react-three/fiber"; + +const WALL_COLORS = ["#50514F", "#CBD4C2", "#FFFCFF", "#247BA0", "#C3B299"]; + +interface BoxRigidBodyProps extends RigidBodyOptions { + color: string; +} + +interface BoxWallProps extends RigidBodyOptions { + height: number; + width: number; +} + +interface RopeJointProps { + anchorPosition: Vector3; + ballPosition: Vector3; + ropeLength: number; +} + +const Floor = (props: RigidBodyOptions) => { + return ( + + + + + + ); +}; + +const BoxRigidBody = (props: BoxRigidBodyProps) => { + return ( + + + + + + ); +}; + +const BoxWall = ({ height, width, ...props }: BoxWallProps) => { + const wall = []; + + for (let i = 0; i < height; i++) { + for (let j = 0; j < width; j++) { + const position: [number, number, number] = [j, i, 0]; + wall.push( + + ); + } + } + + return ( + + {wall.map((box, i) => box)} + + ); +}; + +const RopeJoint = ({ + anchorPosition, + ballPosition, + ropeLength +}: RopeJointProps) => { + const anchor = useRef(null); + const ball = useRef(null); + + useRopeJoint(anchor, ball, [[0, 0, 0], [0, 0, 0], ropeLength]); + + return ( + + {/* Anchor */} + + + {/* Wrecking Ball */} + + + + + + + + + ); +}; + +export const RopeJointExample: Demo = () => { + return ( + + + + + + ); +}; diff --git a/demo/src/examples/spring/SpringExample.tsx b/demo/src/examples/spring/SpringExample.tsx new file mode 100644 index 00000000..29dd1a80 --- /dev/null +++ b/demo/src/examples/spring/SpringExample.tsx @@ -0,0 +1,113 @@ +import { Box, Sphere } from "@react-three/drei"; +import { + BallCollider, + RapierRigidBody, + RigidBody, + RigidBodyOptions, + useSpringJoint +} from "@react-three/rapier"; +import { forwardRef, useMemo, useRef } from "react"; +import { Demo } from "../../App"; +import { useForwardedRef } from "@react-three/rapier/src/hooks/use-forwarded-ref"; +import { vectorArrayToVector3 } from "@react-three/rapier/src/utils/utils"; + +const COLORS_ARR = ["#335C67", "#FFF3B0", "#E09F3E", "#9E2A2B", "#540B0E"]; + +interface BallSpringProps extends RigidBodyOptions { + jointNum: number; + total: number; +} + +interface BoxRigidBodyProps extends RigidBodyOptions { + color: string; +} + +const BoxRigidBody = ({ color, ...props }: BoxRigidBodyProps) => { + return ( + + + + + + ); +}; + +const BallSpring = forwardRef( + (props, floorRef) => { + const floor = useForwardedRef(floorRef); + const ball = useRef(null); + + const stiffness = 1.0e3; + const criticalDamping = 2.0 * Math.sqrt(stiffness * (props.mass ?? 1)); + const dampingRatio = props.jointNum / (props.total / 2); + const damping = dampingRatio * criticalDamping; + + const ballPos = props.position as THREE.Vector3; + + if (!ballPos) { + throw new Error("BallSpring requires a position prop"); + } + + useSpringJoint(ball, floor, [ + [0, 0, 0], + [ballPos.x, ballPos.y - 3, ballPos.z], + 0, + stiffness, + damping + ]); + + return ( + + + + + + + ); + } +); + +export const SpringExample: Demo = () => { + const floor = useRef(null); + + const vectorArr = useMemo(() => { + return Array.from({ length: 30 }).map((_, i) => { + return vectorArrayToVector3([-20 + 1.5 * (i + 1), 7.5, -30]); + }); + }, []); + + return ( + <> + + + {vectorArr.map((_, i) => ( + + + + + ))} + + ); +}; diff --git a/packages/react-three-rapier/package.json b/packages/react-three-rapier/package.json index e03268f9..1de2da64 100644 --- a/packages/react-three-rapier/package.json +++ b/packages/react-three-rapier/package.json @@ -29,7 +29,7 @@ "three": ">=0.139.0" }, "dependencies": { - "@dimforge/rapier3d-compat": "0.11.2", + "@dimforge/rapier3d-compat": "0.12.0", "three-stdlib": "2.23.9", "use-asset": "1.0.4" }, diff --git a/packages/react-three-rapier/readme.md b/packages/react-three-rapier/readme.md index 05e7ec96..87c15276 100644 --- a/packages/react-three-rapier/readme.md +++ b/packages/react-three-rapier/readme.md @@ -78,6 +78,8 @@ For full API outline and documentation, see 🧩 [API Docs](https://pmndrs.githu - [Spherical Joint](#spherical-joint) - [Revolute Joint](#revolute-joint) - [Prismatic Joint](#prismatic-joint) + - [Rope Joint](#rope-joint) + - [Spring Joint](#spring-joint) - [🖼 Joints Example](#-joints-example) - [Advanced hooks usage](#advanced-hooks-usage) - [Manual stepping](#manual-stepping) @@ -623,12 +625,14 @@ Joints can be made between two `RigidBodies` to provide a way to restrict a moti Joints are available in `r3/rapier` as hooks. -There are 4 different joint types available: +There are 6 different joint types available: - Fixed (two bodies are fixed together) - Spherical (two bodies are connected by a ball and socket, for things like arms or chains) - Revolute (two bodies are connected by a hinge, for things like doors or wheels) - Prismatic (two bodies are connected by a sliding joint, for things like pistons or sliders) +- Rope (limits the max distance between two bodies) +- Spring (applies a force proportional to the distance between two bodies) Each joint hook returns a RefObject containing the raw reference to the joint instance. @@ -658,6 +662,9 @@ A fixed joint ensures that two rigid-bodies don't move relative to each other. F ```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], @@ -690,6 +697,9 @@ The spherical joint ensures that two points on the local-spaces of two rigid-bod ```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], @@ -718,6 +728,9 @@ The revolute joint prevents any relative movement between two rigid-bodies, exce ```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], @@ -749,6 +762,9 @@ The prismatic joint prevents any relative movement between two rigid-bodies, exc ```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], @@ -772,6 +788,83 @@ const JointedThing = () => { }; ``` +### Rope Joint + +The rope joint limits the max distance between two bodies. + +🧩 See [RopeJoint docs](https://pmndrs.github.io/react-three-rapier/functions/useRopeJoint.html) for available options. + +```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 ( + + + + + + + + + ); +}; +``` + +### Spring Joint + +The spring joint applies a force proportional to the distance between two bodies. + +🧩 See [SpringJoint docs](https://pmndrs.github.io/react-three-rapier/functions/useSpringJoint.html) for available options. + +```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 ( + + + + + + + + + ); +}; +``` + ### 🖼 Joints Example diff --git a/packages/react-three-rapier/src/components/Physics.tsx b/packages/react-three-rapier/src/components/Physics.tsx index 3efae2f1..e9dae607 100644 --- a/packages/react-three-rapier/src/components/Physics.tsx +++ b/packages/react-three-rapier/src/components/Physics.tsx @@ -29,7 +29,6 @@ import { RigidBodyAutoCollider, Vector3Tuple } from "../types"; - import { _matrix4, _position, @@ -39,7 +38,8 @@ import { import { rapierQuaternionToQuaternion, useConst, - vectorArrayToVector3 + vectorArrayToVector3, + vector3ToRapierVector } from "../utils/utils"; import FrameStepper from "./FrameStepper"; import { Debug } from "./Debug"; @@ -257,32 +257,37 @@ export interface PhysicsProps { gravity?: Vector3Tuple; /** - * The maximum velocity iterations the velocity-based constraint solver can make to attempt - * to remove the energy introduced by constraint stabilization. - * - * @defaultValue 1 + * Amount of penetration the engine wont attempt to correct + * @defaultValue 0.001 */ - maxStabilizationIterations?: number; + allowedLinearError?: number; /** - * The maximum velocity iterations the velocity-based friction constraint solver can make. - * - * The greater this value is, the most realistic friction will be. + * The number of solver iterations run by the constraints solver for calculating forces. + * The greater this value is, the most rigid and realistic the physics simulation will be. * However a greater number of iterations is more computationally intensive. * - * @defaultValue 8 + * @defaultValue 4 */ - maxVelocityFrictionIterations?: number; + numSolverIterations?: number; /** - * The maximum velocity iterations the velocity-based force constraint solver can make. - * - * The greater this value is, the most rigid and realistic the physics simulation will be. + * Number of addition friction resolution iteration run during the last solver sub-step. + * The greater this value is, the most realistic friction will be. * However a greater number of iterations is more computationally intensive. * * @defaultValue 4 */ - maxVelocityIterations?: number; + numAdditionalFrictionIterations?: number; + + /** + * Number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration. + * Increasing this parameter will improve stability of the simulation. It will have a lesser effect than + * increasing `numSolverIterations` but is also less computationally expensive. + * + * @defaultValue 1 + */ + numInternalPgsIterations?: number; /** * The maximal distance separating two objects that will generate predictive contacts @@ -293,7 +298,22 @@ export interface PhysicsProps { predictionDistance?: number; /** - * The Error Reduction Parameter in between 0 and 1, is the proportion of the positional error to be corrected at each time step + * Minimum number of dynamic bodies in each active island + * + * @defaultValue 128 + */ + minIslandSize?: number; + + /** + * Maximum number of substeps performed by the solver + * + * @defaultValue 1 + */ + maxCcdSubsteps?: number; + + /** + * The Error Reduction Parameter in between 0 and 1, is the proportion of the positional error to be corrected at each time step. + * * @defaultValue 0.8 */ erp?: number; @@ -380,10 +400,13 @@ export const Physics: FC = (props) => { debug = false, gravity = [0, -9.81, 0], - maxStabilizationIterations = 1, - maxVelocityFrictionIterations = 8, - maxVelocityIterations = 4, + allowedLinearError = 0.001, predictionDistance = 0.002, + numSolverIterations = 4, + numAdditionalFrictionIterations = 4, + numInternalPgsIterations = 1, + minIslandSize = 128, + maxCcdSubsteps = 1, erp = 0.8 } = props; const rapier = useAsset(importRapier); @@ -420,21 +443,28 @@ export const Physics: FC = (props) => { // Update mutable props useEffect(() => { - worldProxy.gravity = vectorArrayToVector3(gravity); - worldProxy.integrationParameters.maxStabilizationIterations = - maxStabilizationIterations; - worldProxy.integrationParameters.maxVelocityFrictionIterations = - maxVelocityFrictionIterations; - worldProxy.integrationParameters.maxVelocityIterations = - maxVelocityIterations; + worldProxy.gravity = vector3ToRapierVector(gravity); + + worldProxy.integrationParameters.numSolverIterations = numSolverIterations; + worldProxy.integrationParameters.numAdditionalFrictionIterations = + numAdditionalFrictionIterations; + worldProxy.integrationParameters.numInternalPgsIterations = + numInternalPgsIterations; + + worldProxy.integrationParameters.allowedLinearError = allowedLinearError; + worldProxy.integrationParameters.minIslandSize = minIslandSize; + worldProxy.integrationParameters.maxCcdSubsteps = maxCcdSubsteps; worldProxy.integrationParameters.predictionDistance = predictionDistance; worldProxy.integrationParameters.erp = erp; }, [ worldProxy, ...gravity, - maxStabilizationIterations, - maxVelocityIterations, - maxVelocityFrictionIterations, + numSolverIterations, + numAdditionalFrictionIterations, + numInternalPgsIterations, + allowedLinearError, + minIslandSize, + maxCcdSubsteps, predictionDistance, erp ]); diff --git a/packages/react-three-rapier/src/hooks/joints.ts b/packages/react-three-rapier/src/hooks/joints.ts index 889efc10..657502bb 100644 --- a/packages/react-three-rapier/src/hooks/joints.ts +++ b/packages/react-three-rapier/src/hooks/joints.ts @@ -1,28 +1,28 @@ import { - ImpulseJoint, FixedImpulseJoint, - SphericalImpulseJoint, + ImpulseJoint, + PrismaticImpulseJoint, RevoluteImpulseJoint, - PrismaticImpulseJoint + RopeImpulseJoint, + SphericalImpulseJoint, + SpringImpulseJoint, } from "@dimforge/rapier3d-compat"; -import React, { - useRef, - useEffect, - useMemo, - useState, - MutableRefObject, - RefObject -} from "react"; +import { RefObject, useRef } from "react"; import { - useRapier, - RapierRigidBody, - UseImpulseJoint, FixedJointParams, - SphericalJointParams, + PrismaticJointParams, + RapierRigidBody, RevoluteJointParams, - PrismaticJointParams + RopeJointParams, + SphericalJointParams, + SpringJointParams, + UseImpulseJoint, + useRapier, } from ".."; -import { vectorArrayToVector3, tupleToObject } from "../utils/utils"; +import { + vector3ToRapierVector, + quaternionToRapierQuaternion +} from "../utils/utils"; import type Rapier from "@dimforge/rapier3d-compat"; import { useImperativeInstance } from "./use-imperative-instance"; @@ -88,10 +88,10 @@ export const useFixedJoint: UseImpulseJoint< body1, body2, rapier.JointData.fixed( - vectorArrayToVector3(body1Anchor), - tupleToObject(body1LocalFrame, ["x", "y", "z", "w"] as const), - vectorArrayToVector3(body2Anchor), - tupleToObject(body2LocalFrame, ["x", "y", "z", "w"] as const) + vector3ToRapierVector(body1Anchor), + quaternionToRapierQuaternion(body1LocalFrame), + vector3ToRapierVector(body2Anchor), + quaternionToRapierQuaternion(body2LocalFrame) ) ); }; @@ -114,8 +114,8 @@ export const useSphericalJoint: UseImpulseJoint< body1, body2, rapier.JointData.spherical( - vectorArrayToVector3(body1Anchor), - vectorArrayToVector3(body2Anchor) + vector3ToRapierVector(body1Anchor), + vector3ToRapierVector(body2Anchor) ) ); }; @@ -134,9 +134,9 @@ export const useRevoluteJoint: UseImpulseJoint< const { rapier } = useRapier(); const params = rapier.JointData.revolute( - vectorArrayToVector3(body1Anchor), - vectorArrayToVector3(body2Anchor), - vectorArrayToVector3(axis) + vector3ToRapierVector(body1Anchor), + vector3ToRapierVector(body2Anchor), + vector3ToRapierVector(axis) ); if (limits) { @@ -161,9 +161,9 @@ export const usePrismaticJoint: UseImpulseJoint< const { rapier } = useRapier(); const params = rapier.JointData.prismatic( - vectorArrayToVector3(body1Anchor), - vectorArrayToVector3(body2Anchor), - vectorArrayToVector3(axis) + vector3ToRapierVector(body1Anchor), + vector3ToRapierVector(body2Anchor), + vector3ToRapierVector(axis) ); if (limits) { @@ -173,3 +173,49 @@ export const usePrismaticJoint: UseImpulseJoint< return useImpulseJoint(body1, body2, params); }; + +/** + * The rope joint limits the max distance between two bodies. + * @category Hooks - Joints + */ +export const useRopeJoint: UseImpulseJoint< + RopeJointParams, + RopeImpulseJoint +> = (body1, body2, [body1Anchor, body2Anchor, length]) => { + const { rapier } = useRapier(); + + const vBody1Anchor = vector3ToRapierVector(body1Anchor); + const vBody2Anchor = vector3ToRapierVector(body2Anchor); + + const params = rapier.JointData.rope(length, vBody1Anchor, vBody2Anchor); + + return useImpulseJoint(body1, body2, params); +}; + +/** + * The spring joint applies a force proportional to the distance between two objects. + * @category Hooks - Joints + */ +export const useSpringJoint: UseImpulseJoint< + SpringJointParams, + SpringImpulseJoint +> = ( + body1, + body2, + [body1Anchor, body2Anchor, restLength, stiffness, damping] +) => { + const { rapier } = useRapier(); + + const vBody1Anchor = vector3ToRapierVector(body1Anchor); + const vBody2Anchor = vector3ToRapierVector(body2Anchor); + + const params = rapier.JointData.spring( + restLength, + stiffness, + damping, + vBody1Anchor, + vBody2Anchor + ); + + return useImpulseJoint(body1, body2, params); +}; diff --git a/packages/react-three-rapier/src/types.ts b/packages/react-three-rapier/src/types.ts index 2e03bdc4..7581dce3 100644 --- a/packages/react-three-rapier/src/types.ts +++ b/packages/react-three-rapier/src/types.ts @@ -9,7 +9,7 @@ import { TempContactManifold } from "@dimforge/rapier3d-compat"; import { Rotation, Vector } from "@dimforge/rapier3d-compat/math"; -import { Object3DProps } from "@react-three/fiber"; +import { Object3DProps, Vector3, Quaternion } from "@react-three/fiber"; import { Object3D } from "three"; import { ColliderProps } from "."; import { RigidBodyState } from "./components/Physics"; @@ -395,6 +395,17 @@ export interface RigidBodyOptions extends ColliderProps { */ restitution?: number; + /** + * Sets the number of additional solver iterations that will be run for this + * rigid-body and everything that interacts with it directly or indirectly + * through contacts or joints. + * + * Compared to increasing the global `World.numSolverIteration`, setting this + * value lets you increase accuracy on only a subset of the scene, resulting in reduced + * performance loss. + */ + additionalSolverIterations?: number; + /** * The default collision groups bitmask for all colliders in this rigid body. * Can be customized per-collider. @@ -450,31 +461,45 @@ export interface RigidBodyOptions extends ColliderProps { // Joints export type SphericalJointParams = [ - body1Anchor: Vector3Tuple, - body2Anchor: Vector3Tuple + body1Anchor: Vector3, + body2Anchor: Vector3 ]; export type FixedJointParams = [ - body1Anchor: Vector3Tuple, - body1LocalFrame: Vector4Tuple, - body2Anchor: Vector3Tuple, - body2LocalFrame: Vector4Tuple + body1Anchor: Vector3, + body1LocalFrame: Quaternion, + body2Anchor: Vector3, + body2LocalFrame: Quaternion ]; export type PrismaticJointParams = [ - body1Anchor: Vector3Tuple, - body2Anchor: Vector3Tuple, - axis: Vector3Tuple, + body1Anchor: Vector3, + body2Anchor: Vector3, + axis: Vector3, limits?: [min: number, max: number] ]; export type RevoluteJointParams = [ - body1Anchor: Vector3Tuple, - body2Anchor: Vector3Tuple, - axis: Vector3Tuple, + body1Anchor: Vector3, + body2Anchor: Vector3, + axis: Vector3, limits?: [min: number, max: number] ]; +export type RopeJointParams = [ + body1Anchor: Vector3, + body2Anchor: Vector3, + length: number +]; + +export type SpringJointParams = [ + body1Anchor: Vector3, + body2Anchor: Vector3, + restLength: number, + stiffness: number, + damping: number +]; + export interface UseImpulseJoint { ( body1: RefObject, diff --git a/packages/react-three-rapier/src/utils/utils-rigidbody.ts b/packages/react-three-rapier/src/utils/utils-rigidbody.ts index 744b5a42..190f4ab8 100644 --- a/packages/react-three-rapier/src/utils/utils-rigidbody.ts +++ b/packages/react-three-rapier/src/utils/utils-rigidbody.ts @@ -1,5 +1,5 @@ import { RigidBody, RigidBodyDesc } from "@dimforge/rapier3d-compat"; -import React, { MutableRefObject, useEffect, useMemo } from "react"; +import { useEffect, useMemo } from "react"; import { Matrix4, Object3D, Vector3 } from "three"; import { Boolean3Tuple, RigidBodyProps, Vector3Tuple } from ".."; import { @@ -81,6 +81,9 @@ export const mutableRigidBodyOptions: MutableRigidBodyOptions = { gravityScale: (rb: RigidBody, value: number) => { rb.setGravityScale(value, true); }, + additionalSolverIterations(rb: RigidBody, value: number) { + rb.setAdditionalSolverIterations(value); + }, linearDamping: (rb: RigidBody, value: number) => { rb.setLinearDamping(value); }, diff --git a/packages/react-three-rapier/src/utils/utils.ts b/packages/react-three-rapier/src/utils/utils.ts index d131d0d7..3ffce46e 100644 --- a/packages/react-three-rapier/src/utils/utils.ts +++ b/packages/react-three-rapier/src/utils/utils.ts @@ -1,36 +1,18 @@ -import React, { useRef } from "react"; +import { useRef } from "react"; import { Quaternion as RapierQuaternion, - Vector3 as RapierVector3 + Vector3 as RapierVector3, } from "@dimforge/rapier3d-compat"; - -import { Euler, Quaternion, Shape, Vector3 } from "three"; +import { Euler, Quaternion, Vector3 } from "three"; import { _euler, _quaternion, _vector3 } from "./shared-objects"; import { RigidBodyTypeString, Vector3Tuple } from "../types"; +import { Vector3 as Vector3Like, Quaternion as QuaternionLike } from "@react-three/fiber"; export const vectorArrayToVector3 = (arr: Vector3Tuple) => { const [x, y, z] = arr; return new Vector3(x, y, z); }; -export const tupleToObject = < - T extends readonly any[], - K extends readonly string[] ->( - tuple: T, - keys: K -) => { - return keys.reduce( - (obj, key, i) => { - obj[key as K[number]] = tuple[i]; - return obj; - }, - {} as { - [Key in K[number]]: T[number]; - } - ); -}; - export const vector3ToQuaternion = (v: Vector3) => { return _quaternion.setFromEuler(_euler.setFromVector3(v)); }; @@ -45,6 +27,25 @@ export const rapierQuaternionToQuaternion = ({ w }: RapierQuaternion) => _quaternion.set(x, y, z, w); +export const vector3ToRapierVector = (v: Vector3Like) => { + if (Array.isArray(v)) { + return new RapierVector3(v[0], v[1], v[2]); + } else if (typeof v === "number") { + return new RapierVector3(v, v, v); + } else { + const threeVector3 = v as THREE.Vector3; + return new RapierVector3(threeVector3.x, threeVector3.y, threeVector3.z); + } +}; + +export const quaternionToRapierQuaternion = (v: QuaternionLike) => { + if (Array.isArray(v)) { + return new RapierQuaternion(v[0], v[1], v[2], v[3]); + } else { + return new RapierQuaternion(v.x, v.y, v.z, v.w); + } +}; + const rigidBodyTypeMap = { fixed: 1, dynamic: 0, diff --git a/packages/react-three-rapier/tests/__snapshots__/physics.test.tsx.snap b/packages/react-three-rapier/tests/__snapshots__/physics.test.tsx.snap index 1e9c468c..fff728d7 100644 --- a/packages/react-three-rapier/tests/__snapshots__/physics.test.tsx.snap +++ b/packages/react-three-rapier/tests/__snapshots__/physics.test.tsx.snap @@ -4,17 +4,17 @@ exports[`physics > snapshots > restores snapshots correctly 1`] = ` [ Vector3 { "x": 0, - "y": -13.761244773864746, + "y": -13.659093856811523, "z": 0, }, Vector3 { "x": 2, - "y": -11.761244773864746, + "y": -11.659093856811523, "z": 2, }, Vector3 { "x": -2, - "y": -15.761244773864746, + "y": -15.659093856811523, "z": -2, }, ] @@ -24,17 +24,17 @@ exports[`physics > snapshots > restores snapshots correctly 2`] = ` [ Vector3 { "x": 0, - "y": -13.761244773864746, + "y": -13.659093856811523, "z": 0, }, Vector3 { "x": 2, - "y": -11.761244773864746, + "y": -11.659093856811523, "z": 2, }, Vector3 { "x": -2, - "y": -15.761244773864746, + "y": -15.659093856811523, "z": -2, }, ] diff --git a/packages/react-three-rapier/tests/physics.test.tsx b/packages/react-three-rapier/tests/physics.test.tsx index c06ee473..da9d783a 100644 --- a/packages/react-three-rapier/tests/physics.test.tsx +++ b/packages/react-three-rapier/tests/physics.test.tsx @@ -67,14 +67,14 @@ describe("physics", () => { }); expect(vec3(rigidBody.current?.translation()).toArray()).to.deep.eq([ - 0.6666666865348816, 0.6639417409896851, 0.6666666865348816 + 0.6666666269302368, 0.6649635434150696, 0.6666666269302368, ]); await pause(100); // expect nothing to have changed expect(vec3(rigidBody.current?.translation()).toArray()).to.deep.eq([ - 0.6666666865348816, 0.6639417409896851, 0.6666666865348816 + 0.6666666269302368, 0.6649635434150696, 0.6666666269302368 ]); }); }); diff --git a/yarn.lock b/yarn.lock index dda8b6d7..52faa5ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1595,10 +1595,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@dimforge/rapier3d-compat@0.11.2": - version "0.11.2" - resolved "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.11.2.tgz" - integrity sha512-vdWmlkpS3G8nGAzLuK7GYTpNdrkn/0NKCe0l1Jqxc7ZZOB3N0q9uG/Ap9l9bothWuAvxscIt0U97GVLr0lXWLg== +"@dimforge/rapier3d-compat@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz#7b3365e1dfdc5cd957b45afe920b4ac06c7cd389" + integrity sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow== "@esbuild/android-arm64@0.17.14": version "0.17.14" From 35843bbdb6a16d7086afc68ebdec4c5dd8d5b1f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:45:32 +0100 Subject: [PATCH 02/11] chore(changeset): release packages (canary) (#623) Co-authored-by: github-actions[bot] --- .changeset/pre.json | 4 +++- demo/package.json | 4 ++-- packages/react-three-rapier-addons/CHANGELOG.md | 7 +++++++ packages/react-three-rapier-addons/package.json | 6 +++--- packages/react-three-rapier/CHANGELOG.md | 13 +++++++++++++ packages/react-three-rapier/package.json | 2 +- 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 52595472..fde26af4 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -6,5 +6,7 @@ "@react-three/rapier": "1.2.1", "@react-three/rapier-addons": "3.0.3" }, - "changesets": [] + "changesets": [ + "cold-apples-drop" + ] } diff --git a/demo/package.json b/demo/package.json index 1eb9f957..217e240a 100644 --- a/demo/package.json +++ b/demo/package.json @@ -12,8 +12,8 @@ "@react-three/csg": "1.1.5", "@react-three/drei": "9.74.14", "@react-three/fiber": "8.9.1", - "@react-three/rapier": "1.2.1", - "@react-three/rapier-addons": "3.0.3", + "@react-three/rapier": "1.3.0-canary.0", + "@react-three/rapier-addons": "4.0.0-canary.0", "@types/three": "^0.152.1", "leva": "0.9.34", "r3f-perf": "6.4.2", diff --git a/packages/react-three-rapier-addons/CHANGELOG.md b/packages/react-three-rapier-addons/CHANGELOG.md index 58c0307d..5b8d3316 100644 --- a/packages/react-three-rapier-addons/CHANGELOG.md +++ b/packages/react-three-rapier-addons/CHANGELOG.md @@ -1,5 +1,12 @@ # @react-three/rapier-addons +## 4.0.0-canary.0 + +### Patch Changes + +- Updated dependencies [1517acb] + - @react-three/rapier@1.3.0-canary.0 + ## 3.0.3 ### Patch Changes diff --git a/packages/react-three-rapier-addons/package.json b/packages/react-three-rapier-addons/package.json index aef3dce9..af7a6b3c 100644 --- a/packages/react-three-rapier-addons/package.json +++ b/packages/react-three-rapier-addons/package.json @@ -1,13 +1,13 @@ { "name": "@react-three/rapier-addons", - "version": "3.0.3", + "version": "4.0.0-canary.0", "main": "dist/react-three-rapier-addons.cjs.js", "module": "dist/react-three-rapier-addons.esm.js", "license": "MIT", "sideEffects": false, "peerDependencies": { "@react-three/fiber": "*", - "@react-three/rapier": "1.x", + "@react-three/rapier": "1.3.0-canary.0", "react": ">=18.0.0", "three": "*" }, @@ -16,7 +16,7 @@ }, "devDependencies": { "@react-three/fiber": "8.9.1", - "@react-three/rapier": "1.2.1", + "@react-three/rapier": "1.3.0-canary.0", "react": "18.2.0", "react-dom": "18.2.0", "three": "0.146.0" diff --git a/packages/react-three-rapier/CHANGELOG.md b/packages/react-three-rapier/CHANGELOG.md index 7bd1c8ad..fe771007 100644 --- a/packages/react-three-rapier/CHANGELOG.md +++ b/packages/react-three-rapier/CHANGELOG.md @@ -1,5 +1,18 @@ # @react-three/rapier +## 1.3.0-canary.0 + +### Minor Changes + +- 1517acb: feat: update @dimforge/rapier3d-compat to 0.12.0 (@0xtito, @isaac-mason) + + - Change Physics component props to match the new rapier version's integration parameter changes. + - There aren't direct alternatives for all old parameters. See the Physics component docs for more information on the new parameters: https://pmndrs.github.io/react-three-rapier/interfaces/PhysicsProps.html + - Add `additionalSolverIterations` prop to `RigidBodyOptions`. + - See: https://pmndrs.github.io/react-three-rapier/interfaces/RigidBodyOptions.html#additionalSolverIterations + - Add `useSpringJoint` + - Add `useRopeJoint` + ## 1.2.1 ### Patch Changes diff --git a/packages/react-three-rapier/package.json b/packages/react-three-rapier/package.json index 1de2da64..ef582061 100644 --- a/packages/react-three-rapier/package.json +++ b/packages/react-three-rapier/package.json @@ -1,6 +1,6 @@ { "name": "@react-three/rapier", - "version": "1.2.1", + "version": "1.3.0-canary.0", "source": "src/index.ts", "main": "dist/react-three-rapier.cjs.js", "module": "dist/react-three-rapier.esm.js", From 7a74263d5be78fcc070674b31aeb2aba58e536b4 Mon Sep 17 00:00:00 2001 From: Hugo Wiledal Date: Tue, 13 Feb 2024 21:26:29 +0100 Subject: [PATCH 03/11] chore: exit canary --- .changeset/pre.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index fde26af4..a46ca45d 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,5 +1,5 @@ { - "mode": "pre", + "mode": "exit", "tag": "canary", "initialVersions": { "demo": "0.0.0", From c3ad82319a15c7a87a2708f83a6604da3b484245 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 16:18:30 +0100 Subject: [PATCH 04/11] chore(changeset): release packages (#624) Co-authored-by: github-actions[bot] --- .changeset/cold-apples-drop.md | 12 ------------ .changeset/pre.json | 12 ------------ demo/package.json | 4 ++-- packages/react-three-rapier-addons/CHANGELOG.md | 7 +++++++ packages/react-three-rapier-addons/package.json | 6 +++--- packages/react-three-rapier/CHANGELOG.md | 13 +++++++++++++ packages/react-three-rapier/package.json | 2 +- 7 files changed, 26 insertions(+), 30 deletions(-) delete mode 100644 .changeset/cold-apples-drop.md delete mode 100644 .changeset/pre.json diff --git a/.changeset/cold-apples-drop.md b/.changeset/cold-apples-drop.md deleted file mode 100644 index f76e9aa0..00000000 --- a/.changeset/cold-apples-drop.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@react-three/rapier": minor ---- - -feat: update @dimforge/rapier3d-compat to 0.12.0 (@0xtito, @isaac-mason) - -- Change Physics component props to match the new rapier version's integration parameter changes. - - There aren't direct alternatives for all old parameters. See the Physics component docs for more information on the new parameters: https://pmndrs.github.io/react-three-rapier/interfaces/PhysicsProps.html -- Add `additionalSolverIterations` prop to `RigidBodyOptions`. - - See: https://pmndrs.github.io/react-three-rapier/interfaces/RigidBodyOptions.html#additionalSolverIterations -- Add `useSpringJoint` -- Add `useRopeJoint` \ No newline at end of file diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index a46ca45d..00000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "mode": "exit", - "tag": "canary", - "initialVersions": { - "demo": "0.0.0", - "@react-three/rapier": "1.2.1", - "@react-three/rapier-addons": "3.0.3" - }, - "changesets": [ - "cold-apples-drop" - ] -} diff --git a/demo/package.json b/demo/package.json index 217e240a..4275bdb8 100644 --- a/demo/package.json +++ b/demo/package.json @@ -12,8 +12,8 @@ "@react-three/csg": "1.1.5", "@react-three/drei": "9.74.14", "@react-three/fiber": "8.9.1", - "@react-three/rapier": "1.3.0-canary.0", - "@react-three/rapier-addons": "4.0.0-canary.0", + "@react-three/rapier": "1.3.0", + "@react-three/rapier-addons": "4.0.0", "@types/three": "^0.152.1", "leva": "0.9.34", "r3f-perf": "6.4.2", diff --git a/packages/react-three-rapier-addons/CHANGELOG.md b/packages/react-three-rapier-addons/CHANGELOG.md index 5b8d3316..9f252780 100644 --- a/packages/react-three-rapier-addons/CHANGELOG.md +++ b/packages/react-three-rapier-addons/CHANGELOG.md @@ -1,5 +1,12 @@ # @react-three/rapier-addons +## 4.0.0 + +### Patch Changes + +- Updated dependencies [1517acb] + - @react-three/rapier@1.3.0 + ## 4.0.0-canary.0 ### Patch Changes diff --git a/packages/react-three-rapier-addons/package.json b/packages/react-three-rapier-addons/package.json index af7a6b3c..5831a6a3 100644 --- a/packages/react-three-rapier-addons/package.json +++ b/packages/react-three-rapier-addons/package.json @@ -1,13 +1,13 @@ { "name": "@react-three/rapier-addons", - "version": "4.0.0-canary.0", + "version": "4.0.0", "main": "dist/react-three-rapier-addons.cjs.js", "module": "dist/react-three-rapier-addons.esm.js", "license": "MIT", "sideEffects": false, "peerDependencies": { "@react-three/fiber": "*", - "@react-three/rapier": "1.3.0-canary.0", + "@react-three/rapier": "1.3.0", "react": ">=18.0.0", "three": "*" }, @@ -16,7 +16,7 @@ }, "devDependencies": { "@react-three/fiber": "8.9.1", - "@react-three/rapier": "1.3.0-canary.0", + "@react-three/rapier": "1.3.0", "react": "18.2.0", "react-dom": "18.2.0", "three": "0.146.0" diff --git a/packages/react-three-rapier/CHANGELOG.md b/packages/react-three-rapier/CHANGELOG.md index fe771007..48dd131b 100644 --- a/packages/react-three-rapier/CHANGELOG.md +++ b/packages/react-three-rapier/CHANGELOG.md @@ -1,5 +1,18 @@ # @react-three/rapier +## 1.3.0 + +### Minor Changes + +- 1517acb: feat: update @dimforge/rapier3d-compat to 0.12.0 (@0xtito, @isaac-mason) + + - Change Physics component props to match the new rapier version's integration parameter changes. + - There aren't direct alternatives for all old parameters. See the Physics component docs for more information on the new parameters: https://pmndrs.github.io/react-three-rapier/interfaces/PhysicsProps.html + - Add `additionalSolverIterations` prop to `RigidBodyOptions`. + - See: https://pmndrs.github.io/react-three-rapier/interfaces/RigidBodyOptions.html#additionalSolverIterations + - Add `useSpringJoint` + - Add `useRopeJoint` + ## 1.3.0-canary.0 ### Minor Changes diff --git a/packages/react-three-rapier/package.json b/packages/react-three-rapier/package.json index ef582061..bdf6004c 100644 --- a/packages/react-three-rapier/package.json +++ b/packages/react-three-rapier/package.json @@ -1,6 +1,6 @@ { "name": "@react-three/rapier", - "version": "1.3.0-canary.0", + "version": "1.3.0", "source": "src/index.ts", "main": "dist/react-three-rapier.cjs.js", "module": "dist/react-three-rapier.esm.js", From 92e417b18e46fd7e7215fcabc73dec9d2cd34908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Thu, 11 Apr 2024 10:50:49 +0200 Subject: [PATCH 05/11] fix: dep sorting --- packages/react-three-rapier/package.json | 4 ++-- packages/react-three-rapier/src/components/Physics.tsx | 4 ++-- yarn.lock | 9 +-------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/react-three-rapier/package.json b/packages/react-three-rapier/package.json index bdf6004c..60a63b58 100644 --- a/packages/react-three-rapier/package.json +++ b/packages/react-three-rapier/package.json @@ -30,8 +30,8 @@ }, "dependencies": { "@dimforge/rapier3d-compat": "0.12.0", - "three-stdlib": "2.23.9", - "use-asset": "1.0.4" + "suspend-react": "^0.1.3", + "three-stdlib": "2.23.9" }, "repository": "https://github.com/pmndrs/react-three-rapier/tree/master/packages/react-three-rapier" } diff --git a/packages/react-three-rapier/src/components/Physics.tsx b/packages/react-three-rapier/src/components/Physics.tsx index e9dae607..a9ad8132 100644 --- a/packages/react-three-rapier/src/components/Physics.tsx +++ b/packages/react-three-rapier/src/components/Physics.tsx @@ -18,7 +18,7 @@ import React, { useState } from "react"; import { MathUtils, Matrix4, Object3D, Quaternion, Vector3 } from "three"; -import { useAsset } from "use-asset"; +import { suspend } from "suspend-react"; import { CollisionPayload, CollisionEnterHandler, @@ -409,7 +409,7 @@ export const Physics: FC = (props) => { maxCcdSubsteps = 1, erp = 0.8 } = props; - const rapier = useAsset(importRapier); + const rapier = suspend(importRapier, ["@react-thee/rapier", importRapier]); const { invalidate } = useThree(); const rigidBodyStates = useConst(() => new Map()); diff --git a/yarn.lock b/yarn.lock index 52faa5ee..f6127fd7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4041,7 +4041,7 @@ fast-deep-equal@^2.0.1: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz" integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -7533,13 +7533,6 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -use-asset@1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/use-asset/-/use-asset-1.0.4.tgz" - integrity sha512-7/hqDrWa0iMnCoET9W1T07EmD4Eg/Wmoj/X8TGBc++ECRK4m5yTsjP4O6s0yagbxfqIOuUkIxe2/sA+VR2GxZA== - dependencies: - fast-deep-equal "^3.1.3" - util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" From bad7da749dadb51f06c81f1bc89e87b4d0fd0062 Mon Sep 17 00:00:00 2001 From: Isaac Mason Date: Sun, 14 Apr 2024 23:05:46 +1000 Subject: [PATCH 06/11] chore: add changeset --- .changeset/strong-crabs-mate.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/strong-crabs-mate.md diff --git a/.changeset/strong-crabs-mate.md b/.changeset/strong-crabs-mate.md new file mode 100644 index 00000000..e6b8d78c --- /dev/null +++ b/.changeset/strong-crabs-mate.md @@ -0,0 +1,5 @@ +--- +"@react-three/rapier": patch +--- + +fix: move away from use-asset From 14dbc0eb59a1aefa6c61a1f92db39a19b684a805 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 14 Apr 2024 23:10:04 +1000 Subject: [PATCH 07/11] chore(changeset): release packages (#656) Co-authored-by: github-actions[bot] --- .changeset/strong-crabs-mate.md | 5 ----- demo/package.json | 4 ++-- packages/react-three-rapier-addons/CHANGELOG.md | 7 +++++++ packages/react-three-rapier-addons/package.json | 6 +++--- packages/react-three-rapier/CHANGELOG.md | 6 ++++++ packages/react-three-rapier/package.json | 2 +- 6 files changed, 19 insertions(+), 11 deletions(-) delete mode 100644 .changeset/strong-crabs-mate.md diff --git a/.changeset/strong-crabs-mate.md b/.changeset/strong-crabs-mate.md deleted file mode 100644 index e6b8d78c..00000000 --- a/.changeset/strong-crabs-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-three/rapier": patch ---- - -fix: move away from use-asset diff --git a/demo/package.json b/demo/package.json index 4275bdb8..8836ba2a 100644 --- a/demo/package.json +++ b/demo/package.json @@ -12,8 +12,8 @@ "@react-three/csg": "1.1.5", "@react-three/drei": "9.74.14", "@react-three/fiber": "8.9.1", - "@react-three/rapier": "1.3.0", - "@react-three/rapier-addons": "4.0.0", + "@react-three/rapier": "1.3.1", + "@react-three/rapier-addons": "4.0.1", "@types/three": "^0.152.1", "leva": "0.9.34", "r3f-perf": "6.4.2", diff --git a/packages/react-three-rapier-addons/CHANGELOG.md b/packages/react-three-rapier-addons/CHANGELOG.md index 9f252780..ffaa58d3 100644 --- a/packages/react-three-rapier-addons/CHANGELOG.md +++ b/packages/react-three-rapier-addons/CHANGELOG.md @@ -1,5 +1,12 @@ # @react-three/rapier-addons +## 4.0.1 + +### Patch Changes + +- Updated dependencies [bad7da7] + - @react-three/rapier@1.3.1 + ## 4.0.0 ### Patch Changes diff --git a/packages/react-three-rapier-addons/package.json b/packages/react-three-rapier-addons/package.json index 5831a6a3..97f44885 100644 --- a/packages/react-three-rapier-addons/package.json +++ b/packages/react-three-rapier-addons/package.json @@ -1,13 +1,13 @@ { "name": "@react-three/rapier-addons", - "version": "4.0.0", + "version": "4.0.1", "main": "dist/react-three-rapier-addons.cjs.js", "module": "dist/react-three-rapier-addons.esm.js", "license": "MIT", "sideEffects": false, "peerDependencies": { "@react-three/fiber": "*", - "@react-three/rapier": "1.3.0", + "@react-three/rapier": "1.3.1", "react": ">=18.0.0", "three": "*" }, @@ -16,7 +16,7 @@ }, "devDependencies": { "@react-three/fiber": "8.9.1", - "@react-three/rapier": "1.3.0", + "@react-three/rapier": "1.3.1", "react": "18.2.0", "react-dom": "18.2.0", "three": "0.146.0" diff --git a/packages/react-three-rapier/CHANGELOG.md b/packages/react-three-rapier/CHANGELOG.md index 48dd131b..7f2b3aa6 100644 --- a/packages/react-three-rapier/CHANGELOG.md +++ b/packages/react-three-rapier/CHANGELOG.md @@ -1,5 +1,11 @@ # @react-three/rapier +## 1.3.1 + +### Patch Changes + +- bad7da7: fix: move away from use-asset + ## 1.3.0 ### Minor Changes diff --git a/packages/react-three-rapier/package.json b/packages/react-three-rapier/package.json index 60a63b58..e0c97029 100644 --- a/packages/react-three-rapier/package.json +++ b/packages/react-three-rapier/package.json @@ -1,6 +1,6 @@ { "name": "@react-three/rapier", - "version": "1.3.0", + "version": "1.3.1", "source": "src/index.ts", "main": "dist/react-three-rapier.cjs.js", "module": "dist/react-three-rapier.esm.js", From a1552773509eb6b34409f3192ed4b057387708eb Mon Sep 17 00:00:00 2001 From: Isaac Mason Date: Fri, 14 Jun 2024 23:44:34 +1000 Subject: [PATCH 08/11] feat: update to @dimforge/rapier3d-compat 0.13.1 (#677) * feat: bump @dimforge/rapier3d-compat to 0.13.1, expose new functionality * chore: prettier format * chore: add contact skin demo * fix: add softCcdPrediction to cleanRigidBodyPropsForCollider * chore: update changeset * fix: prettier format * chore: change @react-three/rapier-addons to depend on @react-three/rapier ^1.3.1 --- .changeset/little-doors-doubt.md | 10 ++++++ demo/src/App.tsx | 4 ++- .../contact-skin/ContactSkinExample.tsx | 34 +++++++++++++++++++ .../react-three-rapier-addons/package.json | 4 +-- packages/react-three-rapier/package.json | 2 +- .../src/components/Physics.tsx | 23 ++++++++++--- .../react-three-rapier/src/hooks/joints.ts | 4 +-- packages/react-three-rapier/src/types.ts | 33 +++++++++++++++--- .../src/utils/singleton-proxy.ts | 8 +++-- .../src/utils/utils-collider.ts | 4 +++ .../src/utils/utils-rigidbody.ts | 3 ++ .../react-three-rapier/src/utils/utils.ts | 7 ++-- .../react-three-rapier/tests/physics.test.tsx | 2 +- yarn.lock | 8 ++--- 14 files changed, 123 insertions(+), 23 deletions(-) create mode 100644 .changeset/little-doors-doubt.md create mode 100644 demo/src/examples/contact-skin/ContactSkinExample.tsx diff --git a/.changeset/little-doors-doubt.md b/.changeset/little-doors-doubt.md new file mode 100644 index 00000000..c42407d4 --- /dev/null +++ b/.changeset/little-doors-doubt.md @@ -0,0 +1,10 @@ +--- +"@react-three/rapier": minor +--- + +feat: bump @dimforge/rapier3d-compat from 0.12.0 to 0.13.1 + +- Added World prop `lengthUnit` +- Renamed World props `allowedLinearError` and `predictionDistance` to `normalizedAllowedLinearError` and `normalizedPredictionDistance`, matching upstream changes +- Added `softCcdPrediction` RigidBody prop +- Added `contactSkin` collider prop diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 824ef213..c17babf3 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -21,6 +21,7 @@ import { Colliders } from "./examples/colliders/CollidersExample"; import { CollisionEventsExample } from "./examples/collision-events/CollisionEventsExample"; import { ComponentsExample } from "./examples/components/ComponentsExample"; import { ContactForceEventsExample } from "./examples/contact-force-events/ContactForceEventsExample"; +import { ContactSkinExample } from "./examples/contact-skin/ContactSkinExample"; import { CradleExample } from "./examples/cradle/CradleExample"; import { Damping } from "./examples/damping/DampingExample"; import { DynamicTypeChangeExample } from "./examples/dynamic-type-change/DynamicTypeChangeExample"; @@ -119,7 +120,8 @@ const routes: Record = { "immutable-props": , snapshot: , spring: , - "rope-joint": + "rope-joint": , + "contact-skin": }; export const App = () => { diff --git a/demo/src/examples/contact-skin/ContactSkinExample.tsx b/demo/src/examples/contact-skin/ContactSkinExample.tsx new file mode 100644 index 00000000..ade7b7d5 --- /dev/null +++ b/demo/src/examples/contact-skin/ContactSkinExample.tsx @@ -0,0 +1,34 @@ +import { Box, Sphere } from "@react-three/drei"; +import { RapierRigidBody, RigidBody } from "@react-three/rapier"; +import { useRef } from "react"; + +const Ball = () => { + const rb = useRef(null); + + return ( + + + + + + ); +}; + +const Floor = () => { + return ( + + + + + + ); +}; + +export const ContactSkinExample = () => { + return ( + + + + + ); +}; diff --git a/packages/react-three-rapier-addons/package.json b/packages/react-three-rapier-addons/package.json index 97f44885..a282adf3 100644 --- a/packages/react-three-rapier-addons/package.json +++ b/packages/react-three-rapier-addons/package.json @@ -7,7 +7,7 @@ "sideEffects": false, "peerDependencies": { "@react-three/fiber": "*", - "@react-three/rapier": "1.3.1", + "@react-three/rapier": "^1.3.1", "react": ">=18.0.0", "three": "*" }, @@ -16,7 +16,7 @@ }, "devDependencies": { "@react-three/fiber": "8.9.1", - "@react-three/rapier": "1.3.1", + "@react-three/rapier": "^1.3.1", "react": "18.2.0", "react-dom": "18.2.0", "three": "0.146.0" diff --git a/packages/react-three-rapier/package.json b/packages/react-three-rapier/package.json index e0c97029..9983fb3b 100644 --- a/packages/react-three-rapier/package.json +++ b/packages/react-three-rapier/package.json @@ -29,7 +29,7 @@ "three": ">=0.139.0" }, "dependencies": { - "@dimforge/rapier3d-compat": "0.12.0", + "@dimforge/rapier3d-compat": "0.13.1", "suspend-react": "^0.1.3", "three-stdlib": "2.23.9" }, diff --git a/packages/react-three-rapier/src/components/Physics.tsx b/packages/react-three-rapier/src/components/Physics.tsx index a9ad8132..504c097c 100644 --- a/packages/react-three-rapier/src/components/Physics.tsx +++ b/packages/react-three-rapier/src/components/Physics.tsx @@ -318,6 +318,16 @@ export interface PhysicsProps { */ erp?: number; + /** + * The approximate size of most dynamic objects in the scene. + * + * This value is used internally to estimate some length-based tolerance. + * This value can be understood as the number of units-per-meter in your physical world compared to a human-sized world in meter. + * + * @defaultValue 1 + */ + lengthUnit?: number; + /** * Set the base automatic colliders for this physics world * All Meshes inside RigidBodies will generate a collider @@ -407,7 +417,8 @@ export const Physics: FC = (props) => { numInternalPgsIterations = 1, minIslandSize = 128, maxCcdSubsteps = 1, - erp = 0.8 + erp = 0.8, + lengthUnit = 1 } = props; const rapier = suspend(importRapier, ["@react-thee/rapier", importRapier]); const { invalidate } = useThree(); @@ -451,11 +462,14 @@ export const Physics: FC = (props) => { worldProxy.integrationParameters.numInternalPgsIterations = numInternalPgsIterations; - worldProxy.integrationParameters.allowedLinearError = allowedLinearError; + worldProxy.integrationParameters.normalizedAllowedLinearError = + allowedLinearError; worldProxy.integrationParameters.minIslandSize = minIslandSize; worldProxy.integrationParameters.maxCcdSubsteps = maxCcdSubsteps; - worldProxy.integrationParameters.predictionDistance = predictionDistance; + worldProxy.integrationParameters.normalizedPredictionDistance = + predictionDistance; worldProxy.integrationParameters.erp = erp; + worldProxy.lengthUnit = lengthUnit; }, [ worldProxy, ...gravity, @@ -466,7 +480,8 @@ export const Physics: FC = (props) => { minIslandSize, maxCcdSubsteps, predictionDistance, - erp + erp, + lengthUnit ]); const getSourceFromColliderHandle = useCallback((handle: ColliderHandle) => { diff --git a/packages/react-three-rapier/src/hooks/joints.ts b/packages/react-three-rapier/src/hooks/joints.ts index 657502bb..1909331b 100644 --- a/packages/react-three-rapier/src/hooks/joints.ts +++ b/packages/react-three-rapier/src/hooks/joints.ts @@ -5,7 +5,7 @@ import { RevoluteImpulseJoint, RopeImpulseJoint, SphericalImpulseJoint, - SpringImpulseJoint, + SpringImpulseJoint } from "@dimforge/rapier3d-compat"; import { RefObject, useRef } from "react"; import { @@ -17,7 +17,7 @@ import { SphericalJointParams, SpringJointParams, UseImpulseJoint, - useRapier, + useRapier } from ".."; import { vector3ToRapierVector, diff --git a/packages/react-three-rapier/src/types.ts b/packages/react-three-rapier/src/types.ts index 7581dce3..7316ca0a 100644 --- a/packages/react-three-rapier/src/types.ts +++ b/packages/react-three-rapier/src/types.ts @@ -250,6 +250,19 @@ export interface ColliderOptions> { angularInertiaLocalFrame: Rotation; }; + /** + * The contact skin of the collider. + * + * The contact skin acts as if the collider was enlarged with a skin of width contactSkin around it, keeping objects further apart when colliding. + * + * A non-zero contact skin can increase performance, and in some cases, stability. + * However it creates a small gap between colliding object (equal to the sum of their skin). + * If the skin is sufficiently small, this might not be visually significant or can be hidden by the rendering assets. + * + * @defaultValue 0 + */ + contactSkin?: number; + /** * Sets whether or not this collider is a sensor. */ @@ -362,6 +375,21 @@ export interface RigidBodyOptions extends ColliderProps { */ ccd?: boolean; + /** + * The maximum prediction distance Soft Continuous Collision-Detection. + * + * When set to 0, soft-CCD is disabled. + * + * Soft-CCD helps prevent tunneling especially of slow-but-thin to moderately fast objects. + * The soft CCD prediction distance indicates how far in the object’s path the CCD algorithm is allowed to inspect. + * Large values can impact performance badly by increasing the work needed from the broad-phase. + * + * It is a generally cheaper variant of regular CCD since it relies on predictive constraints instead of shape-cast and substeps. + * + * @defaultValue 0 + */ + softCcdPrediction?: number; + /** * Initial position of the RigidBody */ @@ -460,10 +488,7 @@ export interface RigidBodyOptions extends ColliderProps { } // Joints -export type SphericalJointParams = [ - body1Anchor: Vector3, - body2Anchor: Vector3 -]; +export type SphericalJointParams = [body1Anchor: Vector3, body2Anchor: Vector3]; export type FixedJointParams = [ body1Anchor: Vector3, diff --git a/packages/react-three-rapier/src/utils/singleton-proxy.ts b/packages/react-three-rapier/src/utils/singleton-proxy.ts index 4721c5a0..cc2260b0 100644 --- a/packages/react-three-rapier/src/utils/singleton-proxy.ts +++ b/packages/react-three-rapier/src/utils/singleton-proxy.ts @@ -6,13 +6,17 @@ */ export const createSingletonProxy = < SingletonClass extends object, - CreationFn extends () => SingletonClass = () => SingletonClass, + CreationFn extends () => SingletonClass = () => SingletonClass >( /** * A function that returns a new instance of the class */ createInstance: CreationFn -): { proxy: SingletonClass; reset: () => void, set: (newInstance: SingletonClass) => void } => { +): { + proxy: SingletonClass; + reset: () => void; + set: (newInstance: SingletonClass) => void; +} => { let instance: SingletonClass | undefined; const handler: ProxyHandler = { diff --git a/packages/react-three-rapier/src/utils/utils-collider.ts b/packages/react-three-rapier/src/utils/utils-collider.ts index f8cf73cf..5789dc6a 100644 --- a/packages/react-three-rapier/src/utils/utils-collider.ts +++ b/packages/react-three-rapier/src/utils/utils-collider.ts @@ -138,6 +138,9 @@ const mutableColliderOptions: MutableColliderOptions = { restitutionCombineRule: (collider, value) => { collider.setRestitutionCombineRule(value); }, + contactSkin: (collider, value: number) => { + collider.setContactSkin(value); + }, // To make sure the options all mutable options are listed quaternion: () => {}, position: () => {}, @@ -476,6 +479,7 @@ export const cleanRigidBodyPropsForCollider = (props: RigidBodyProps = {}) => { canSleep, ccd, gravityScale, + softCcdPrediction, ...rest } = props; diff --git a/packages/react-three-rapier/src/utils/utils-rigidbody.ts b/packages/react-three-rapier/src/utils/utils-rigidbody.ts index 190f4ab8..05f30017 100644 --- a/packages/react-three-rapier/src/utils/utils-rigidbody.ts +++ b/packages/react-three-rapier/src/utils/utils-rigidbody.ts @@ -114,6 +114,9 @@ export const mutableRigidBodyOptions: MutableRigidBodyOptions = { ccd: (rb: RigidBody, value: boolean) => { rb.enableCcd(value); }, + softCcdPrediction: (rb: RigidBody, value: number) => { + rb.setSoftCcdPrediction(value); + }, userData: (rb: RigidBody, value: { [key: string]: any }) => { rb.userData = value; }, diff --git a/packages/react-three-rapier/src/utils/utils.ts b/packages/react-three-rapier/src/utils/utils.ts index 3ffce46e..fc7ebc71 100644 --- a/packages/react-three-rapier/src/utils/utils.ts +++ b/packages/react-three-rapier/src/utils/utils.ts @@ -1,12 +1,15 @@ import { useRef } from "react"; import { Quaternion as RapierQuaternion, - Vector3 as RapierVector3, + Vector3 as RapierVector3 } from "@dimforge/rapier3d-compat"; import { Euler, Quaternion, Vector3 } from "three"; import { _euler, _quaternion, _vector3 } from "./shared-objects"; import { RigidBodyTypeString, Vector3Tuple } from "../types"; -import { Vector3 as Vector3Like, Quaternion as QuaternionLike } from "@react-three/fiber"; +import { + Vector3 as Vector3Like, + Quaternion as QuaternionLike +} from "@react-three/fiber"; export const vectorArrayToVector3 = (arr: Vector3Tuple) => { const [x, y, z] = arr; diff --git a/packages/react-three-rapier/tests/physics.test.tsx b/packages/react-three-rapier/tests/physics.test.tsx index da9d783a..8f8b9b38 100644 --- a/packages/react-three-rapier/tests/physics.test.tsx +++ b/packages/react-three-rapier/tests/physics.test.tsx @@ -67,7 +67,7 @@ describe("physics", () => { }); expect(vec3(rigidBody.current?.translation()).toArray()).to.deep.eq([ - 0.6666666269302368, 0.6649635434150696, 0.6666666269302368, + 0.6666666269302368, 0.6649635434150696, 0.6666666269302368 ]); await pause(100); diff --git a/yarn.lock b/yarn.lock index f6127fd7..45668acf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1595,10 +1595,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@dimforge/rapier3d-compat@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz#7b3365e1dfdc5cd957b45afe920b4ac06c7cd389" - integrity sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow== +"@dimforge/rapier3d-compat@0.13.1": + version "0.13.1" + resolved "https://registry.yarnpkg.com/@dimforge/rapier3d-compat/-/rapier3d-compat-0.13.1.tgz#d9da32941de5fcfae55ffb6ac26c38539f57ddf4" + integrity sha512-SsQ/MTH4Vvs8f62g31iVV1VOmzwNwsJl91rVzafi5B2mCrI2OsQ3VyjJOb4/tvS5VNc6OLjIDgfClcOAkW+O2A== "@esbuild/android-arm64@0.17.14": version "0.17.14" From 1dc78d0e28c43d5ba1744805e46787bd0f2f2aa3 Mon Sep 17 00:00:00 2001 From: Isaac Mason Date: Fri, 14 Jun 2024 23:46:10 +1000 Subject: [PATCH 09/11] feat: add activeCollisionTypes prop to RigidBody and Collider components (#678) * feat: add activeCollisionTypes prop to RigidBody and Collider components * chore: add changeset * chore: cleanup ActiveCollisionTypesExample * fix: revert unintentional version bumps * feat: organise imports * fix: revert unintentional version bumps * chore: change @react-three/rapier-addons to depend on @react-three/rapier ^1.3.1 --- .changeset/green-paws-mix.md | 5 ++ demo/src/App.tsx | 4 +- .../ActiveCollisionTypesExample.tsx | 57 +++++++++++++++++++ packages/react-three-rapier/src/types.ts | 30 ++++++++-- .../src/utils/utils-collider.ts | 3 + 5 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 .changeset/green-paws-mix.md create mode 100644 demo/src/examples/active-collision-types/ActiveCollisionTypesExample.tsx diff --git a/.changeset/green-paws-mix.md b/.changeset/green-paws-mix.md new file mode 100644 index 00000000..9520c8c2 --- /dev/null +++ b/.changeset/green-paws-mix.md @@ -0,0 +1,5 @@ +--- +"@react-three/rapier": patch +--- + +feat: add `activeCollisionTypes` prop to RigidBody and Collider components diff --git a/demo/src/App.tsx b/demo/src/App.tsx index c17babf3..25b1cd41 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -41,6 +41,7 @@ import { SnapshotExample } from "./examples/snapshot/SnapshotExample"; import { SpringExample } from "./examples/spring/SpringExample"; import { StutteringExample } from "./examples/stuttering/StutteringExample"; import { Transforms } from "./examples/transforms/TransformsExample"; +import { ActiveCollisionTypesExample } from "./examples/active-collision-types/ActiveCollisionTypesExample"; const demoContext = createContext<{ setDebug?(f: boolean): void; @@ -121,7 +122,8 @@ const routes: Record = { snapshot: , spring: , "rope-joint": , - "contact-skin": + "active-collision-types": , + "contact-skin": , }; export const App = () => { diff --git a/demo/src/examples/active-collision-types/ActiveCollisionTypesExample.tsx b/demo/src/examples/active-collision-types/ActiveCollisionTypesExample.tsx new file mode 100644 index 00000000..8f319cb2 --- /dev/null +++ b/demo/src/examples/active-collision-types/ActiveCollisionTypesExample.tsx @@ -0,0 +1,57 @@ +import { ActiveCollisionTypes } from "@dimforge/rapier3d-compat"; +import { Box, Sphere } from "@react-three/drei"; +import { useFrame } from "@react-three/fiber"; +import { RapierRigidBody, RigidBody } from "@react-three/rapier"; +import { useRef, useState } from "react"; + +const activeCollisionTypes = + ActiveCollisionTypes.DEFAULT | ActiveCollisionTypes.KINEMATIC_FIXED; + +const Ball = () => { + const rb = useRef(null); + + const [color, setColor] = useState("blue"); + + useFrame(({ clock: { elapsedTime } }) => { + if (!rb.current) return; + + rb.current.setTranslation( + { x: Math.sin(elapsedTime) * 3, y: 0, z: 0 }, + true + ); + }); + + return ( + setColor("green")} + onCollisionExit={() => setColor("blue")} + > + + + + + ); +}; + +const Wall = () => { + return ( + + + + + + ); +}; + +export const ActiveCollisionTypesExample = () => { + return ( + + + + + ); +}; diff --git a/packages/react-three-rapier/src/types.ts b/packages/react-three-rapier/src/types.ts index 7316ca0a..eb53db46 100644 --- a/packages/react-three-rapier/src/types.ts +++ b/packages/react-three-rapier/src/types.ts @@ -1,21 +1,22 @@ import { MutableRefObject, RefObject } from "react"; import { + ActiveCollisionTypes, CoefficientCombineRule, - Collider as RapierCollider, ImpulseJoint, InteractionGroups, + Collider as RapierCollider, RigidBody as RapierRigidBody, TempContactManifold } from "@dimforge/rapier3d-compat"; import { Rotation, Vector } from "@dimforge/rapier3d-compat/math"; -import { Object3DProps, Vector3, Quaternion } from "@react-three/fiber"; +import { Object3DProps, Quaternion, Vector3 } from "@react-three/fiber"; import { Object3D } from "three"; import { ColliderProps } from "."; import { RigidBodyState } from "./components/Physics"; export { CoefficientCombineRule as CoefficientCombineRule } from "@dimforge/rapier3d-compat"; -export { RapierRigidBody, RapierCollider }; +export { RapierCollider, RapierRigidBody }; export type RefGetter = MutableRefObject<() => T | undefined>; @@ -187,7 +188,7 @@ export interface ColliderOptions> { scale?: Object3DProps["scale"]; /** - * Callback when this collider collides with another collider. + * Callback when this collider collideas with another collider. */ onCollisionEnter?: CollisionEnterHandler; @@ -221,6 +222,16 @@ export interface ColliderOptions> { */ solverGroups?: InteractionGroups; + /** + * The collision types active for this collider. + * + * Use `ActiveCollisionTypes` to specify which collision types should be active for this collider. + * + * @see https://rapier.rs/javascript3d/classes/Collider.html#setActiveCollisionTypes + * @see https://rapier.rs/javascript3d/enums/ActiveCollisionTypes.html + */ + activeCollisionTypes?: ActiveCollisionTypes; + /** * Sets the uniform density of this collider. * If this is set, other mass-properties like the angular inertia tensor are computed @@ -446,6 +457,17 @@ export interface RigidBodyOptions extends ColliderProps { */ solverGroups?: InteractionGroups; + /** + * The default active collision types for all colliders in this rigid body. + * Can be customized per-collider. + * + * Use `ActiveCollisionTypes` to specify which collision types should be active for this collider. + * + * @see https://rapier.rs/javascript3d/classes/Collider.html#setActiveCollisionTypes + * @see https://rapier.rs/javascript3d/enums/ActiveCollisionTypes.html + */ + activeCollisionTypes?: ActiveCollisionTypes; + onSleep?(): void; onWake?(): void; diff --git a/packages/react-three-rapier/src/utils/utils-collider.ts b/packages/react-three-rapier/src/utils/utils-collider.ts index 5789dc6a..c2bdd22c 100644 --- a/packages/react-three-rapier/src/utils/utils-collider.ts +++ b/packages/react-three-rapier/src/utils/utils-collider.ts @@ -138,6 +138,9 @@ const mutableColliderOptions: MutableColliderOptions = { restitutionCombineRule: (collider, value) => { collider.setRestitutionCombineRule(value); }, + activeCollisionTypes: (collider, value: number) => { + collider.setActiveCollisionTypes(value); + }, contactSkin: (collider, value: number) => { collider.setContactSkin(value); }, From 582faa1f5b52d72cdaa31ade1eb338f08e9d08d2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 14 Jun 2024 23:59:00 +1000 Subject: [PATCH 10/11] chore(changeset): release packages (#685) Co-authored-by: github-actions[bot] --- .changeset/green-paws-mix.md | 5 ----- .changeset/little-doors-doubt.md | 10 ---------- demo/package.json | 2 +- packages/react-three-rapier/CHANGELOG.md | 15 +++++++++++++++ packages/react-three-rapier/package.json | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 .changeset/green-paws-mix.md delete mode 100644 .changeset/little-doors-doubt.md diff --git a/.changeset/green-paws-mix.md b/.changeset/green-paws-mix.md deleted file mode 100644 index 9520c8c2..00000000 --- a/.changeset/green-paws-mix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-three/rapier": patch ---- - -feat: add `activeCollisionTypes` prop to RigidBody and Collider components diff --git a/.changeset/little-doors-doubt.md b/.changeset/little-doors-doubt.md deleted file mode 100644 index c42407d4..00000000 --- a/.changeset/little-doors-doubt.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@react-three/rapier": minor ---- - -feat: bump @dimforge/rapier3d-compat from 0.12.0 to 0.13.1 - -- Added World prop `lengthUnit` -- Renamed World props `allowedLinearError` and `predictionDistance` to `normalizedAllowedLinearError` and `normalizedPredictionDistance`, matching upstream changes -- Added `softCcdPrediction` RigidBody prop -- Added `contactSkin` collider prop diff --git a/demo/package.json b/demo/package.json index 8836ba2a..14d67c24 100644 --- a/demo/package.json +++ b/demo/package.json @@ -12,7 +12,7 @@ "@react-three/csg": "1.1.5", "@react-three/drei": "9.74.14", "@react-three/fiber": "8.9.1", - "@react-three/rapier": "1.3.1", + "@react-three/rapier": "1.4.0", "@react-three/rapier-addons": "4.0.1", "@types/three": "^0.152.1", "leva": "0.9.34", diff --git a/packages/react-three-rapier/CHANGELOG.md b/packages/react-three-rapier/CHANGELOG.md index 7f2b3aa6..01f959a0 100644 --- a/packages/react-three-rapier/CHANGELOG.md +++ b/packages/react-three-rapier/CHANGELOG.md @@ -1,5 +1,20 @@ # @react-three/rapier +## 1.4.0 + +### Minor Changes + +- a155277: feat: bump @dimforge/rapier3d-compat from 0.12.0 to 0.13.1 + + - Added World prop `lengthUnit` + - Renamed World props `allowedLinearError` and `predictionDistance` to `normalizedAllowedLinearError` and `normalizedPredictionDistance`, matching upstream changes + - Added `softCcdPrediction` RigidBody prop + - Added `contactSkin` collider prop + +### Patch Changes + +- 1dc78d0: feat: add `activeCollisionTypes` prop to RigidBody and Collider components + ## 1.3.1 ### Patch Changes diff --git a/packages/react-three-rapier/package.json b/packages/react-three-rapier/package.json index 9983fb3b..b0299e48 100644 --- a/packages/react-three-rapier/package.json +++ b/packages/react-three-rapier/package.json @@ -1,6 +1,6 @@ { "name": "@react-three/rapier", - "version": "1.3.1", + "version": "1.4.0", "source": "src/index.ts", "main": "dist/react-three-rapier.cjs.js", "module": "dist/react-three-rapier.esm.js", From 47bbc3cbebce199a048b6f4ea6b23bd89d3092e4 Mon Sep 17 00:00:00 2001 From: Isaac Mason Date: Sat, 15 Jun 2024 00:11:46 +1000 Subject: [PATCH 11/11] chore: update CHANGELOG.md (#687) --- packages/react-three-rapier/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-three-rapier/CHANGELOG.md b/packages/react-three-rapier/CHANGELOG.md index 01f959a0..33e417b4 100644 --- a/packages/react-three-rapier/CHANGELOG.md +++ b/packages/react-three-rapier/CHANGELOG.md @@ -5,7 +5,8 @@ ### Minor Changes - a155277: feat: bump @dimforge/rapier3d-compat from 0.12.0 to 0.13.1 - + + - See the rapier.js changelog for more information: https://github.com/dimforge/rapier.js/blob/master/CHANGELOG.md - Added World prop `lengthUnit` - Renamed World props `allowedLinearError` and `predictionDistance` to `normalizedAllowedLinearError` and `normalizedPredictionDistance`, matching upstream changes - Added `softCcdPrediction` RigidBody prop