diff --git a/.changeset/moody-radios-visit.md b/.changeset/moody-radios-visit.md new file mode 100644 index 00000000..73790eed --- /dev/null +++ b/.changeset/moody-radios-visit.md @@ -0,0 +1,5 @@ +--- +"@react-three/rapier": patch +--- + +Fix issue with `canSleep` missing from RigidBodyDesc diff --git a/.changeset/olive-lemons-smoke.md b/.changeset/olive-lemons-smoke.md new file mode 100644 index 00000000..d0e92db9 --- /dev/null +++ b/.changeset/olive-lemons-smoke.md @@ -0,0 +1,5 @@ +--- +"@react-three/rapier": patch +--- + +Enable dynamic changing of RigidBody `type` diff --git a/demo/package.json b/demo/package.json index 9fe736bc..ae96b898 100644 --- a/demo/package.json +++ b/demo/package.json @@ -9,15 +9,16 @@ "preview": "vite preview" }, "dependencies": { - "@react-three/drei": "^9.34.1", - "@react-three/fiber": "^8.8.9", + "@react-three/csg": "1.1.5", + "@react-three/drei": "9.45.0", + "@react-three/fiber": "8.9.1", "@react-three/rapier": "*", - "leva": "^0.9.34", - "r3f-perf": "^6.4.2", - "react": "^18.1.0", - "react-dom": "^18.1.0", - "react-router-dom": "^6.3.0", - "three": "^0.139.2" + "leva": "0.9.34", + "r3f-perf": "6.4.2", + "react": "18.2.0", + "react-dom": "18.2.0", + "react-router-dom": "6.4.3", + "three": "0.146.0" }, "devDependencies": { "@vitejs/plugin-react": "^2.1.0", diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 4c093c21..821c6a0d 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -12,32 +12,35 @@ import { useEffect } from "react"; import { NavLink, NavLinkProps, Route, Routes } from "react-router-dom"; -import { AllCollidersExample } from "./all-colliders/AllCollidersExample"; -import { AllShapesExample } from "./all-shapes/AllShapesExample"; -import { ApiUsage } from "./api-usage/ApiUsageExample"; -import { AttractorExample } from "./attractors/AttractorsExample"; -import { Car } from "./car/CarExample"; -import { Cluster } from "./cluster/ClusterExample"; -import { Colliders } from "./colliders/CollidersExample"; -import { CollisionEventsExample } from "./collision-events/CollisionEventsExample"; -import { ComponentsExample } from "./components/ComponentsExample"; -import { ContactForceEventsExample } from "./contact-force-events/ContactForceEventsExample"; -import { CradleExample } from "./cradle/CradleExample"; -import { Damping } from "./damping/DampingExample"; -import { InstancedMeshes } from "./instanced-meshes/InstancedMeshesExample"; -import { InstancedMeshesCompound } from "./instances-meshes-compound/InstancedMeshesCompoundExample"; -import { Joints } from "./joints/JointsExample"; -import { Kinematics } from "./kinematics/KinematicsExample"; -import { ManualStepExample } from "./manual-step/ManualStepExamples"; -import { MeshColliderTest } from "./mesh-collider-test/MeshColliderExample"; -import { SensorsExample } from "./sensors/SensorsExample"; -import Shapes from "./shapes/ShapesExample"; -import { Transforms } from "./transforms/TransformsExample"; -import { LockedTransformsExample } from "./locked-transforms/LockedTransformsExample"; +import { AllCollidersExample } from "./examples/all-colliders/AllCollidersExample"; +import { AllShapesExample } from "./examples/all-shapes/AllShapesExample"; +import { ApiUsage } from "./examples/api-usage/ApiUsageExample"; +import { AttractorExample } from "./examples/attractors/AttractorsExample"; +import { Car } from "./examples/car/CarExample"; +import { Cluster } from "./examples/cluster/ClusterExample"; +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 { CradleExample } from "./examples/cradle/CradleExample"; +import { Damping } from "./examples/damping/DampingExample"; +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 { 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"; const demoContext = createContext<{ setDebug?(f: boolean): void; setPaused?(f: boolean): void; + setCameraEnabled?(f: boolean): void; }>({}); export const useDemo = () => useContext(demoContext); @@ -105,7 +108,9 @@ const routes: Record = { "contact-force-events": , sensors: , "manual-step": , - "locked-transforms": + "locked-transforms": , + performance: , + "dynamic-type-changes": }; export const App = () => { @@ -113,6 +118,7 @@ export const App = () => { const [perf, setPerf] = useState(false); const [paused, setPaused] = useState(false); const [physicsKey, setPhysicsKey] = useState(0); + const [cameraEnabled, setCameraEnabled] = useState(true); const updatePhysicsKey = () => { setPhysicsKey((current) => current + 1); @@ -142,12 +148,14 @@ export const App = () => { shadow-bias={-0.0001} /> - + + @@ -179,7 +187,7 @@ export const App = () => { > {Object.keys(routes).map((key) => ( - {key.replace(/-/g, " ") || "Shapes"} + {key.replace(/-/g, " ") || "Plinko"} ))} diff --git a/demo/src/all-colliders/AllCollidersExample.tsx b/demo/src/examples/all-colliders/AllCollidersExample.tsx similarity index 100% rename from demo/src/all-colliders/AllCollidersExample.tsx rename to demo/src/examples/all-colliders/AllCollidersExample.tsx diff --git a/demo/src/all-shapes/AllShapesExample.tsx b/demo/src/examples/all-shapes/AllShapesExample.tsx similarity index 93% rename from demo/src/all-shapes/AllShapesExample.tsx rename to demo/src/examples/all-shapes/AllShapesExample.tsx index 71fd2696..ea7772d3 100644 --- a/demo/src/all-shapes/AllShapesExample.tsx +++ b/demo/src/examples/all-shapes/AllShapesExample.tsx @@ -11,12 +11,14 @@ import { TrimeshCollider } from "@react-three/rapier"; -import { Demo } from "../App"; +import { Demo } from "../../App"; import { Mesh } from "three"; export const useSuzanne = () => { // @ts-ignore - return useGLTF(new URL("./susanne.glb", import.meta.url).toString()) as { + return useGLTF( + new URL("../../models/susanne.glb", import.meta.url).toString() + ) as { nodes: { Suzanne: Mesh; }; @@ -25,7 +27,9 @@ export const useSuzanne = () => { const useOffsetTorus = () => { // @ts-ignore - return useGLTF(new URL("./offset-torus.glb", import.meta.url).toString()) as { + return useGLTF( + new URL("../../models/offset-torus.glb", import.meta.url).toString() + ) as { nodes: { Torus: Mesh; }; diff --git a/demo/src/api-usage/ApiUsageExample.tsx b/demo/src/examples/api-usage/ApiUsageExample.tsx similarity index 96% rename from demo/src/api-usage/ApiUsageExample.tsx rename to demo/src/examples/api-usage/ApiUsageExample.tsx index 6562f4c7..8b75fc8e 100644 --- a/demo/src/api-usage/ApiUsageExample.tsx +++ b/demo/src/examples/api-usage/ApiUsageExample.tsx @@ -1,7 +1,7 @@ import { Torus } from "@react-three/drei"; import { RigidBody, RigidBodyApi } from "@react-three/rapier"; import { useEffect, useRef } from "react"; -import { Demo } from "../App"; +import { Demo } from "../../App"; export const ApiUsage: Demo = () => { const torus = useRef(null); diff --git a/demo/src/attractors/AttractorsExample.tsx b/demo/src/examples/attractors/AttractorsExample.tsx similarity index 97% rename from demo/src/attractors/AttractorsExample.tsx rename to demo/src/examples/attractors/AttractorsExample.tsx index f0c46461..9324b0c8 100644 --- a/demo/src/attractors/AttractorsExample.tsx +++ b/demo/src/examples/attractors/AttractorsExample.tsx @@ -8,7 +8,7 @@ import { RigidBody } from "@react-three/rapier"; import { createRef, useEffect, useRef } from "react"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const BALLS = 100; diff --git a/demo/src/car/CarExample.tsx b/demo/src/examples/car/CarExample.tsx similarity index 98% rename from demo/src/car/CarExample.tsx rename to demo/src/examples/car/CarExample.tsx index 2b65ea12..e33500b3 100644 --- a/demo/src/car/CarExample.tsx +++ b/demo/src/examples/car/CarExample.tsx @@ -9,7 +9,7 @@ import { Vector3Array } from "@react-three/rapier"; import { createRef, useRef } from "react"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const WheelJoint = ({ body, diff --git a/demo/src/cluster/ClusterExample.tsx b/demo/src/examples/cluster/ClusterExample.tsx similarity index 97% rename from demo/src/cluster/ClusterExample.tsx rename to demo/src/examples/cluster/ClusterExample.tsx index 673f744d..4c0a1ca4 100644 --- a/demo/src/cluster/ClusterExample.tsx +++ b/demo/src/examples/cluster/ClusterExample.tsx @@ -6,7 +6,7 @@ import { useRapier } from "@react-three/rapier"; import { createRef, useEffect, useRef } from "react"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const BALLS = 1000; diff --git a/demo/src/colliders/CollidersExample.tsx b/demo/src/examples/colliders/CollidersExample.tsx similarity index 97% rename from demo/src/colliders/CollidersExample.tsx rename to demo/src/examples/colliders/CollidersExample.tsx index f6426a62..e640eab9 100644 --- a/demo/src/colliders/CollidersExample.tsx +++ b/demo/src/examples/colliders/CollidersExample.tsx @@ -8,7 +8,7 @@ import { } from "@react-three/rapier"; import { useRef } from "react"; import { Euler, Vector3 } from "three"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const Ball = () => { const ball = useRef(null); diff --git a/demo/src/collision-events/CollisionEventsExample.tsx b/demo/src/examples/collision-events/CollisionEventsExample.tsx similarity index 100% rename from demo/src/collision-events/CollisionEventsExample.tsx rename to demo/src/examples/collision-events/CollisionEventsExample.tsx diff --git a/demo/src/components/ComponentsExample.tsx b/demo/src/examples/components/ComponentsExample.tsx similarity index 93% rename from demo/src/components/ComponentsExample.tsx rename to demo/src/examples/components/ComponentsExample.tsx index 58cba448..1003875d 100644 --- a/demo/src/components/ComponentsExample.tsx +++ b/demo/src/examples/components/ComponentsExample.tsx @@ -4,12 +4,12 @@ import { Box, Clone, Sphere, useGLTF } from "@react-three/drei"; import { RigidBody, TrimeshCollider } from "@react-three/rapier"; import { GroupProps, Object3DNode, useFrame } from "@react-three/fiber"; import { Mesh } from "three"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const Map = () => { const { nodes } = useGLTF( // @ts-ignore - new URL("../map.glb", import.meta.url).toString() + new URL("../../models/map.glb", import.meta.url).toString() ) as unknown as { nodes: { map: Mesh } }; nodes.map.castShadow = true; @@ -32,7 +32,7 @@ const Map = () => { const Pear = (props: GroupProps) => { const { nodes } = useGLTF( - new URL("../shapes/objects.glb", import.meta.url).toString() + new URL("../../models/objects.glb", import.meta.url).toString() ) as unknown as { nodes: { pear: Mesh; diff --git a/demo/src/contact-force-events/ContactForceEventsExample.tsx b/demo/src/examples/contact-force-events/ContactForceEventsExample.tsx similarity index 98% rename from demo/src/contact-force-events/ContactForceEventsExample.tsx rename to demo/src/examples/contact-force-events/ContactForceEventsExample.tsx index 2b3c2ae5..b651eecf 100644 --- a/demo/src/contact-force-events/ContactForceEventsExample.tsx +++ b/demo/src/examples/contact-force-events/ContactForceEventsExample.tsx @@ -3,7 +3,7 @@ import { MeshPhysicalMaterialProps } from "@react-three/fiber"; import { RigidBody, RigidBodyApi, RigidBodyProps } from "@react-three/rapier"; import { useRef, useState } from "react"; import { Color } from "three"; -import { Demo } from "../App"; +import { Demo } from "../../App"; type BallProps = { onContactForce: RigidBodyProps["onContactForce"] }; const Ball = ({ onContactForce }: BallProps) => { diff --git a/demo/src/cradle/CradleExample.tsx b/demo/src/examples/cradle/CradleExample.tsx similarity index 97% rename from demo/src/cradle/CradleExample.tsx rename to demo/src/examples/cradle/CradleExample.tsx index 3e12735c..6218ad8d 100644 --- a/demo/src/cradle/CradleExample.tsx +++ b/demo/src/examples/cradle/CradleExample.tsx @@ -9,7 +9,7 @@ import { useSphericalJoint } from "@react-three/rapier"; import { useRef } from "react"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const Rod = (props: UseRigidBodyOptions) => { const anchor = useRef(null); diff --git a/demo/src/damping/DampingExample.tsx b/demo/src/examples/damping/DampingExample.tsx similarity index 97% rename from demo/src/damping/DampingExample.tsx rename to demo/src/examples/damping/DampingExample.tsx index 6d5087f7..2e5096bc 100644 --- a/demo/src/damping/DampingExample.tsx +++ b/demo/src/examples/damping/DampingExample.tsx @@ -1,7 +1,7 @@ import { Box, Sphere, useTexture } from "@react-three/drei"; import { RigidBody } from "@react-three/rapier"; import { RepeatWrapping } from "three"; -import { Demo } from "../App"; +import { Demo } from "../../App"; export const Damping: Demo = () => { const floor = useTexture(new URL("./white.png", import.meta.url).toString()); diff --git a/demo/src/damping/green.png b/demo/src/examples/damping/green.png similarity index 100% rename from demo/src/damping/green.png rename to demo/src/examples/damping/green.png diff --git a/demo/src/damping/red.png b/demo/src/examples/damping/red.png similarity index 100% rename from demo/src/damping/red.png rename to demo/src/examples/damping/red.png diff --git a/demo/src/damping/white.png b/demo/src/examples/damping/white.png similarity index 100% rename from demo/src/damping/white.png rename to demo/src/examples/damping/white.png diff --git a/demo/src/examples/dynamic-type-change/DynamicTypeChangeExample.tsx b/demo/src/examples/dynamic-type-change/DynamicTypeChangeExample.tsx new file mode 100644 index 00000000..ef8a35a4 --- /dev/null +++ b/demo/src/examples/dynamic-type-change/DynamicTypeChangeExample.tsx @@ -0,0 +1,96 @@ +import { Html } from "@react-three/drei"; +import { useFrame, useThree } from "@react-three/fiber"; +import { RigidBody, RigidBodyApi } from "@react-three/rapier"; +import { useEffect, useRef, useState } from "react"; +import { useDemo } from "../../App"; +import { useSuzanne } from "../all-shapes/AllShapesExample"; + +export const DynamicTypeChangeExample = () => { + const { setCameraEnabled } = useDemo(); + const monkee = useRef(null); + const [dragging, setDragging] = useState(false); + const [s] = useState<{ mouse: { x: number; y: number } | null }>({ + mouse: null + }); + + const { + nodes: { Suzanne } + } = useSuzanne(); + + const { mouse } = useThree(); + + useEffect(() => { + if (dragging) { + document.body.style.cursor = "grabbing"; + setCameraEnabled?.(false); + } else { + document.body.style.cursor = ""; + setCameraEnabled?.(true); + s.mouse = null; + } + }, [dragging]); + + useFrame(() => { + if (dragging) { + if (!s.mouse) { + s.mouse = { x: mouse.x, y: mouse.y }; + } else { + const { x, y } = monkee.current?.translation() || { x: 0, y: 0 }; + + monkee.current?.setTranslation({ + x: x + (mouse.x - s.mouse.x) * 10, + y: y + (mouse.y - s.mouse.y) * 10, + z: 0 + }); + + s.mouse = { x: mouse.x, y: mouse.y }; + } + } + }); + + useEffect(() => { + const handleMouseUp = () => { + setDragging(false); + }; + window.addEventListener("pointerup", handleMouseUp); + + return () => { + window.removeEventListener("pointerup", handleMouseUp); + }; + }, []); + + return ( + + + { + setDragging(true); + }} + onPointerOver={() => (document.body.style.cursor = "grab")} + onPointerOut={() => (document.body.style.cursor = "")} + > + + +
Drag me!
+
Type: {dragging ? "kinematicPosition" : "dynamic"}
+ +
+
+
+ ); +}; diff --git a/demo/src/instanced-meshes/InstancedMeshesExample.tsx b/demo/src/examples/instanced-meshes/InstancedMeshesExample.tsx similarity index 98% rename from demo/src/instanced-meshes/InstancedMeshesExample.tsx rename to demo/src/examples/instanced-meshes/InstancedMeshesExample.tsx index 9106359b..903f3105 100644 --- a/demo/src/instanced-meshes/InstancedMeshesExample.tsx +++ b/demo/src/examples/instanced-meshes/InstancedMeshesExample.tsx @@ -13,7 +13,7 @@ import { Vector3 } from "three"; import { useSuzanne } from "../all-shapes/AllShapesExample"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const COUNT = 300; diff --git a/demo/src/instances-meshes-compound/InstancedMeshesCompoundExample.tsx b/demo/src/examples/instances-meshes-compound/InstancedMeshesCompoundExample.tsx similarity index 98% rename from demo/src/instances-meshes-compound/InstancedMeshesCompoundExample.tsx rename to demo/src/examples/instances-meshes-compound/InstancedMeshesCompoundExample.tsx index f5caa076..3af06968 100644 --- a/demo/src/instances-meshes-compound/InstancedMeshesCompoundExample.tsx +++ b/demo/src/examples/instances-meshes-compound/InstancedMeshesCompoundExample.tsx @@ -8,7 +8,7 @@ import { } from "@react-three/rapier"; import { useEffect, useRef } from "react"; import { useSuzanne } from "../all-shapes/AllShapesExample"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const COUNT = 10; diff --git a/demo/src/joints/JointsExample.tsx b/demo/src/examples/joints/JointsExample.tsx similarity index 98% rename from demo/src/joints/JointsExample.tsx rename to demo/src/examples/joints/JointsExample.tsx index 42e38e55..4f4f0408 100644 --- a/demo/src/joints/JointsExample.tsx +++ b/demo/src/examples/joints/JointsExample.tsx @@ -10,7 +10,7 @@ import { } from "@react-three/rapier"; import { useImperativeHandle } from "react"; import { useFrame } from "@react-three/fiber"; -import { Demo } from "../App"; +import { Demo } from "../../App"; import { Quaternion } from "three"; const ShadowElement = forwardRef((_, ref) => ( diff --git a/demo/src/kinematics/KinematicsExample.tsx b/demo/src/examples/kinematics/KinematicsExample.tsx similarity index 98% rename from demo/src/kinematics/KinematicsExample.tsx rename to demo/src/examples/kinematics/KinematicsExample.tsx index fb9bd8d0..0c9f9f3f 100644 --- a/demo/src/kinematics/KinematicsExample.tsx +++ b/demo/src/examples/kinematics/KinematicsExample.tsx @@ -3,7 +3,7 @@ import { useFrame } from "@react-three/fiber"; import { RigidBody, RigidBodyApi } from "@react-three/rapier"; import { useEffect, useRef } from "react"; import { Euler, Quaternion } from "three"; -import { Demo } from "../App"; +import { Demo } from "../../App"; const Ball = () => { const ball = useRef(null); diff --git a/demo/src/locked-transforms/LockedTransformsExample.tsx b/demo/src/examples/locked-transforms/LockedTransformsExample.tsx similarity index 97% rename from demo/src/locked-transforms/LockedTransformsExample.tsx rename to demo/src/examples/locked-transforms/LockedTransformsExample.tsx index 65eb68bd..04a73b93 100644 --- a/demo/src/locked-transforms/LockedTransformsExample.tsx +++ b/demo/src/examples/locked-transforms/LockedTransformsExample.tsx @@ -3,7 +3,7 @@ import { useFrame } from "@react-three/fiber"; import { RigidBody, RigidBodyApi } from "@react-three/rapier"; import { useControls } from "leva"; import { useEffect, useRef } from "react"; -import { Demo } from "../App"; +import { Demo } from "../../App"; export const LockedTransformsExample: Demo = () => { return ( diff --git a/demo/src/manual-step/ManualStepExamples.tsx b/demo/src/examples/manual-step/ManualStepExamples.tsx similarity index 93% rename from demo/src/manual-step/ManualStepExamples.tsx rename to demo/src/examples/manual-step/ManualStepExamples.tsx index e1394715..79ddd94a 100644 --- a/demo/src/manual-step/ManualStepExamples.tsx +++ b/demo/src/examples/manual-step/ManualStepExamples.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from "react"; import { RigidBody, useRapier } from "@react-three/rapier"; import { Box } from "@react-three/drei"; import { useControls, button } from "leva"; -import { useDemo } from "../App"; +import { useDemo } from "../../App"; export const ManualStepExample = () => { const { setPaused } = useDemo(); diff --git a/demo/src/mesh-collider-test/MeshColliderExample.tsx b/demo/src/examples/mesh-collider-test/MeshColliderExample.tsx similarity index 98% rename from demo/src/mesh-collider-test/MeshColliderExample.tsx rename to demo/src/examples/mesh-collider-test/MeshColliderExample.tsx index 96ced54f..2be94ba4 100644 --- a/demo/src/mesh-collider-test/MeshColliderExample.tsx +++ b/demo/src/examples/mesh-collider-test/MeshColliderExample.tsx @@ -1,7 +1,7 @@ import { Box, Sphere, Torus } from "@react-three/drei"; import { useFrame } from "@react-three/fiber"; import { MeshCollider, RigidBody } from "@react-three/rapier"; -import { Demo } from "../App"; +import { Demo } from "../../App"; export const MeshColliderTest: Demo = () => { return ( diff --git a/demo/src/examples/performance/PeformanceExample.tsx b/demo/src/examples/performance/PeformanceExample.tsx new file mode 100644 index 00000000..624848dd --- /dev/null +++ b/demo/src/examples/performance/PeformanceExample.tsx @@ -0,0 +1,123 @@ +import { useGLTF } from "@react-three/drei"; +import { GroupProps, useFrame } from "@react-three/fiber"; +import { RigidBody, RigidBodyProps } from "@react-three/rapier"; +import { RigidBodyApi } from "@react-three/rapier/dist/declarations/src/types"; +import { ReactNode, useEffect, useRef, useState } from "react"; +import { Mesh } from "three"; +import { GLTF } from "three-stdlib"; +import { useSuzanne } from "../all-shapes/AllShapesExample"; + +const useBendy = () => { + return useGLTF( + new URL("../../models/bendy.glb", import.meta.url).toString() + ) as unknown as GLTF & { + nodes: { + BezierCurve: Mesh; + }; + }; +}; + +const Monkae = ({ + onDead, + ...props +}: RigidBodyProps & { + onDead: (pos: { x: number; y: number; z: number }) => void; +}) => { + const { + nodes: { Suzanne } + } = useSuzanne(); + + const monmon = useRef(null); + + useFrame(() => { + if (monmon.current && monmon.current.translation().y < -10) { + onDead(monmon.current.translation()); + } + }); + + return ( + + + + + + ); +}; + +const Emitter = (props: GroupProps & { time?: number }) => { + const [monkaes, setMonkaes] = useState< + { key: number; position: [number, number, number] }[] + >(() => []); + + const removeMonkae = (id: number) => { + setMonkaes((monkaes) => monkaes.filter((monkae) => monkae.key !== id)); + }; + + useEffect(() => { + const interval = setInterval(() => { + setMonkaes((monkaes) => [ + ...monkaes, + { + key: Math.random(), + position: [ + Math.random() * 10 - 5, + Math.random(), + Math.random() * 10 - 5 + ] + } + ]); + }, props.time || 1000); + + return () => clearInterval(interval); + }, []); + + return ( + + {monkaes.map((m, i) => ( + removeMonkae(m.key)} + /> + ))} + + ); +}; + +const Bendy = (props: GroupProps) => { + const { nodes } = useBendy(); + + return ( + + + + + + + + ); +}; + +export const PerformanceExample = () => { + return ( + + + + + + + + ); +}; diff --git a/demo/src/shapes/Plinko.tsx b/demo/src/examples/plinko/Plinko.tsx similarity index 96% rename from demo/src/shapes/Plinko.tsx rename to demo/src/examples/plinko/Plinko.tsx index 5825fa15..8933f3c6 100644 --- a/demo/src/shapes/Plinko.tsx +++ b/demo/src/examples/plinko/Plinko.tsx @@ -27,7 +27,7 @@ export default function Plinko({ ...props }: JSX.IntrinsicElements["group"]) { const { nodes, materials } = useGLTF( // @ts-ignore - new URL("plinko.glb", import.meta.url).toString() + new URL("../../models/plinko.glb", import.meta.url).toString() ) as unknown as GLTFResult; return ( diff --git a/demo/src/shapes/ShapesExample.tsx b/demo/src/examples/plinko/ShapesExample.tsx similarity index 89% rename from demo/src/shapes/ShapesExample.tsx rename to demo/src/examples/plinko/ShapesExample.tsx index a9e756ee..0a9dcd78 100644 --- a/demo/src/shapes/ShapesExample.tsx +++ b/demo/src/examples/plinko/ShapesExample.tsx @@ -1,24 +1,9 @@ -import { - Dispatch, - FC, - memo, - ReactNode, - useEffect, - useRef, - useState -} from "react"; - -import { Box, Html, Plane, Sphere, useGLTF } from "@react-three/drei"; +import React, { FC, memo, useEffect, useRef, useState } from "react"; + +import { Box, Html, Sphere, useGLTF } from "@react-three/drei"; import { CylinderCollider, RigidBody, RigidBodyApi } from "@react-three/rapier"; import Plinko from "./Plinko"; -import { - BufferGeometry, - Material, - Mesh, - MeshPhysicalMaterial, - Vector3 -} from "three"; -import { useDemo } from "../App"; +import { Mesh, Vector3 } from "three"; import { useControls, button } from "leva"; const colors = ["red", "green", "blue", "yellow", "orange", "purple"]; @@ -114,11 +99,13 @@ const RigidBall = memo(() => { ); }); -useGLTF.preload(new URL("objects.glb", import.meta.url).toString()); +useGLTF.preload( + new URL("../../models/objects.glb", import.meta.url).toString() +); const HullPear = memo(() => { const { nodes } = useGLTF( - new URL("objects.glb", import.meta.url).toString() + new URL("../../models/objects.glb", import.meta.url).toString() ) as unknown as { nodes: { pear: Mesh; @@ -140,7 +127,7 @@ const HullPear = memo(() => { const MeshBoat = memo(() => { const { nodes } = useGLTF( - new URL("objects.glb", import.meta.url).toString() + new URL("../../models/objects.glb", import.meta.url).toString() ) as unknown as { nodes: { boat: Mesh; diff --git a/demo/src/sensors/SensorsExample.tsx b/demo/src/examples/sensors/SensorsExample.tsx similarity index 100% rename from demo/src/sensors/SensorsExample.tsx rename to demo/src/examples/sensors/SensorsExample.tsx diff --git a/demo/src/transforms/TransformsExample.tsx b/demo/src/examples/transforms/TransformsExample.tsx similarity index 98% rename from demo/src/transforms/TransformsExample.tsx rename to demo/src/examples/transforms/TransformsExample.tsx index a097756a..7784c365 100644 --- a/demo/src/transforms/TransformsExample.tsx +++ b/demo/src/examples/transforms/TransformsExample.tsx @@ -7,7 +7,7 @@ import { } from "@react-three/rapier"; import { useEffect, useRef } from "react"; import { Group } from "three"; -import { Demo } from "../App"; +import { Demo } from "../../App"; export const Transforms: Demo = () => { const group = useRef(null); diff --git a/demo/src/models/bendy.glb b/demo/src/models/bendy.glb new file mode 100644 index 00000000..cbf07d83 Binary files /dev/null and b/demo/src/models/bendy.glb differ diff --git a/demo/src/map.glb b/demo/src/models/map.glb similarity index 100% rename from demo/src/map.glb rename to demo/src/models/map.glb diff --git a/demo/src/shapes/objects.glb b/demo/src/models/objects.glb similarity index 100% rename from demo/src/shapes/objects.glb rename to demo/src/models/objects.glb diff --git a/demo/src/all-shapes/offset-torus.glb b/demo/src/models/offset-torus.glb similarity index 100% rename from demo/src/all-shapes/offset-torus.glb rename to demo/src/models/offset-torus.glb diff --git a/demo/src/shapes/plinko.glb b/demo/src/models/plinko.glb similarity index 100% rename from demo/src/shapes/plinko.glb rename to demo/src/models/plinko.glb diff --git a/demo/src/all-shapes/susanne.glb b/demo/src/models/susanne.glb similarity index 100% rename from demo/src/all-shapes/susanne.glb rename to demo/src/models/susanne.glb diff --git a/packages/react-three-rapier/package.json b/packages/react-three-rapier/package.json index cd609c7a..376717c3 100644 --- a/packages/react-three-rapier/package.json +++ b/packages/react-three-rapier/package.json @@ -12,17 +12,17 @@ "ts": "tsc -w" }, "devDependencies": { - "@react-three/drei": "^9.34.1", - "@react-three/fiber": "^8.8.9", + "@react-three/drei": "9.45.0", + "@react-three/fiber": "8.9.1", "@react-three/test-renderer": "^8.0.17", "@types/react-dom": "^18.0.2", "@types/three": "^0.139.0", "@vitejs/plugin-react": "^2.1.0", "@vitest/ui": "^0.25.2", "happy-dom": "^7.5.5", - "react": "^18.1.0", - "react-dom": "^18.1.0", - "three": "^0.139.2", + "react": "18.2.0", + "react-dom": "18.2.0", + "three": "0.146.0", "vitest": "^0.25.2" }, "peerDependencies": { diff --git a/packages/react-three-rapier/src/utils-rigidbody.ts b/packages/react-three-rapier/src/utils-rigidbody.ts index ed31b8e9..74739bce 100644 --- a/packages/react-three-rapier/src/utils-rigidbody.ts +++ b/packages/react-three-rapier/src/utils-rigidbody.ts @@ -17,6 +17,9 @@ export const rigidBodyDescFromOptions = (options: RigidBodyProps) => { const desc = new RigidBodyDesc(type); + // Apply immutable options + desc.canSleep = options?.canSleep || true; + return desc; }; @@ -60,7 +63,7 @@ type ImmutableRigidBodyOptions = (keyof RigidBodyProps)[]; export const immutableRigidBodyOptions: ImmutableRigidBodyOptions = [ "args", "colliders", - "type" + "canSleep" ]; type MutableRigidBodyOptions = { @@ -101,6 +104,9 @@ const mutableRigidBodyOptions: MutableRigidBodyOptions = { userData: (rb: RigidBody, value: { [key: string]: any }) => { rb.userData = value; }, + type(rb, value) { + rb.setBodyType(rigidBodyTypeFromString(value)); + }, position: () => {}, rotation: () => {}, quaternion: () => {}, diff --git a/yarn.lock b/yarn.lock index 1ebf20fc..0ef79db0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1836,10 +1836,18 @@ resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.5.5.tgz#c8e94f1b9232ca7cb9d860ea67762ec401b1de14" integrity sha512-7I/qY8H7Enwasxr4jU6WmtNK+RZ4Z/XvSlDvjXFVe7ii1x0MoSlkw6pD7xuac8qrHQRm9BTcbZNyeeKApYsvCg== -"@react-three/drei@^9.34.1": - version "9.34.2" - resolved "https://registry.yarnpkg.com/@react-three/drei/-/drei-9.34.2.tgz#2bd6f6220a868bf871161af318516daffd4bc9a6" - integrity sha512-ez3hwTQJRxz14cktWthcL7rlEd7PpYhDlHPTa8y+MQao2EOrvNRc1gnhp+nIUDCinXpmvsOMBeHwiX/+KGfoiw== +"@react-three/csg@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@react-three/csg/-/csg-1.1.5.tgz#9725973b9a6b39e8e2a685f8a200928798d1abc2" + integrity sha512-b/xejsRHPjwDtd44X8VtoLkXC+Vc/PRt/SqA5dSYocn3efFZkk0CZCubDhAzR0rj+Ydbqr3AXVPWPo6YLqRIHw== + dependencies: + react-merge-refs "^1.1.0" + three-bvh-csg "^0.0.2" + +"@react-three/drei@9.45.0": + version "9.45.0" + resolved "https://registry.yarnpkg.com/@react-three/drei/-/drei-9.45.0.tgz#0f99fab9ecceb7184908aee3deee47ff40799c19" + integrity sha512-/zvV9hOb+jJeLR9tCZfxaLxcGMDVsKZ0WcSKtRYv932K8Ql2qd/2JGLOal0/oWorI77mzyhvvP254ILJr1HJYQ== dependencies: "@babel/runtime" "^7.11.2" "@react-spring/three" "^9.3.1" @@ -1855,19 +1863,19 @@ stats.js "^0.17.0" suspend-react "^0.0.8" three-mesh-bvh "^0.5.15" - three-stdlib "2.17.0" + three-stdlib "^2.18.1" troika-three-text "^0.46.4" utility-types "^3.10.0" zustand "^3.5.13" -"@react-three/fiber@^8.8.9": - version "8.8.9" - resolved "https://registry.yarnpkg.com/@react-three/fiber/-/fiber-8.8.9.tgz#365219cbad66f99589fe8f87f81eeeb278efea70" - integrity sha512-TGeDm6EieaQ/ckRPC0rbG0ntHjWO7xp7eLRh4ZFqQ5BzCqIO+mA3QXLzAuVItL1Y32OuBdXC28iqVHWOw2AWCw== +"@react-three/fiber@8.9.1": + version "8.9.1" + resolved "https://registry.yarnpkg.com/@react-three/fiber/-/fiber-8.9.1.tgz#54e278148ae1c301a4b516936bfce0d9240a7292" + integrity sha512-xRMO9RGp0DkxSFu5BmmkjCxJ4r0dEpLobtxXdZwI0h2rZZaCnkPM5zThRN8xaZNbZhzRSVICeNOFaZltr9xFyQ== dependencies: "@babel/runtime" "^7.17.8" "@types/react-reconciler" "^0.26.7" - its-fine "^1.0.4" + its-fine "^1.0.6" react-reconciler "^0.27.0" react-use-measure "^2.1.1" scheduler "^0.21.0" @@ -1879,10 +1887,10 @@ resolved "https://registry.yarnpkg.com/@react-three/test-renderer/-/test-renderer-8.0.17.tgz#1649ed3b5cc3ffb982e96d54765b64b1b7b00f33" integrity sha512-QyztaVpEkOOo7F4eJ2aL37WgID5nkVMQxdZcDPPng4eAdgicxHvv9dCPEVPeOWz4ORHG54nDm5rHh1N0TuFRfw== -"@remix-run/router@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.0.2.tgz#1c17eadb2fa77f80a796ad5ea9bf108e6993ef06" - integrity sha512-GRSOFhJzjGN+d4sKHTMSvNeUPoZiDHWmRnXfzaxrqe7dE/Nzlc8BiMSJdLDESZlndM7jIUrZ/F4yWqVYlI0rwQ== +"@remix-run/router@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.0.3.tgz#953b88c20ea00d0eddaffdc1b115c08474aa295d" + integrity sha512-ceuyTSs7PZ/tQqi19YZNBc5X7kj1f8p+4DIyrcIYFY9h+hd1OKm4RqtiWldR9eGEvIiJfsqwM4BsuCtRIuEw6Q== "@rollup/plugin-alias@^3.1.1": version "3.1.9" @@ -4545,10 +4553,10 @@ issue-regex@^3.1.0: resolved "https://registry.yarnpkg.com/issue-regex/-/issue-regex-3.1.0.tgz#0671f094d6449c5b712fac3c9562aecb727d709e" integrity sha512-0RHjbtw9QXeSYnIEY5Yrp2QZrdtz21xBDV9C/GIlY2POmgoS6a7qjkYS5siRKXScnuAj5/SPv1C3YForNCHTJA== -its-fine@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/its-fine/-/its-fine-1.0.5.tgz#dbd8130e021aafe030ca5001085c27ff2a057ab3" - integrity sha512-JVqIHuUGRF4mBJWV/o9CS86wU57oWAX+mE2iokFpZ+B1R1tcfRvLZXVFd9tWJgY7gfhBURYyXJs7LcoJl/Af+Q== +its-fine@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/its-fine/-/its-fine-1.0.6.tgz#087b14d71137816dab676d8b57c35a6cd5d2b021" + integrity sha512-VZJZPwVT2kxe5KQv+TxCjojfLiUIut8zXDNLTxcM7gJ/xQ/bSPk5M0neZ+j3myy45KKkltY1mm1jyJgx3Fxsdg== dependencies: "@types/react-reconciler" "^0.28.0" @@ -4666,7 +4674,7 @@ latest-version@^5.1.0: dependencies: package-json "^6.3.0" -leva@^0.9.34: +leva@0.9.34: version "0.9.34" resolved "https://registry.yarnpkg.com/leva/-/leva-0.9.34.tgz#24f2d717f620de959e9ff27b0118d8d94d4e730b" integrity sha512-hQmWAakOCuBXYIenJ7RaNIei5enDwHNNb6Gz5BUU3mZk+ElECdbvNJbmcMfkFAJslJw33MXRabt7OKIzItLLWw== @@ -5687,10 +5695,10 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -r3f-perf@^6.4.2: - version "6.5.0" - resolved "https://registry.yarnpkg.com/r3f-perf/-/r3f-perf-6.5.0.tgz#9ed6ac3cf45d0f2d514a97f02fa40f8a9813e0b5" - integrity sha512-6hT9V5ihOOv2g/zyOpMGviiqxW9SKFX6AMfcAMnFz3S74M5WNjfAWx4D54Cd89O+5hrcj5Pa69/piGZEKmWPeg== +r3f-perf@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/r3f-perf/-/r3f-perf-6.4.2.tgz#bc04d4f0bb6a318bee2fce21382a6ad5f8f1b43b" + integrity sha512-DUsNOZhEiqpnyceVD/oCB65nwzS/jN43AAEQWxAt/ijZWKuQLa8Hi/uDHGCdUfZ/mfFVFRmvuPsFJrZZPV6aEg== dependencies: "@radix-ui/react-icons" "^1.0.3" "@stitches/react" "^1.2.6" @@ -5718,7 +5726,7 @@ react-composer@^5.0.3: dependencies: prop-types "^15.6.0" -react-dom@^18.1.0: +react-dom@18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== @@ -5758,20 +5766,20 @@ react-refresh@^0.14.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== -react-router-dom@^6.3.0: - version "6.4.2" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.4.2.tgz#115b37d501d6d8ac870683694978c51c43e6c0d2" - integrity sha512-yM1kjoTkpfjgczPrcyWrp+OuQMyB1WleICiiGfstnQYo/S8hPEEnVjr/RdmlH6yKK4Tnj1UGXFSa7uwAtmDoLQ== +react-router-dom@6.4.3: + version "6.4.3" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.4.3.tgz#70093b5f65f85f1df9e5d4182eb7ff3a08299275" + integrity sha512-MiaYQU8CwVCaOfJdYvt84KQNjT78VF0TJrA17SIQgNHRvLnXDJO6qsFqq8F/zzB1BWZjCFIrQpu4QxcshitziQ== dependencies: - "@remix-run/router" "1.0.2" - react-router "6.4.2" + "@remix-run/router" "1.0.3" + react-router "6.4.3" -react-router@6.4.2: - version "6.4.2" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.4.2.tgz#300628ee9ed81b8ef1597b5cb98b474efe9779b8" - integrity sha512-Rb0BAX9KHhVzT1OKhMvCDMw776aTYM0DtkxqUBP8dNBom3mPXlfNs76JNGK8wKJ1IZEY1+WGj+cvZxHVk/GiKw== +react-router@6.4.3: + version "6.4.3" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.4.3.tgz#9ed3ee4d6e95889e9b075a5d63e29acc7def0d49" + integrity sha512-BT6DoGn6aV1FVP5yfODMOiieakp3z46P1Fk0RNzJMACzE7C339sFuHebfvWtnB4pzBvXXkHP2vscJzWRuUjTtA== dependencies: - "@remix-run/router" "1.0.2" + "@remix-run/router" "1.0.3" react-use-measure@^2.1.1: version "2.1.1" @@ -5780,7 +5788,7 @@ react-use-measure@^2.1.1: dependencies: debounce "^1.2.1" -react@^18.1.0: +react@18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== @@ -6544,12 +6552,17 @@ then-request@^6.0.0: promise "^8.0.0" qs "^6.4.0" +three-bvh-csg@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/three-bvh-csg/-/three-bvh-csg-0.0.2.tgz#1e7c9d68bf02e37d3a520f6d9ada5b8d9771ccfa" + integrity sha512-5T1BP1iRjvrG0YIt6G5GwQNgTGHKHrDfRajG10qIVrfjk2QXcwu6rfmSOm+TW7IZQbTcpiBp1/wePyiaYmdlIw== + three-mesh-bvh@^0.5.15: version "0.5.16" resolved "https://registry.yarnpkg.com/three-mesh-bvh/-/three-mesh-bvh-0.5.16.tgz#ed8518355fb70d7da6a5537558ba43f76a56b067" integrity sha512-kN3QGKJNiQQcuiOsjVIkjtPnV3PJa+0Orih2E52afa+kQfs3zfoYt6Kxn6b6RNiAfaQ+7ckwPK0mTVFVl2F2LA== -three-stdlib@2.17.0, three-stdlib@^2.15.0: +three-stdlib@^2.15.0: version "2.17.0" resolved "https://registry.yarnpkg.com/three-stdlib/-/three-stdlib-2.17.0.tgz#5915b110ec6dbf07e0e653bd59889293c7b93407" integrity sha512-m19X4+ajh+2EJIVcjB288LgbqTli5b8kFahJlg9oNCBfaL8geCgEoM4OUirgV0Ez6Lr58N1MPBR6LjJt7ALfKQ== @@ -6566,10 +6579,27 @@ three-stdlib@2.17.0, three-stdlib@^2.15.0: potpack "^1.0.1" zstddec "^0.0.2" -three@^0.139.2: - version "0.139.2" - resolved "https://registry.yarnpkg.com/three/-/three-0.139.2.tgz#b110799a15736df673b9293e31653a4ac73648dd" - integrity sha512-gV7q7QY8rogu7HLFZR9cWnOQAUedUhu2WXAnpr2kdXZP9YDKsG/0ychwQvWkZN5PlNw9mv5MoCTin6zNTXoONg== +three-stdlib@^2.18.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/three-stdlib/-/three-stdlib-2.19.0.tgz#22b73fe07b2524548b486e551737db4b17586beb" + integrity sha512-ImKJXIlmx/iYH3U2CeLiYA2V60UqhpwLE2ErOME+FrD3Xodk7oQU5N9IZGKQzGjnl3hOfLmLZ5BPJrotmttBjg== + dependencies: + "@babel/runtime" "^7.16.7" + "@types/offscreencanvas" "^2019.6.4" + "@webgpu/glslang" "^0.0.15" + chevrotain "^10.1.2" + draco3d "^1.4.1" + fflate "^0.6.9" + ktx-parse "^0.4.5" + mmd-parser "^1.0.4" + opentype.js "^1.3.3" + potpack "^1.0.1" + zstddec "^0.0.2" + +three@0.146.0: + version "0.146.0" + resolved "https://registry.yarnpkg.com/three/-/three-0.146.0.tgz#fd80f0d128ab4bb821a02191ae241e4e6326f17a" + integrity sha512-1lvNfLezN6OJ9NaFAhfX4sm5e9YCzHtaRgZ1+B4C+Hv6TibRMsuBAM5/wVKzxjpYIlMymvgsHEFrrigEfXnb2A== through2@^4.0.0: version "4.0.2"