@threlte/rapier 2.0.0 → 3.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/components/Attractor/Attractor.svelte +8 -11
  2. package/dist/components/Attractor/Attractor.svelte.d.ts +2 -2
  3. package/dist/components/Colliders/AutoColliders.svelte +9 -25
  4. package/dist/components/Colliders/AutoColliders.svelte.d.ts +4 -4
  5. package/dist/components/Colliders/Collider.svelte +47 -51
  6. package/dist/components/Colliders/Collider.svelte.d.ts +4 -4
  7. package/dist/components/CollisionGroups/CollisionGroups.svelte +3 -5
  8. package/dist/components/Debug/Debug.svelte +5 -5
  9. package/dist/components/Debug/Debug.svelte.d.ts +3 -2
  10. package/dist/components/RigidBody/RigidBody.svelte +41 -57
  11. package/dist/components/RigidBody/RigidBody.svelte.d.ts +2 -2
  12. package/dist/components/World/InnerWorld.svelte +7 -24
  13. package/dist/components/World/InnerWorld.svelte.d.ts +7 -18
  14. package/dist/components/World/World.svelte +10 -24
  15. package/dist/hooks/useFrameHandler.js +36 -39
  16. package/dist/hooks/useHasEventListener.js +4 -4
  17. package/dist/lib/applyColliderActiveEvents.d.ts +1 -3
  18. package/dist/lib/applyColliderActiveEvents.js +10 -10
  19. package/dist/lib/createCollidersFromChildren.js +2 -2
  20. package/dist/lib/createRapierContext.d.ts +3 -3
  21. package/dist/lib/createRapierContext.js +4 -4
  22. package/dist/lib/getWorldTransforms.js +1 -1
  23. package/dist/lib/useCreateEvent.d.ts +1 -1
  24. package/dist/lib/useCreateEvent.js +2 -4
  25. package/dist/recipes/BasicPlayerController.svelte +9 -3
  26. package/dist/recipes/BasicPlayerController.svelte.d.ts +5 -2
  27. package/dist/types/types.d.ts +4 -7
  28. package/package.json +31 -28
@@ -1,13 +1,10 @@
1
- <script>import { T, useTask } from '@threlte/core';
1
+ <script lang="ts">import { T, useTask } from '@threlte/core';
2
2
  import { Group, Vector3 } from 'three';
3
3
  import { useRapier } from '../../hooks/useRapier';
4
- export let strength = 1;
5
- export let range = 50;
6
- export let gravityType = 'static';
7
- export let gravitationalConstant = 6.673e-11;
4
+ let { strength = 1, range = 50, gravityType = 'static', gravitationalConstant = 6.673e-11, ref = $bindable(), ...props } = $props();
8
5
  const { world, debug } = useRapier();
9
6
  const gravitySource = new Vector3();
10
- let obj = new Group();
7
+ const group = new Group();
11
8
  const calcForceByType = {
12
9
  static: (s, m2, r, d, G) => s,
13
10
  linear: (s, m2, r, d, G) => s * (d / r),
@@ -16,7 +13,7 @@ const calcForceByType = {
16
13
  const impulseVector = new Vector3();
17
14
  const bodyV3 = new Vector3();
18
15
  function applyImpulseToBodiesInRange() {
19
- obj.getWorldPosition(gravitySource);
16
+ group.getWorldPosition(gravitySource);
20
17
  world.forEachRigidBody((body) => {
21
18
  const { x, y, z } = body.translation();
22
19
  bodyV3.set(x, y, z);
@@ -36,11 +33,11 @@ useTask(() => {
36
33
  </script>
37
34
 
38
35
  <T
39
- let:ref
40
- is={obj}
41
- {...$$restProps}
36
+ is={group}
37
+ bind:ref
38
+ {...props}
42
39
  >
43
- <slot {ref} />
40
+ <slot ref={group} />
44
41
 
45
42
  {#if $debug}
46
43
  <T.Mesh>
@@ -1,5 +1,5 @@
1
1
  import { Props, type Events, type Slots } from '@threlte/core'
2
- import { SvelteComponentTyped } from 'svelte'
2
+ import { SvelteComponent } from 'svelte'
3
3
  import type { Group } from 'three'
4
4
  import type { GravityType } from '../../types/types'
5
5
 
@@ -35,7 +35,7 @@ type AttractorEvents = Events<Group>
35
35
 
36
36
  type AttractorSlots = Slots<Group>
37
37
 
38
- export default class Attractor extends SvelteComponentTyped<
38
+ export default class Attractor extends SvelteComponent<
39
39
  AttractorProps,
40
40
  AttractorEvents,
41
41
  AttractorSlots
@@ -1,9 +1,8 @@
1
- <script>import { ActiveCollisionTypes, CoefficientCombineRule } from '@dimforge/rapier3d-compat';
2
- import { createRawEventDispatcher, SceneGraphObject } from '@threlte/core';
1
+ <script lang="ts">import { ActiveCollisionTypes, CoefficientCombineRule } from '@dimforge/rapier3d-compat';
2
+ import { SceneGraphObject } from '@threlte/core';
3
3
  import { onDestroy, onMount } from 'svelte';
4
4
  import { Group } from 'three';
5
5
  import { useCollisionGroups } from '../../hooks/useCollisionGroups';
6
- import { useHasEventListeners } from '../../hooks/useHasEventListener';
7
6
  import { useRapier } from '../../hooks/useRapier';
8
7
  import { useRigidBody } from '../../hooks/useRigidBody';
9
8
  import { useCreateEvent } from '../../lib/useCreateEvent';
@@ -11,28 +10,16 @@ import { useParentRigidbodyObject } from '../../lib/rigidBodyObjectContext';
11
10
  import { applyColliderActiveEvents } from '../../lib/applyColliderActiveEvents';
12
11
  import { createCollidersFromChildren } from '../../lib/createCollidersFromChildren';
13
12
  import { eulerToQuaternion } from '../../lib/eulerToQuaternion';
14
- export let shape = 'convexHull';
15
- export let restitution = undefined;
16
- export let restitutionCombineRule = undefined;
17
- export let friction = undefined;
18
- export let frictionCombineRule = undefined;
19
- export let sensor = undefined;
20
- export let contactForceEventThreshold = undefined;
21
- export let density = undefined;
22
- export let mass = undefined;
23
- export let centerOfMass = undefined;
24
- export let principalAngularInertia = undefined;
25
- export let angularInertiaLocalFrame = undefined;
13
+ let { shape = 'convexHull', restitution, restitutionCombineRule, friction, frictionCombineRule, sensor, contactForceEventThreshold, density, mass, centerOfMass, principalAngularInertia, angularInertiaLocalFrame, refresh = $bindable(() => create()), colliders = $bindable(), ...props } = $props();
26
14
  const group = new Group();
27
- const { updateRef } = useCreateEvent();
15
+ const { updateRef } = useCreateEvent(props.$$events);
28
16
  const rigidBody = useRigidBody();
29
17
  const rigidBodyParentObject = useParentRigidbodyObject();
30
18
  const { world, addColliderToContext, removeColliderFromContext } = useRapier();
31
- export let colliders = [];
32
19
  const collisionGroups = useCollisionGroups();
33
- const dispatcher = createRawEventDispatcher();
34
- const { hasEventListeners: colliderHasEventListeners } = useHasEventListeners();
35
20
  const cleanup = () => {
21
+ if (colliders === undefined)
22
+ return;
36
23
  collisionGroups.removeColliders(colliders);
37
24
  colliders.forEach((c) => {
38
25
  removeColliderFromContext(c);
@@ -40,13 +27,13 @@ const cleanup = () => {
40
27
  });
41
28
  colliders.length = 0;
42
29
  };
43
- export const create = () => {
30
+ const create = () => {
44
31
  cleanup();
45
32
  colliders = createCollidersFromChildren(group, shape ?? 'convexHull', world, rigidBody, rigidBodyParentObject);
46
- colliders.forEach((c) => addColliderToContext(c, group, dispatcher));
33
+ colliders.forEach((c) => addColliderToContext(c, group, props.$$events));
47
34
  collisionGroups.registerColliders(colliders);
48
35
  colliders.forEach((collider) => {
49
- applyColliderActiveEvents(collider, colliderHasEventListeners, rigidBody?.userData?.hasEventListeners);
36
+ applyColliderActiveEvents(collider, props.$$events, rigidBody?.userData?.events);
50
37
  collider.setActiveCollisionTypes(ActiveCollisionTypes.ALL);
51
38
  collider.setRestitution(restitution ?? 0);
52
39
  collider.setRestitutionCombineRule(restitutionCombineRule ?? CoefficientCombineRule.Average);
@@ -72,9 +59,6 @@ export const create = () => {
72
59
  onMount(() => {
73
60
  create();
74
61
  });
75
- export const refresh = () => {
76
- create();
77
- };
78
62
  /**
79
63
  * Cleanup
80
64
  */
@@ -57,10 +57,10 @@ export type MassDef = Density | Mass | MassProperties | NoMassProperties
57
57
  type MassProps<TMassDef extends MassDef> = TMassDef extends Density
58
58
  ? Density
59
59
  : TMassDef extends MassProperties
60
- ? MassProperties
61
- : TMassDef extends Mass
62
- ? Mass
63
- : NoMassProperties
60
+ ? MassProperties
61
+ : TMassDef extends Mass
62
+ ? Mass
63
+ : NoMassProperties
64
64
 
65
65
  // ------------------ COLLIDER ------------------
66
66
 
@@ -1,9 +1,8 @@
1
- <script>import { ActiveCollisionTypes, CoefficientCombineRule, Collider, ColliderDesc } from '@dimforge/rapier3d-compat';
2
- import { createRawEventDispatcher, SceneGraphObject, useTask } from '@threlte/core';
1
+ <script lang="ts">import { ActiveCollisionTypes, CoefficientCombineRule, Collider, ColliderDesc } from '@dimforge/rapier3d-compat';
2
+ import { SceneGraphObject, useTask } from '@threlte/core';
3
3
  import { onDestroy, onMount, tick } from 'svelte';
4
4
  import { Object3D, Quaternion, Vector3 } from 'three';
5
5
  import { useCollisionGroups } from '../../hooks/useCollisionGroups';
6
- import { useHasEventListeners } from '../../hooks/useHasEventListener';
7
6
  import { useRapier } from '../../hooks/useRapier';
8
7
  import { useRigidBody } from '../../hooks/useRigidBody';
9
8
  import { useParentRigidbodyObject } from '../../lib/rigidBodyObjectContext';
@@ -12,30 +11,20 @@ import { applyColliderActiveEvents } from '../../lib/applyColliderActiveEvents';
12
11
  import { eulerToQuaternion } from '../../lib/eulerToQuaternion';
13
12
  import { getWorldPosition, getWorldQuaternion } from '../../lib/getWorldTransforms';
14
13
  import { scaleColliderArgs } from '../../lib/scaleColliderArgs';
15
- export let shape;
16
- export let args;
17
- export let type = undefined;
18
- export let restitution = undefined;
19
- export let restitutionCombineRule = undefined;
20
- export let friction = undefined;
21
- export let frictionCombineRule = undefined;
22
- export let sensor = undefined;
23
- export let contactForceEventThreshold = undefined;
24
- export let density = undefined;
25
- export let mass = undefined;
26
- export let centerOfMass = undefined;
27
- export let principalAngularInertia = undefined;
28
- export let angularInertiaLocalFrame = undefined;
14
+ let { shape, args, type, restitution, restitutionCombineRule, friction, frictionCombineRule, sensor, contactForceEventThreshold, density, mass, centerOfMass, principalAngularInertia, angularInertiaLocalFrame, collider = $bindable(), refresh = $bindable(() => {
15
+ if (!collider)
16
+ return;
17
+ collider.setTranslation(getWorldPosition(object));
18
+ collider.setRotation(getWorldQuaternion(object));
19
+ }), ...props } = $props();
29
20
  const object = new Object3D();
30
- const { updateRef } = useCreateEvent();
21
+ const { updateRef } = useCreateEvent(props.$$events);
31
22
  const rigidBody = useRigidBody();
32
23
  const parentRigidBodyObject = useParentRigidbodyObject();
33
24
  const hasRigidBodyParent = !!rigidBody;
34
25
  const rapierContext = useRapier();
35
26
  const { world } = rapierContext;
36
- export let collider = undefined;
37
27
  const collisionGroups = useCollisionGroups();
38
- const dispatcher = createRawEventDispatcher();
39
28
  /**
40
29
  * Actual collider setup happens onMount as only then
41
30
  * the transforms are finished.
@@ -52,7 +41,7 @@ onMount(async () => {
52
41
  /**
53
42
  * Add collider to context
54
43
  */
55
- rapierContext.addColliderToContext(collider, object, dispatcher);
44
+ rapierContext.addColliderToContext(collider, object, props.$$events);
56
45
  /**
57
46
  * For use in conjunction with component <CollisionGroups>
58
47
  */
@@ -75,36 +64,43 @@ onMount(async () => {
75
64
  collider.setRotation(object.getWorldQuaternion(new Quaternion()));
76
65
  }
77
66
  });
78
- const { hasEventListeners: colliderHasEventListeners } = useHasEventListeners();
79
- $: collider?.setRestitution(restitution ?? 0);
80
- $: collider?.setRestitutionCombineRule(restitutionCombineRule ?? CoefficientCombineRule.Average);
81
- $: collider?.setFriction(friction ?? 0.7);
82
- $: collider?.setFrictionCombineRule(frictionCombineRule ?? CoefficientCombineRule.Average);
83
- $: collider?.setSensor(sensor ?? false);
84
- $: collider?.setContactForceEventThreshold(contactForceEventThreshold ?? 0);
85
- $: if (density)
86
- collider?.setDensity(density);
87
- $: if (collider && mass) {
88
- if (centerOfMass && principalAngularInertia && angularInertiaLocalFrame) {
89
- collider.setMassProperties(mass, { x: centerOfMass[0], y: centerOfMass[1], z: centerOfMass[2] }, {
90
- x: principalAngularInertia[0],
91
- y: principalAngularInertia[1],
92
- z: principalAngularInertia[2]
93
- }, eulerToQuaternion(angularInertiaLocalFrame));
67
+ $effect.pre(() => {
68
+ collider?.setRestitution(restitution ?? 0);
69
+ });
70
+ $effect.pre(() => {
71
+ collider?.setRestitutionCombineRule(restitutionCombineRule ?? CoefficientCombineRule.Average);
72
+ });
73
+ $effect.pre(() => {
74
+ collider?.setFriction(friction ?? 0.7);
75
+ });
76
+ $effect.pre(() => {
77
+ collider?.setFrictionCombineRule(frictionCombineRule ?? CoefficientCombineRule.Average);
78
+ });
79
+ $effect.pre(() => collider?.setSensor(sensor ?? false));
80
+ $effect.pre(() => collider?.setContactForceEventThreshold(contactForceEventThreshold ?? 0));
81
+ $effect.pre(() => {
82
+ if (density !== undefined)
83
+ collider?.setDensity(density);
84
+ });
85
+ $effect.pre(() => {
86
+ if (collider && mass) {
87
+ if (centerOfMass && principalAngularInertia && angularInertiaLocalFrame) {
88
+ collider.setMassProperties(mass, { x: centerOfMass[0], y: centerOfMass[1], z: centerOfMass[2] }, {
89
+ x: principalAngularInertia[0],
90
+ y: principalAngularInertia[1],
91
+ z: principalAngularInertia[2]
92
+ }, eulerToQuaternion(angularInertiaLocalFrame));
93
+ }
94
+ else {
95
+ collider.setMass(mass);
96
+ }
94
97
  }
95
- else {
96
- collider.setMass(mass);
98
+ });
99
+ $effect.pre(() => {
100
+ if (collider) {
101
+ applyColliderActiveEvents(collider, props.$$events, rigidBody?.userData?.events);
97
102
  }
98
- }
99
- $: if (collider) {
100
- applyColliderActiveEvents(collider, colliderHasEventListeners, rigidBody?.userData?.hasEventListeners);
101
- }
102
- export const refresh = () => {
103
- if (!collider)
104
- return;
105
- collider.setTranslation(getWorldPosition(object));
106
- collider.setRotation(getWorldQuaternion(object));
107
- };
103
+ });
108
104
  /**
109
105
  * If the Collider isAttached (i.e. NOT child of a RigidBody), update the
110
106
  * transforms on every frame.
@@ -114,12 +110,12 @@ const { start, stop } = useTask(() => {
114
110
  }, {
115
111
  autoStart: !hasRigidBodyParent && type === 'dynamic'
116
112
  });
117
- $: {
113
+ $effect.pre(() => {
118
114
  if (!hasRigidBodyParent && type === 'dynamic')
119
115
  start();
120
116
  else
121
117
  stop();
122
- }
118
+ });
123
119
  /**
124
120
  * Cleanup
125
121
  */
@@ -89,10 +89,10 @@ export type MassDef = Density | Mass | MassProperties | NoMassProperties
89
89
  type MassProps<TMassDef extends MassDef> = TMassDef extends Density
90
90
  ? Density
91
91
  : TMassDef extends MassProperties
92
- ? MassProperties
93
- : TMassDef extends Mass
94
- ? Mass
95
- : NoMassProperties
92
+ ? MassProperties
93
+ : TMassDef extends Mass
94
+ ? Mass
95
+ : NoMassProperties
96
96
 
97
97
  // ------------------ COLLIDER ------------------
98
98
 
@@ -1,11 +1,9 @@
1
- <script>import { setContext } from 'svelte';
1
+ <script lang="ts">import { setContext } from 'svelte';
2
2
  import { writable } from 'svelte/store';
3
3
  import { computeBitMask } from '../../lib/computeBitMask';
4
- export let groups = undefined;
5
- export let filter = undefined;
6
- export let memberships = undefined;
4
+ let { groups, filter, memberships } = $props();
7
5
  const store = writable(computeBitMask(groups, filter, memberships));
8
- $: store.set(computeBitMask(groups, filter, memberships));
6
+ $effect.pre(() => store.set(computeBitMask(groups, filter, memberships)));
9
7
  setContext('threlte-rapier-collision-group', store);
10
8
  </script>
11
9
 
@@ -1,7 +1,8 @@
1
- <script>import { T, useTask } from '@threlte/core';
1
+ <script lang="ts">import { T, useTask } from '@threlte/core';
2
2
  import { onDestroy } from 'svelte';
3
3
  import { BufferAttribute, BufferGeometry } from 'three';
4
4
  import { useRapier } from '../../hooks/useRapier';
5
+ let { ref = $bindable(), ...props } = $props();
5
6
  const { world, debug } = useRapier();
6
7
  const geometry = new BufferGeometry();
7
8
  debug.set(true);
@@ -18,12 +19,11 @@ onDestroy(() => {
18
19
  </script>
19
20
 
20
21
  <T.LineSegments
22
+ bind:ref
21
23
  frustumCulled={false}
22
24
  renderOrder={Infinity}
25
+ {...props}
23
26
  >
24
27
  <T is={geometry} />
25
- <T.LineBasicMaterial
26
- vertexColors
27
- {...$$restProps}
28
- />
28
+ <T.LineBasicMaterial vertexColors />
29
29
  </T.LineSegments>
@@ -1,6 +1,7 @@
1
+ import type { Props } from '@threlte/core'
1
2
  import { SvelteComponent } from 'svelte'
2
- import type { LineBasicMaterialParameters } from 'three'
3
+ import type { LineSegments } from 'three'
3
4
 
4
- export type DebugProps = LineBasicMaterialParameters
5
+ export type DebugProps = Props<LineSegments>
5
6
 
6
7
  export default class Debug extends SvelteComponent<DebugProps> {}
@@ -1,30 +1,14 @@
1
- <script>import { createRawEventDispatcher, SceneGraphObject } from '@threlte/core';
1
+ <script lang="ts">import { SceneGraphObject } from '@threlte/core';
2
2
  import { onDestroy, setContext, tick } from 'svelte';
3
3
  import { Object3D, Vector3 } from 'three';
4
- import { useHasEventListeners } from '../../hooks/useHasEventListener';
5
4
  import { useRapier } from '../../hooks/useRapier';
6
5
  import { getWorldPosition, getWorldQuaternion, getWorldScale } from '../../lib/getWorldTransforms';
7
6
  import { parseRigidBodyType } from '../../lib/parseRigidBodyType';
8
7
  import { setParentRigidbodyObject } from '../../lib/rigidBodyObjectContext';
9
8
  import { useCreateEvent } from '../../lib/useCreateEvent';
10
9
  const { world, rapier, addRigidBodyToContext, removeRigidBodyFromContext } = useRapier();
11
- export let linearVelocity = undefined;
12
- export let angularVelocity = undefined;
13
- export let type = 'dynamic';
14
- export let canSleep = true;
15
- export let gravityScale = 1;
16
- export let ccd = false;
17
- export let angularDamping = 0;
18
- export let linearDamping = 0;
19
- export let lockRotations = false;
20
- export let lockTranslations = false;
21
- export let enabledRotations = [true, true, true];
22
- export let enabledTranslations = [true, true, true];
23
- export let dominance = 0;
24
- export let enabled = true;
25
- export let userData = {};
26
- const dispatcher = createRawEventDispatcher();
27
- const { updateRef } = useCreateEvent();
10
+ let { linearVelocity, angularVelocity, type = 'dynamic', canSleep = true, gravityScale = 1, ccd = false, angularDamping = 0, linearDamping = 0, lockRotations = false, lockTranslations = false, enabledRotations = [true, true, true], enabledTranslations = [true, true, true], dominance = 0, enabled = true, userData = {}, rigidBody = $bindable(), ...props } = $props();
11
+ const { updateRef } = useCreateEvent(props.$$events);
28
12
  const object = new Object3D();
29
13
  /**
30
14
  * isSleeping used for events "sleep" and "wake" in `useFrameHandler`
@@ -34,14 +18,11 @@ object.userData.isSleeping = false;
34
18
  * RigidBody Description
35
19
  */
36
20
  const desc = new rapier.RigidBodyDesc(parseRigidBodyType(type)).setCanSleep(canSleep);
37
- /**
38
- * Export the rigidBody only after positional initialization
39
- */
40
- export let rigidBody = undefined;
41
21
  /**
42
22
  * Temporary RigidBody init
43
23
  */
44
- const rigidBodyTemp = world.createRigidBody(desc);
24
+ let rigidBodyInternal = world.createRigidBody(desc);
25
+ rigidBody = rigidBodyInternal;
45
26
  /**
46
27
  * Apply transforms after the parent component added "object" to itself
47
28
  */
@@ -52,47 +33,50 @@ const initPosition = async () => {
52
33
  const parentWorldScale = object.parent ? getWorldScale(object.parent) : new Vector3(1, 1, 1);
53
34
  const worldPosition = getWorldPosition(object).multiply(parentWorldScale);
54
35
  const worldQuaternion = getWorldQuaternion(object);
55
- rigidBodyTemp.setTranslation(worldPosition, true);
56
- rigidBodyTemp.setRotation(worldQuaternion, true);
57
- rigidBody = rigidBodyTemp;
58
- updateRef(rigidBody);
36
+ rigidBodyInternal.setTranslation(worldPosition, true);
37
+ rigidBodyInternal.setRotation(worldQuaternion, true);
38
+ updateRef(rigidBodyInternal);
59
39
  };
60
40
  initPosition();
61
41
  /**
62
42
  * Will come in handy in the future for joints
63
43
  */
64
- object.userData.rigidBody = rigidBodyTemp;
65
- /**
66
- * Reactive RigidBody properties
67
- */
68
- $: rigidBodyTemp.setBodyType(parseRigidBodyType(type), true);
69
- $: if (linearVelocity)
70
- rigidBodyTemp.setLinvel({ x: linearVelocity[0], y: linearVelocity[1], z: linearVelocity[2] }, true);
71
- $: if (angularVelocity)
72
- rigidBodyTemp.setAngvel({ x: angularVelocity[0], y: angularVelocity[1], z: angularVelocity[2] }, true);
73
- $: rigidBodyTemp.setGravityScale(gravityScale, true);
74
- $: rigidBodyTemp.enableCcd(ccd);
75
- $: rigidBodyTemp.setDominanceGroup(dominance);
76
- $: rigidBodyTemp.lockRotations(lockRotations, true);
77
- $: rigidBodyTemp.lockTranslations(lockTranslations, true);
78
- $: rigidBodyTemp.setEnabledRotations(...enabledRotations, true);
79
- $: rigidBodyTemp.setEnabledTranslations(...enabledTranslations, true);
80
- $: rigidBodyTemp.setAngularDamping(angularDamping);
81
- $: rigidBodyTemp.setLinearDamping(linearDamping);
82
- $: rigidBodyTemp.setEnabled(enabled);
44
+ object.userData.rigidBody = rigidBodyInternal;
45
+ $effect.pre(() => rigidBodyInternal.setBodyType(parseRigidBodyType(type), true));
46
+ $effect.pre(() => {
47
+ if (linearVelocity) {
48
+ rigidBodyInternal.setLinvel({ x: linearVelocity[0], y: linearVelocity[1], z: linearVelocity[2] }, true);
49
+ }
50
+ });
51
+ $effect.pre(() => {
52
+ if (angularVelocity) {
53
+ rigidBodyInternal.setAngvel({ x: angularVelocity[0], y: angularVelocity[1], z: angularVelocity[2] }, true);
54
+ }
55
+ });
56
+ $effect.pre(() => rigidBodyInternal.setGravityScale(gravityScale, true));
57
+ $effect.pre(() => rigidBodyInternal.enableCcd(ccd));
58
+ $effect.pre(() => rigidBodyInternal.setDominanceGroup(dominance));
59
+ $effect.pre(() => rigidBodyInternal.lockRotations(lockRotations, true));
60
+ $effect.pre(() => rigidBodyInternal.lockTranslations(lockTranslations, true));
61
+ $effect.pre(() => rigidBodyInternal.setEnabledRotations(...enabledRotations, true));
62
+ $effect.pre(() => rigidBodyInternal.setEnabledTranslations(...enabledTranslations, true));
63
+ $effect.pre(() => rigidBodyInternal.setAngularDamping(angularDamping));
64
+ $effect.pre(() => rigidBodyInternal.setLinearDamping(linearDamping));
65
+ $effect.pre(() => rigidBodyInternal.setEnabled(enabled));
83
66
  /**
84
67
  * Add userData to the rigidBody
85
68
  */
86
- const { hasEventListeners } = useHasEventListeners();
87
- $: rigidBodyTemp.userData = {
88
- hasEventListeners,
89
- ...userData
90
- };
69
+ $effect.pre(() => {
70
+ rigidBodyInternal.userData = {
71
+ events: props.$$events,
72
+ ...userData
73
+ };
74
+ });
91
75
  /**
92
76
  * Setting the RigidBody context so that colliders can
93
77
  * hook onto.
94
78
  */
95
- setContext('threlte-rapier-rigidbody', rigidBodyTemp);
79
+ setContext('threlte-rapier-rigidbody', rigidBodyInternal);
96
80
  /**
97
81
  * Used by child colliders to restore transform
98
82
  */
@@ -100,16 +84,16 @@ setParentRigidbodyObject(object);
100
84
  /**
101
85
  * Add the mesh to the context
102
86
  */
103
- addRigidBodyToContext(rigidBodyTemp, object, dispatcher);
87
+ addRigidBodyToContext(rigidBodyInternal, object, props.$$events);
104
88
  /**
105
89
  * cleanup
106
90
  */
107
91
  onDestroy(() => {
108
- removeRigidBodyFromContext(rigidBodyTemp);
109
- world.removeRigidBody(rigidBodyTemp);
92
+ removeRigidBodyFromContext(rigidBodyInternal);
93
+ world.removeRigidBody(rigidBodyInternal);
110
94
  });
111
95
  </script>
112
96
 
113
97
  <SceneGraphObject {object}>
114
- <slot {rigidBody} />
98
+ <slot rigidBody={rigidBodyInternal} />
115
99
  </SceneGraphObject>
@@ -7,7 +7,7 @@ import type { RigidBodyEventMap } from '../../types/types'
7
7
  export type Boolean3Array = [x: boolean, y: boolean, z: boolean]
8
8
 
9
9
  export type RigidBodyProps = {
10
- rigidBody?: RapierRigidBody
10
+ rigidBody: RapierRigidBody
11
11
 
12
12
  /**
13
13
  * Specify the type of this rigid body
@@ -58,7 +58,7 @@ export type RigidBodyProps = {
58
58
  enabledRotations?: Boolean3Array
59
59
 
60
60
  /**
61
- * Allow rotation of this rigid-body only along specific axes.
61
+ * Allow translations of this rigid-body only along specific axes.
62
62
  */
63
63
  enabledTranslations?: Boolean3Array
64
64
 
@@ -1,31 +1,14 @@
1
- <script
2
- context="module"
3
-
4
- >import { onDestroy, setContext, tick } from 'svelte';
1
+ <script lang="ts">import { onDestroy, setContext, tick } from 'svelte';
5
2
  import { useFrameHandler } from '../../hooks/useFrameHandler';
6
3
  import { createRapierContext } from '../../lib/createRapierContext';
7
- </script>
8
-
9
- <script>export let gravity = [0, -9.81, 0];
10
- export let rawIntegrationParameters = undefined;
11
- export let rawIslands = undefined;
12
- export let rawBroadPhase = undefined;
13
- export let rawNarrowPhase = undefined;
14
- export let rawBodies = undefined;
15
- export let rawColliders = undefined;
16
- export let rawImpulseJoints = undefined;
17
- export let rawMultibodyJoints = undefined;
18
- export let rawCCDSolver = undefined;
19
- export let rawQueryPipeline = undefined;
20
- export let rawPhysicsPipeline = undefined;
21
- export let rawSerializationPipeline = undefined;
22
- export let rawDebugRenderPipeline = undefined;
23
- export let stage = undefined;
4
+ let { gravity = [0, -9.81, 0], rawIntegrationParameters, rawIslands, rawBroadPhase, rawNarrowPhase, rawBodies, rawColliders, rawImpulseJoints, rawMultibodyJoints, rawCCDSolver, rawQueryPipeline, rawPhysicsPipeline, rawSerializationPipeline, rawDebugRenderPipeline, stage } = $props();
24
5
  const rapierContext = createRapierContext({ x: gravity[0], y: gravity[1], z: gravity[2] }, rawIntegrationParameters, rawIslands, rawBroadPhase, rawNarrowPhase, rawBodies, rawColliders, rawImpulseJoints, rawMultibodyJoints, rawCCDSolver, rawQueryPipeline, rawPhysicsPipeline, rawSerializationPipeline, rawDebugRenderPipeline);
25
6
  setContext('threlte-rapier-context', rapierContext);
26
- $: if (gravity !== undefined) {
27
- rapierContext.world.gravity = { x: gravity[0], y: gravity[1], z: gravity[2] };
28
- }
7
+ $effect.pre(() => {
8
+ if (gravity !== undefined) {
9
+ rapierContext.world.gravity = { x: gravity[0], y: gravity[1], z: gravity[2] };
10
+ }
11
+ });
29
12
  useFrameHandler(rapierContext, stage);
30
13
  onDestroy(async () => {
31
14
  await tick();
@@ -1,21 +1,10 @@
1
- import { SvelteComponentTyped } from "svelte";
1
+ import { SvelteComponent } from "svelte";
2
+ import type { WorldProps } from './World.svelte';
2
3
  declare const __propDef: {
3
- props: {
4
- gravity?: [x: number, y: number, z: number] | undefined;
5
- rawIntegrationParameters?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawIntegrationParameters | undefined;
6
- rawIslands?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawIslandManager | undefined;
7
- rawBroadPhase?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawBroadPhase | undefined;
8
- rawNarrowPhase?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawNarrowPhase | undefined;
9
- rawBodies?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawRigidBodySet | undefined;
10
- rawColliders?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawColliderSet | undefined;
11
- rawImpulseJoints?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawImpulseJointSet | undefined;
12
- rawMultibodyJoints?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawMultibodyJointSet | undefined;
13
- rawCCDSolver?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawCCDSolver | undefined;
14
- rawQueryPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawQueryPipeline | undefined;
15
- rawPhysicsPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawPhysicsPipeline | undefined;
16
- rawSerializationPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawSerializationPipeline | undefined;
17
- rawDebugRenderPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawDebugRenderPipeline | undefined;
18
- stage?: import("@threlte/core").Key | import("@threlte/core").Stage | undefined;
4
+ props: WorldProps & {
5
+ children?: ((this: void) => typeof import("svelte").SnippetReturn & {
6
+ _: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
7
+ }) | undefined;
19
8
  };
20
9
  events: {
21
10
  [evt: string]: CustomEvent<any>;
@@ -27,6 +16,6 @@ declare const __propDef: {
27
16
  export type InnerWorldProps = typeof __propDef.props;
28
17
  export type InnerWorldEvents = typeof __propDef.events;
29
18
  export type InnerWorldSlots = typeof __propDef.slots;
30
- export default class InnerWorld extends SvelteComponentTyped<InnerWorldProps, InnerWorldEvents, InnerWorldSlots> {
19
+ export default class InnerWorld extends SvelteComponent<InnerWorldProps, InnerWorldEvents, InnerWorldSlots> {
31
20
  }
32
21
  export {};
@@ -1,6 +1,6 @@
1
1
  <script
2
2
  context="module"
3
-
3
+ lang="ts"
4
4
  >import RAPIER from '@dimforge/rapier3d-compat';
5
5
  import { onMount } from 'svelte';
6
6
  import { writable } from 'svelte/store';
@@ -10,29 +10,15 @@ import { writable } from 'svelte/store';
10
10
  const initialized = writable(false);
11
11
  </script>
12
12
 
13
- <script>import InnerWorld from './InnerWorld.svelte';
14
- // self
15
- export let gravity = undefined;
16
- export let rawIntegrationParameters = undefined;
17
- export let rawIslands = undefined;
18
- export let rawBroadPhase = undefined;
19
- export let rawNarrowPhase = undefined;
20
- export let rawBodies = undefined;
21
- export let rawColliders = undefined;
22
- export let rawImpulseJoints = undefined;
23
- export let rawMultibodyJoints = undefined;
24
- export let rawCCDSolver = undefined;
25
- export let rawQueryPipeline = undefined;
26
- export let rawPhysicsPipeline = undefined;
27
- export let rawSerializationPipeline = undefined;
28
- export let rawDebugRenderPipeline = undefined;
13
+ <script lang="ts">import InnerWorld from './InnerWorld.svelte';
14
+ let { gravity, rawIntegrationParameters, rawIslands, rawBroadPhase, rawNarrowPhase, rawBodies, rawColliders, rawImpulseJoints, rawMultibodyJoints, rawCCDSolver, rawQueryPipeline, rawPhysicsPipeline, rawSerializationPipeline, rawDebugRenderPipeline,
29
15
  /**
30
- * This is passed to the useTask handler.
31
- * Use this to control when the rapier physics engine is updating the scene.
32
- * @default undefined
33
- */
34
- export let stage = undefined;
35
- let error = false;
16
+ * This is passed to the useTask handler.
17
+ * Use this to control when the rapier physics engine is updating the scene.
18
+ * @default undefined
19
+ */
20
+ stage } = $props();
21
+ let error = $state(false);
36
22
  const init = async () => {
37
23
  if ($initialized)
38
24
  return;
@@ -63,7 +49,7 @@ onMount(init);
63
49
  {rawPhysicsPipeline}
64
50
  {rawSerializationPipeline}
65
51
  {rawDebugRenderPipeline}
66
- {stage}
52
+ {stage}
67
53
  >
68
54
  <slot />
69
55
  </InnerWorld>
@@ -1,4 +1,4 @@
1
- import { Collider, EventQueue } from '@dimforge/rapier3d-compat';
1
+ import { EventQueue } from '@dimforge/rapier3d-compat';
2
2
  import { useTask } from '@threlte/core';
3
3
  import { derived } from 'svelte/store';
4
4
  import { Object3D, Quaternion, Vector3 } from 'three';
@@ -6,21 +6,21 @@ const tempObject = new Object3D();
6
6
  const tempVector3 = new Vector3();
7
7
  const tempQuaternion = new Quaternion();
8
8
  const getEventDispatchers = (ctx, collider1, collider2) => {
9
- const colliderDispatcher1 = ctx.colliderEventDispatchers.get(collider1.handle);
10
- const colliderDispatcher2 = ctx.colliderEventDispatchers.get(collider2.handle);
9
+ const collider1Events = ctx.colliderEventDispatchers.get(collider1.handle);
10
+ const collider2Events = ctx.colliderEventDispatchers.get(collider2.handle);
11
11
  const rigidBody1 = collider1.parent();
12
12
  const rigidBody2 = collider2.parent();
13
- const rigidBodyDispatcher1 = rigidBody1
13
+ const rigidBody1Events = rigidBody1
14
14
  ? ctx.rigidBodyEventDispatchers.get(rigidBody1.handle)
15
15
  : undefined;
16
- const rigidBodyDispatcher2 = rigidBody2
16
+ const rigidBody2Events = rigidBody2
17
17
  ? ctx.rigidBodyEventDispatchers.get(rigidBody2.handle)
18
18
  : undefined;
19
19
  return {
20
- colliderDispatcher1,
21
- colliderDispatcher2,
22
- rigidBodyDispatcher1,
23
- rigidBodyDispatcher2
20
+ collider1Events,
21
+ collider2Events,
22
+ rigidBody1Events,
23
+ rigidBody2Events
24
24
  };
25
25
  };
26
26
  export const useFrameHandler = (ctx, stage) => {
@@ -37,15 +37,15 @@ export const useFrameHandler = (ctx, stage) => {
37
37
  const rigidBody = world.getRigidBody(handle);
38
38
  if (!rigidBody)
39
39
  return;
40
- const dispatcher = ctx.rigidBodyEventDispatchers.get(handle);
40
+ const events = ctx.rigidBodyEventDispatchers.get(handle);
41
41
  if (!rigidBody || !rigidBody.isValid())
42
42
  return;
43
- if (dispatcher) {
43
+ if (events) {
44
44
  if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
45
- dispatcher('sleep');
45
+ events.sleep?.();
46
46
  }
47
47
  if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
48
- dispatcher('wake');
48
+ events.wake?.();
49
49
  }
50
50
  mesh.userData.isSleeping = rigidBody.isSleeping();
51
51
  }
@@ -75,11 +75,11 @@ export const useFrameHandler = (ctx, stage) => {
75
75
  if (!collider1 || !collider2) {
76
76
  return;
77
77
  }
78
- const { colliderDispatcher1, colliderDispatcher2, rigidBodyDispatcher1, rigidBodyDispatcher2 } = getEventDispatchers(ctx, collider1, collider2);
78
+ const { collider1Events, collider2Events, rigidBody1Events, rigidBody2Events } = getEventDispatchers(ctx, collider1, collider2);
79
79
  const rigidBody1 = collider1.parent();
80
80
  const rigidBody2 = collider2.parent();
81
81
  // Collider events
82
- colliderDispatcher1?.('contact', {
82
+ collider1Events?.contact?.({
83
83
  targetCollider: collider2,
84
84
  targetRigidBody: rigidBody2,
85
85
  maxForceDirection: e.maxForceDirection(),
@@ -87,7 +87,7 @@ export const useFrameHandler = (ctx, stage) => {
87
87
  totalForce: e.totalForce(),
88
88
  totalForceMagnitude: e.totalForceMagnitude()
89
89
  });
90
- colliderDispatcher2?.('contact', {
90
+ collider2Events?.contact?.({
91
91
  targetCollider: collider1,
92
92
  targetRigidBody: rigidBody1,
93
93
  maxForceDirection: e.maxForceDirection(),
@@ -96,7 +96,7 @@ export const useFrameHandler = (ctx, stage) => {
96
96
  totalForceMagnitude: e.totalForceMagnitude()
97
97
  });
98
98
  // RigidBody Events
99
- rigidBodyDispatcher1?.('contact', {
99
+ rigidBody1Events?.contact?.({
100
100
  targetCollider: collider2,
101
101
  targetRigidBody: rigidBody2,
102
102
  maxForceDirection: e.maxForceDirection(),
@@ -104,7 +104,7 @@ export const useFrameHandler = (ctx, stage) => {
104
104
  totalForce: e.totalForce(),
105
105
  totalForceMagnitude: e.totalForceMagnitude()
106
106
  });
107
- rigidBodyDispatcher2?.('contact', {
107
+ rigidBody2Events?.contact?.({
108
108
  targetCollider: collider1,
109
109
  targetRigidBody: rigidBody1,
110
110
  maxForceDirection: e.maxForceDirection(),
@@ -121,11 +121,8 @@ export const useFrameHandler = (ctx, stage) => {
121
121
  if (!collider1 || !collider2) {
122
122
  return;
123
123
  }
124
- const { colliderDispatcher1, colliderDispatcher2, rigidBodyDispatcher1, rigidBodyDispatcher2 } = getEventDispatchers(ctx, collider1, collider2);
125
- if (!colliderDispatcher1 &&
126
- !colliderDispatcher2 &&
127
- !rigidBodyDispatcher1 &&
128
- !rigidBodyDispatcher2) {
124
+ const { collider1Events, collider2Events, rigidBody1Events, rigidBody2Events } = getEventDispatchers(ctx, collider1, collider2);
125
+ if (!collider1Events && !collider2Events && !rigidBody1Events && !rigidBody2Events) {
129
126
  return;
130
127
  }
131
128
  const rigidBody1 = collider1.parent();
@@ -135,20 +132,20 @@ export const useFrameHandler = (ctx, stage) => {
135
132
  const isIntersection = world.intersectionPair(collider1, collider2);
136
133
  if (isIntersection) {
137
134
  // Collider Events
138
- colliderDispatcher1?.('sensorenter', {
135
+ collider1Events?.sensorenter?.({
139
136
  targetCollider: collider2,
140
137
  targetRigidBody: rigidBody2
141
138
  });
142
- colliderDispatcher2?.('sensorenter', {
139
+ collider2Events?.sensorenter?.({
143
140
  targetCollider: collider1,
144
141
  targetRigidBody: rigidBody1
145
142
  });
146
143
  // RigidBody Events
147
- rigidBodyDispatcher1?.('sensorenter', {
144
+ rigidBody1Events?.sensorenter?.({
148
145
  targetCollider: collider2,
149
146
  targetRigidBody: rigidBody2
150
147
  });
151
- rigidBodyDispatcher2?.('sensorenter', {
148
+ rigidBody2Events?.sensorenter?.({
152
149
  targetCollider: collider1,
153
150
  targetRigidBody: rigidBody1
154
151
  });
@@ -157,26 +154,26 @@ export const useFrameHandler = (ctx, stage) => {
157
154
  }
158
155
  world.contactPair(collider1, collider2, (manifold, flipped) => {
159
156
  // Collider events
160
- colliderDispatcher1?.('collisionenter', {
157
+ collider1Events?.collisionenter?.({
161
158
  flipped,
162
159
  manifold,
163
160
  targetCollider: collider2,
164
161
  targetRigidBody: rigidBody2
165
162
  });
166
- colliderDispatcher2?.('collisionenter', {
163
+ collider2Events?.collisionenter?.({
167
164
  flipped,
168
165
  manifold,
169
166
  targetCollider: collider1,
170
167
  targetRigidBody: rigidBody1
171
168
  });
172
169
  // RigidBody Events
173
- rigidBodyDispatcher1?.('collisionenter', {
170
+ rigidBody1Events?.collisionenter?.({
174
171
  flipped,
175
172
  manifold,
176
173
  targetCollider: collider2,
177
174
  targetRigidBody: rigidBody2
178
175
  });
179
- rigidBodyDispatcher2?.('collisionenter', {
176
+ rigidBody2Events?.collisionenter?.({
180
177
  flipped,
181
178
  manifold,
182
179
  targetCollider: collider1,
@@ -191,20 +188,20 @@ export const useFrameHandler = (ctx, stage) => {
191
188
  collider1.isSensor() ||
192
189
  collider2.isSensor();
193
190
  if (isIntersection) {
194
- colliderDispatcher1?.('sensorexit', {
191
+ collider1Events?.sensorexit?.({
195
192
  targetCollider: collider2,
196
193
  targetRigidBody: rigidBody2
197
194
  });
198
- colliderDispatcher2?.('sensorexit', {
195
+ collider2Events?.sensorexit?.({
199
196
  targetCollider: collider1,
200
197
  targetRigidBody: rigidBody1
201
198
  });
202
199
  // RigidBody Events
203
- rigidBodyDispatcher1?.('sensorexit', {
200
+ rigidBody1Events?.sensorexit?.({
204
201
  targetCollider: collider2,
205
202
  targetRigidBody: rigidBody2
206
203
  });
207
- rigidBodyDispatcher2?.('sensorexit', {
204
+ rigidBody2Events?.sensorexit?.({
208
205
  targetCollider: collider1,
209
206
  targetRigidBody: rigidBody1
210
207
  });
@@ -212,20 +209,20 @@ export const useFrameHandler = (ctx, stage) => {
212
209
  return;
213
210
  }
214
211
  // Collider events
215
- colliderDispatcher1?.('collisionexit', {
212
+ collider1Events?.collisionexit?.({
216
213
  targetCollider: collider2,
217
214
  targetRigidBody: rigidBody2
218
215
  });
219
- colliderDispatcher2?.('collisionexit', {
216
+ collider2Events?.collisionexit?.({
220
217
  targetCollider: collider1,
221
218
  targetRigidBody: rigidBody1
222
219
  });
223
220
  // RigidBody Events
224
- rigidBodyDispatcher1?.('collisionexit', {
221
+ rigidBody1Events?.collisionexit?.({
225
222
  targetCollider: collider2,
226
223
  targetRigidBody: rigidBody2
227
224
  });
228
- rigidBodyDispatcher2?.('collisionexit', {
225
+ rigidBody2Events?.collisionexit?.({
229
226
  targetCollider: collider1,
230
227
  targetRigidBody: rigidBody1
231
228
  });
@@ -1,9 +1,9 @@
1
- import { get_current_component } from 'svelte/internal';
2
1
  export const useHasEventListeners = () => {
3
- const component = get_current_component();
2
+ // const component = get_current_component()
4
3
  const hasEventListeners = (type) => {
5
- const callbacks = component.$$.callbacks;
6
- return type in callbacks && callbacks[type].length > 0;
4
+ // const callbacks = component.$$.callbacks
5
+ return true;
6
+ // return type in callbacks && (callbacks[type] as any[]).length > 0
7
7
  };
8
8
  return {
9
9
  hasEventListeners
@@ -1,4 +1,2 @@
1
1
  import { type Collider } from '@dimforge/rapier3d-compat';
2
- import type { useHasEventListeners } from '../hooks/useHasEventListener';
3
- import type { ColliderEventDispatcher, RigidBodyEventDispatcher } from '../types/types';
4
- export declare const applyColliderActiveEvents: (collider: Collider, colliderHasEventListeners: ReturnType<typeof useHasEventListeners<ColliderEventDispatcher>>['hasEventListeners'], rigidBodyHasEventListeners?: ReturnType<typeof useHasEventListeners<RigidBodyEventDispatcher>>['hasEventListeners']) => void;
2
+ export declare const applyColliderActiveEvents: (collider: Collider, colliderEvents?: Record<string, (arg: unknown) => void>, rigidBodyEvents?: Record<string, (arg: unknown) => void>) => void;
@@ -1,17 +1,17 @@
1
1
  import { ActiveEvents } from '@dimforge/rapier3d-compat';
2
- export const applyColliderActiveEvents = (collider, colliderHasEventListeners, rigidBodyHasEventListeners) => {
2
+ export const applyColliderActiveEvents = (collider, colliderEvents = {}, rigidBodyEvents = {}) => {
3
3
  let events = 0;
4
- if (colliderHasEventListeners('collisionenter') ||
5
- colliderHasEventListeners('collisionexit') ||
6
- rigidBodyHasEventListeners?.('collisionenter') ||
7
- rigidBodyHasEventListeners?.('collisionexit') ||
8
- colliderHasEventListeners('sensorenter') ||
9
- colliderHasEventListeners('sensorexit') ||
10
- rigidBodyHasEventListeners?.('sensorenter') ||
11
- rigidBodyHasEventListeners?.('sensorexit')) {
4
+ if (colliderEvents.collisionenter ||
5
+ colliderEvents.collisionexit ||
6
+ rigidBodyEvents.collisionenter ||
7
+ rigidBodyEvents.collisionexit ||
8
+ colliderEvents.sensorenter ||
9
+ colliderEvents.sensorexit ||
10
+ rigidBodyEvents.sensorenter ||
11
+ rigidBodyEvents.sensorexit) {
12
12
  events = events | ActiveEvents.COLLISION_EVENTS;
13
13
  }
14
- if (colliderHasEventListeners('contact') || rigidBodyHasEventListeners?.('contact')) {
14
+ if (colliderEvents.contact || rigidBodyEvents.contact) {
15
15
  events = events | ActiveEvents.CONTACT_FORCE_EVENTS;
16
16
  }
17
17
  if (events > 0) {
@@ -1,5 +1,5 @@
1
- import { ActiveEvents, Collider, ColliderDesc, World, RigidBody } from '@dimforge/rapier3d-compat';
2
- import { Mesh, Quaternion, Vector3 } from 'three';
1
+ import { ActiveEvents, ColliderDesc } from '@dimforge/rapier3d-compat';
2
+ import { Quaternion, Vector3 } from 'three';
3
3
  const offset = new Vector3();
4
4
  const worldPosition = new Vector3();
5
5
  const worldQuaternion = new Quaternion();
@@ -2,7 +2,7 @@
2
2
  import type { Collider, RigidBody } from '@dimforge/rapier3d-compat';
3
3
  import RAPIER from '@dimforge/rapier3d-compat';
4
4
  import type { Object3D } from 'three';
5
- import type { ColliderEventDispatcher, ColliderEventDispatchers, RigidBodyEventDispatcher, RigidBodyEventDispatchers } from '../types/types';
5
+ import type { ColliderEventDispatchers, RigidBodyEventDispatchers } from '../types/types';
6
6
  export declare const createRapierContext: (gravity: RAPIER.Vector, rawIntegrationParameters?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawIntegrationParameters | undefined, rawIslands?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawIslandManager | undefined, rawBroadPhase?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawBroadPhase | undefined, rawNarrowPhase?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawNarrowPhase | undefined, rawBodies?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawRigidBodySet | undefined, rawColliders?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawColliderSet | undefined, rawImpulseJoints?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawImpulseJointSet | undefined, rawMultibodyJoints?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawMultibodyJointSet | undefined, rawCCDSolver?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawCCDSolver | undefined, rawQueryPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawQueryPipeline | undefined, rawPhysicsPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawPhysicsPipeline | undefined, rawSerializationPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawSerializationPipeline | undefined, rawDebugRenderPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawDebugRenderPipeline | undefined) => {
7
7
  rapier: typeof RAPIER;
8
8
  world: RAPIER.World;
@@ -10,9 +10,9 @@ export declare const createRapierContext: (gravity: RAPIER.Vector, rawIntegratio
10
10
  rigidBodyObjects: Map<number, Object3D<import("three").Object3DEventMap>>;
11
11
  rigidBodyEventDispatchers: RigidBodyEventDispatchers;
12
12
  colliderEventDispatchers: ColliderEventDispatchers;
13
- addColliderToContext: (collider: Collider, object: Object3D, eventDispatcher: ColliderEventDispatcher) => void;
13
+ addColliderToContext: (collider: Collider, object: Object3D, events: Record<string, (arg: unknown) => void>) => void;
14
14
  removeColliderFromContext: (collider: Collider) => void;
15
- addRigidBodyToContext: (rigidBody: RigidBody, object: Object3D, eventDispatcher: RigidBodyEventDispatcher) => void;
15
+ addRigidBodyToContext: (rigidBody: RigidBody, object: Object3D, events: Record<string, (arg: unknown) => void>) => void;
16
16
  removeRigidBodyFromContext: (rigidBody: RigidBody) => void;
17
17
  debug: import("svelte/store").Writable<boolean>;
18
18
  pause: () => void;
@@ -12,9 +12,9 @@ export const createRapierContext = (...args) => {
12
12
  * @param object
13
13
  * @param eventDispatcher
14
14
  */
15
- const addColliderToContext = (collider, object, eventDispatcher) => {
15
+ const addColliderToContext = (collider, object, events) => {
16
16
  colliderObjects.set(collider.handle, object);
17
- colliderEventDispatchers.set(collider.handle, eventDispatcher);
17
+ colliderEventDispatchers.set(collider.handle, events);
18
18
  };
19
19
  /**
20
20
  * Removes the collider from the context
@@ -30,9 +30,9 @@ export const createRapierContext = (...args) => {
30
30
  * @param object
31
31
  * @param eventDispatcher
32
32
  */
33
- const addRigidBodyToContext = (rigidBody, object, eventDispatcher) => {
33
+ const addRigidBodyToContext = (rigidBody, object, events) => {
34
34
  rigidBodyObjects.set(rigidBody.handle, object);
35
- rigidBodyEventDispatchers.set(rigidBody.handle, eventDispatcher);
35
+ rigidBodyEventDispatchers.set(rigidBody.handle, events);
36
36
  };
37
37
  /**
38
38
  * Removes the RigidBody from the context
@@ -1,4 +1,4 @@
1
- import { Euler, Object3D, Quaternion, Vector3 } from 'three';
1
+ import { Euler, Quaternion, Vector3 } from 'three';
2
2
  const tempPosition = new Vector3();
3
3
  const tempQuaternion = new Quaternion();
4
4
  const tempRotation = new Euler();
@@ -1,3 +1,3 @@
1
- export declare const useCreateEvent: <T>() => {
1
+ export declare const useCreateEvent: <T>(events: Record<string, (arg: unknown) => void>) => {
2
2
  updateRef: (newRef: T) => void;
3
3
  };
@@ -1,7 +1,5 @@
1
1
  import { onDestroy } from 'svelte';
2
- import { createRawEventDispatcher } from '@threlte/core';
3
- export const useCreateEvent = () => {
4
- const dispatchRaw = createRawEventDispatcher();
2
+ export const useCreateEvent = (events) => {
5
3
  const cleanupFunctions = [];
6
4
  let ref = undefined;
7
5
  const dispatchCreateEvent = () => {
@@ -15,7 +13,7 @@ export const useCreateEvent = () => {
15
13
  };
16
14
  if (ref === undefined)
17
15
  return;
18
- dispatchRaw('create', { ref, cleanup });
16
+ events?.create?.({ ref, cleanup });
19
17
  };
20
18
  const updateRef = (newRef) => {
21
19
  ref = newRef;
@@ -1,4 +1,4 @@
1
- <script>import { createRawEventDispatcher, T, useTask } from '@threlte/core';
1
+ <script lang="ts">import { createRawEventDispatcher, T, useTask } from '@threlte/core';
2
2
  import { Vector2, Vector3 } from 'three';
3
3
  import Collider from '../components/Colliders/Collider.svelte';
4
4
  import CollisionGroups from '../components/CollisionGroups/CollisionGroups.svelte';
@@ -103,7 +103,10 @@ const onKeyUp = (e) => {
103
103
  };
104
104
  </script>
105
105
 
106
- <svelte:window on:keydown|preventDefault={onKeyDown} on:keyup|preventDefault={onKeyUp} />
106
+ <svelte:window
107
+ on:keydown|preventDefault={onKeyDown}
108
+ on:keyup|preventDefault={onKeyUp}
109
+ />
107
110
 
108
111
  <T.Group {position}>
109
112
  <RigidBody
@@ -113,7 +116,10 @@ const onKeyUp = (e) => {
113
116
  type={'dynamic'}
114
117
  >
115
118
  <CollisionGroups groups={playerCollisionGroups}>
116
- <Collider shape={'capsule'} args={[height / 2 - radius, radius]} />
119
+ <Collider
120
+ shape={'capsule'}
121
+ args={[height / 2 - radius, radius]}
122
+ />
117
123
  </CollisionGroups>
118
124
 
119
125
  <CollisionGroups groups={groundCollisionGroups}>
@@ -1,4 +1,4 @@
1
- import { SvelteComponentTyped } from "svelte";
1
+ import { SvelteComponent } from "svelte";
2
2
  import { Vector3 } from 'three';
3
3
  import type { CollisionGroupsBitMask } from '../types/types';
4
4
  declare const __propDef: {
@@ -10,6 +10,9 @@ declare const __propDef: {
10
10
  jumpStrength?: number | undefined;
11
11
  playerCollisionGroups?: CollisionGroupsBitMask | undefined;
12
12
  groundCollisionGroups?: CollisionGroupsBitMask | undefined;
13
+ children?: ((this: void) => typeof import("svelte").SnippetReturn & {
14
+ _: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
15
+ }) | undefined;
13
16
  };
14
17
  events: {
15
18
  [evt: string]: CustomEvent<any>;
@@ -21,6 +24,6 @@ declare const __propDef: {
21
24
  export type BasicPlayerControllerProps = typeof __propDef.props;
22
25
  export type BasicPlayerControllerEvents = typeof __propDef.events;
23
26
  export type BasicPlayerControllerSlots = typeof __propDef.slots;
24
- export default class BasicPlayerController extends SvelteComponentTyped<BasicPlayerControllerProps, BasicPlayerControllerEvents, BasicPlayerControllerSlots> {
27
+ export default class BasicPlayerController extends SvelteComponent<BasicPlayerControllerProps, BasicPlayerControllerEvents, BasicPlayerControllerSlots> {
25
28
  }
26
29
  export {};
@@ -1,7 +1,6 @@
1
+ /// <reference types="svelte" />
1
2
  import type { Collider, ColliderHandle, RigidBody, RigidBodyHandle, TempContactManifold, Vector } from '@dimforge/rapier3d-compat';
2
- import type { createRawEventDispatcher } from '@threlte/core';
3
3
  import type { Writable } from 'svelte/store';
4
- import type { useHasEventListeners } from '../hooks/useHasEventListener';
5
4
  import type { createRapierContext } from '../lib/createRapierContext';
6
5
  export type ColliderShapes = 'ball' | 'capsule' | 'segment' | 'triangle' | 'roundTriangle' | 'polyline' | 'trimesh' | 'cuboid' | 'roundCuboid' | 'heightfield' | 'cylinder' | 'roundCylinder' | 'cone' | 'roundCone' | 'convexHull' | 'convexMesh' | 'roundConvexHull' | 'roundConvexMesh';
7
6
  export type AutoCollidersShapes = 'cuboid' | 'ball' | 'trimesh' | 'convexHull' | 'capsule';
@@ -46,14 +45,12 @@ export type RigidBodyEventMap = ColliderEventMap & {
46
45
  sleep: void;
47
46
  wake: void;
48
47
  };
49
- export type RigidBodyEventDispatcher = ReturnType<typeof createRawEventDispatcher<RigidBodyEventMap>>;
50
- export type ColliderEventDispatcher = ReturnType<typeof createRawEventDispatcher<ColliderEventMap>>;
51
- export type RigidBodyEventDispatchers = Map<RigidBodyHandle, RigidBodyEventDispatcher>;
52
- export type ColliderEventDispatchers = Map<ColliderHandle, ColliderEventDispatcher>;
48
+ export type RigidBodyEventDispatchers = Map<RigidBodyHandle, Record<string, (arg: unknown) => void>>;
49
+ export type ColliderEventDispatchers = Map<ColliderHandle, Record<string, (arg: unknown) => void>>;
53
50
  export type RapierContext = ReturnType<typeof createRapierContext>;
54
51
  export type CollisionGroupsContext = Writable<number> | undefined;
55
52
  export type RigidBodyUserData = {
56
- hasEventListeners?: ReturnType<typeof useHasEventListeners<RigidBodyEventDispatcher>>['hasEventListeners'];
53
+ events?: Record<string, (arg: unknown) => void>;
57
54
  };
58
55
  export type ThrelteRigidBody = RigidBody & {
59
56
  userData?: RigidBodyUserData;
package/package.json CHANGED
@@ -1,38 +1,41 @@
1
1
  {
2
2
  "name": "@threlte/rapier",
3
- "version": "2.0.0",
3
+ "version": "3.0.0-next.1",
4
4
  "author": "Grischa Erbe <hello@legrisch.com> (https://legrisch.com)",
5
5
  "license": "MIT",
6
6
  "devDependencies": {
7
- "@dimforge/rapier3d-compat": "^0.11.2",
8
- "@sveltejs/adapter-auto": "^2.0.0",
9
- "@sveltejs/kit": "^1.20.4",
10
- "@sveltejs/package": "^2.1.0",
11
- "@types/node": "^18.0.3",
12
- "@types/three": "^0.158.3",
13
- "@typescript-eslint/eslint-plugin": "^5.45.0",
14
- "@typescript-eslint/parser": "^5.45.0",
15
- "@yushijinhun/three-minifier-rollup": "^0.3.1",
16
- "eslint": "^8.28.0",
17
- "eslint-config-prettier": "^8.5.0",
18
- "eslint-plugin-svelte": "^2.30.0",
19
- "prettier": "^2.8.8",
20
- "prettier-plugin-svelte": "^2.10.1",
21
- "publint": "^0.1.12",
22
- "rimraf": "^5.0.1",
23
- "svelte-check": "^3.4.3",
24
- "svelte-preprocess": "^5.0.4",
25
- "svelte2tsx": "^0.6.19",
26
- "tslib": "^2.4.1",
27
- "type-fest": "^2.13.0",
28
- "typescript": "^5.0.0",
29
- "vite": "^4.3.6",
30
- "@threlte/core": "7.0.12"
7
+ "@dimforge/rapier3d-compat": "^0.12.0",
8
+ "@sveltejs/adapter-auto": "^3.2.0",
9
+ "@sveltejs/kit": "^2.5.5",
10
+ "@sveltejs/package": "^2.3.1",
11
+ "@sveltejs/vite-plugin-svelte": "^3.1.0",
12
+ "@types/node": "^20.12.7",
13
+ "@types/three": "^0.163.0",
14
+ "@typescript-eslint/eslint-plugin": "^7.6.0",
15
+ "@typescript-eslint/parser": "^7.6.0",
16
+ "@yushijinhun/three-minifier-rollup": "^0.4.0",
17
+ "eslint": "^8.57.0",
18
+ "eslint-config-prettier": "^9.1.0",
19
+ "eslint-plugin-svelte": "^2.36.0",
20
+ "prettier": "^3.2.5",
21
+ "prettier-plugin-svelte": "^3.2.2",
22
+ "publint": "^0.2.7",
23
+ "rimraf": "^5.0.5",
24
+ "svelte": "5.0.0-next.97",
25
+ "svelte-check": "^3.6.9",
26
+ "svelte-preprocess": "^5.1.3",
27
+ "svelte2tsx": "^0.7.6",
28
+ "three": "^0.163.0",
29
+ "tslib": "^2.6.2",
30
+ "type-fest": "^4.15.0",
31
+ "typescript": "^5.4.5",
32
+ "vite": "^5.2.8",
33
+ "@threlte/core": "8.0.0-next.2"
31
34
  },
32
35
  "peerDependencies": {
33
- "svelte": ">=4",
34
- "three": ">=0.133",
35
- "@dimforge/rapier3d-compat": ">=0.11"
36
+ "@dimforge/rapier3d-compat": ">=0.12",
37
+ "svelte": ">=5",
38
+ "three": ">=0.152"
36
39
  },
37
40
  "type": "module",
38
41
  "exports": {