Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: continuation of update @dimforge/rapier3d-compat to 0.12.0 + optimizations #619

Merged
merged 13 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/cold-apples-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@react-three/rapier": minor
---

feat: update @dimforge/rapier3d-compat to 0.12.0

- 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`
30 changes: 16 additions & 14 deletions demo/src/App.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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;
Expand Down Expand Up @@ -116,7 +117,9 @@ const routes: Record<string, ReactNode> = {
"dynamic-type-changes": <DynamicTypeChangeExample />,
stuttering: <StutteringExample />,
"immutable-props": <ImmutablePropsExample />,
snapshot: <SnapshotExample />
snapshot: <SnapshotExample />,
spring: <SpringExample />,
"rope-joint": <RopeJointExample />
};

export const App = () => {
Expand Down Expand Up @@ -149,7 +152,6 @@ export const App = () => {
interpolate={interpolate}
debug={debug}
timeStep={1 / 60}
// erp={0.2}
>
<directionalLight
castShadow
Expand Down
9 changes: 1 addition & 8 deletions demo/src/examples/cradle/CradleExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import {
RapierRigidBody,
RigidBody,
RigidBodyOptions,
useRapier,
useSphericalJoint
} from "@react-three/rapier";
import { useEffect, useRef } from "react";
import { useRef } from "react";
import { Demo } from "../../App";

const Rod = (props: RigidBodyOptions) => {
Expand All @@ -20,12 +19,6 @@ const Rod = (props: RigidBodyOptions) => {
[0, 0, 0]
]);

const { world } = useRapier();

useEffect(() => {
world.maxStabilizationIterations = 10;
}, []);

return (
<group>
<RigidBody ref={anchor} {...props} />
Expand Down
120 changes: 120 additions & 0 deletions demo/src/examples/rope-joint/RopeJointExample.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<RigidBody type="fixed" colliders="cuboid" position={[0, -1, 0]} {...props}>
<Box args={[20, 1, 20]}>
<meshStandardMaterial color="white" />
</Box>
</RigidBody>
);
};

const BoxRigidBody = (props: BoxRigidBodyProps) => {
return (
<RigidBody {...props}>
<Box castShadow receiveShadow>
<meshStandardMaterial color={props.color} />
</Box>
</RigidBody>
);
};

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(
<BoxRigidBody
key={`${i}-${j}`}
{...props}
density={2}
color={WALL_COLORS[i % 5]}
position={position}
/>
);
}
}

return (
<group name="wall" rotation-y={-0.7853982} position={[-1.8, 0, -1.8]}>
{wall.map((box, i) => box)}
</group>
);
};

const RopeJoint = ({
anchorPosition,
ballPosition,
ropeLength
}: RopeJointProps) => {
const anchor = useRef<RapierRigidBody>(null);
const ball = useRef<RapierRigidBody>(null);

useRopeJoint(anchor, ball, [[0, 0, 0], [0, 0, 0], ropeLength]);

return (
<group>
{/* Anchor */}
<RigidBody ref={anchor} position={anchorPosition} />

{/* Wrecking Ball */}
<RigidBody
position={ballPosition}
ref={ball}
restitution={1.2}
density={30}
colliders={false}
>
<Sphere args={[2]} receiveShadow castShadow>
<meshStandardMaterial metalness={1} roughness={0.3} />
</Sphere>

<BallCollider args={[2]} />
</RigidBody>
</group>
);
};

export const RopeJointExample: Demo = () => {
return (
<group position={[0, 0, 0]} scale={3}>
<Floor />
<BoxWall height={10} width={6} />
<RopeJoint
ropeLength={35}
anchorPosition={[0, 15, 0]}
ballPosition={[-8, 15, 8]}
/>
</group>
);
};
113 changes: 113 additions & 0 deletions demo/src/examples/spring/SpringExample.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<RigidBody {...props} ccd canSleep={false}>
<Box castShadow receiveShadow>
<meshStandardMaterial color={color} />
</Box>
</RigidBody>
);
};

const BallSpring = forwardRef<RapierRigidBody, BallSpringProps>(
(props, floorRef) => {
const floor = useForwardedRef(floorRef);
const ball = useRef<RapierRigidBody>(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 (
<RigidBody
key={`spring-${props.jointNum}`}
{...props}
ref={ball}
ccd
name={`spring-${props.jointNum}`}
position={ballPos}
colliders={false}
canSleep={false}
>
<Sphere args={[0.5]} castShadow receiveShadow>
<meshStandardMaterial color="#E09F3E" />
</Sphere>
<BallCollider args={[0.5]} />
</RigidBody>
);
}
);

export const SpringExample: Demo = () => {
const floor = useRef<RapierRigidBody>(null);

const vectorArr = useMemo(() => {
return Array.from({ length: 30 }).map((_, i) => {
return vectorArrayToVector3([-20 + 1.5 * (i + 1), 7.5, -30]);
});
}, []);

return (
<>
<RigidBody ref={floor} position={[0, 0, 0]} type="fixed" />

{vectorArr.map((_, i) => (
<group key={`box-ball-${i}`}>
<BallSpring
key={`ball-${i}`}
ref={floor}
position={vectorArr[i]}
mass={1}
jointNum={i}
total={30}
/>
<BoxRigidBody
key={`box-${i}`}
color={COLORS_ARR[i % 5]}
position={[vectorArr[i].x, vectorArr[i].y + 3, vectorArr[i].z]}
colliders="cuboid"
density={100}
/>
</group>
))}
</>
);
};
2 changes: 1 addition & 1 deletion packages/react-three-rapier/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
Loading
Loading