@threlte/rapier 1.1.4 → 3.0.0-next.0

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 (29) hide show
  1. package/dist/components/Attractor/Attractor.svelte +7 -6
  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 +49 -53
  6. package/dist/components/Colliders/Collider.svelte.d.ts +4 -4
  7. package/dist/components/CollisionGroups/CollisionGroups.svelte +1 -1
  8. package/dist/components/Debug/Debug.svelte +2 -2
  9. package/dist/components/RigidBody/RigidBody.svelte +41 -57
  10. package/dist/components/RigidBody/RigidBody.svelte.d.ts +2 -2
  11. package/dist/components/World/InnerWorld.svelte +4 -4
  12. package/dist/components/World/InnerWorld.svelte.d.ts +4 -19
  13. package/dist/components/World/World.svelte +8 -8
  14. package/dist/components/World/World.svelte.d.ts +4 -3
  15. package/dist/hooks/useFrameHandler.d.ts +2 -1
  16. package/dist/hooks/useFrameHandler.js +42 -39
  17. package/dist/hooks/useHasEventListener.js +4 -4
  18. package/dist/lib/applyColliderActiveEvents.d.ts +1 -3
  19. package/dist/lib/applyColliderActiveEvents.js +10 -10
  20. package/dist/lib/createCollidersFromChildren.js +2 -2
  21. package/dist/lib/createRapierContext.d.ts +3 -3
  22. package/dist/lib/createRapierContext.js +4 -4
  23. package/dist/lib/getWorldTransforms.js +1 -1
  24. package/dist/lib/useCreateEvent.d.ts +1 -1
  25. package/dist/lib/useCreateEvent.js +2 -4
  26. package/dist/recipes/BasicPlayerController.svelte +31 -17
  27. package/dist/recipes/BasicPlayerController.svelte.d.ts +5 -2
  28. package/dist/types/types.d.ts +4 -7
  29. package/package.json +31 -27
@@ -1,4 +1,4 @@
1
- <script>import { T, useFrame } 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
4
  export let strength = 1;
@@ -13,14 +13,15 @@ const calcForceByType = {
13
13
  linear: (s, m2, r, d, G) => s * (d / r),
14
14
  newtonian: (s, m2, r, d, G) => (G * s * m2) / Math.pow(d, 2)
15
15
  };
16
+ const impulseVector = new Vector3();
17
+ const bodyV3 = new Vector3();
16
18
  function applyImpulseToBodiesInRange() {
17
- const impulseVector = new Vector3();
18
19
  obj.getWorldPosition(gravitySource);
19
20
  world.forEachRigidBody((body) => {
20
21
  const { x, y, z } = body.translation();
21
- const bodyV3 = new Vector3(x, y, z);
22
- const distance = gravitySource.distanceTo(bodyV3);
23
- if (distance < range) {
22
+ bodyV3.set(x, y, z);
23
+ const distance = gravitySource.distanceToSquared(bodyV3);
24
+ if (distance < range ** 2) {
24
25
  let force = calcForceByType[gravityType](strength, body.mass(), range, distance, gravitationalConstant);
25
26
  // Prevent wild forces when Attractors collide
26
27
  force = force === Infinity ? strength : force;
@@ -29,7 +30,7 @@ function applyImpulseToBodiesInRange() {
29
30
  }
30
31
  });
31
32
  }
32
- useFrame(() => {
33
+ useTask(() => {
33
34
  applyImpulseToBodiesInRange();
34
35
  });
35
36
  </script>
@@ -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, useFrame } 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,51 +64,58 @@ 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.
111
107
  */
112
- const { start, stop } = useFrame(() => {
108
+ const { start, stop } = useTask(() => {
113
109
  refresh();
114
110
  }, {
115
- autostart: !hasRigidBodyParent && type === 'dynamic'
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,4 +1,4 @@
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
4
  export let groups = undefined;
@@ -1,11 +1,11 @@
1
- <script>import { T, useFrame } 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
5
  const { world, debug } = useRapier();
6
6
  const geometry = new BufferGeometry();
7
7
  debug.set(true);
8
- useFrame(() => {
8
+ useTask(() => {
9
9
  const buffers = world.debugRender();
10
10
  const vertices = new BufferAttribute(buffers.vertices, 3);
11
11
  const colors = new BufferAttribute(buffers.colors, 4);
@@ -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,12 +1,12 @@
1
1
  <script
2
2
  context="module"
3
-
3
+ lang="ts"
4
4
  >import { onDestroy, setContext, tick } from 'svelte';
5
5
  import { useFrameHandler } from '../../hooks/useFrameHandler';
6
6
  import { createRapierContext } from '../../lib/createRapierContext';
7
7
  </script>
8
8
 
9
- <script>export let gravity = [0, -9.81, 0];
9
+ <script lang="ts">export let gravity = [0, -9.81, 0];
10
10
  export let rawIntegrationParameters = undefined;
11
11
  export let rawIslands = undefined;
12
12
  export let rawBroadPhase = undefined;
@@ -20,13 +20,13 @@ export let rawQueryPipeline = undefined;
20
20
  export let rawPhysicsPipeline = undefined;
21
21
  export let rawSerializationPipeline = undefined;
22
22
  export let rawDebugRenderPipeline = undefined;
23
- export let order = undefined;
23
+ export let stage = undefined;
24
24
  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
25
  setContext('threlte-rapier-context', rapierContext);
26
26
  $: if (gravity !== undefined) {
27
27
  rapierContext.world.gravity = { x: gravity[0], y: gravity[1], z: gravity[2] };
28
28
  }
29
- useFrameHandler(rapierContext, order);
29
+ useFrameHandler(rapierContext, stage);
30
30
  onDestroy(async () => {
31
31
  await tick();
32
32
  rapierContext.world.free();
@@ -1,22 +1,7 @@
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
- order?: number | undefined;
19
- };
4
+ props: WorldProps;
20
5
  events: {
21
6
  [evt: string]: CustomEvent<any>;
22
7
  };
@@ -27,6 +12,6 @@ declare const __propDef: {
27
12
  export type InnerWorldProps = typeof __propDef.props;
28
13
  export type InnerWorldEvents = typeof __propDef.events;
29
14
  export type InnerWorldSlots = typeof __propDef.slots;
30
- export default class InnerWorld extends SvelteComponentTyped<InnerWorldProps, InnerWorldEvents, InnerWorldSlots> {
15
+ export default class InnerWorld extends SvelteComponent<InnerWorldProps, InnerWorldEvents, InnerWorldSlots> {
31
16
  }
32
17
  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,7 +10,7 @@ import { writable } from 'svelte/store';
10
10
  const initialized = writable(false);
11
11
  </script>
12
12
 
13
- <script>import InnerWorld from './InnerWorld.svelte';
13
+ <script lang="ts">import InnerWorld from './InnerWorld.svelte';
14
14
  // self
15
15
  export let gravity = undefined;
16
16
  export let rawIntegrationParameters = undefined;
@@ -27,11 +27,11 @@ export let rawPhysicsPipeline = undefined;
27
27
  export let rawSerializationPipeline = undefined;
28
28
  export let rawDebugRenderPipeline = undefined;
29
29
  /**
30
- * The property order is passed to the useFrame handler.
31
- * Use this to control when the rapier physics engine is updating the scene.
32
- * @default undefined
33
- */
34
- export let order = undefined;
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
35
  let error = false;
36
36
  const init = async () => {
37
37
  if ($initialized)
@@ -63,7 +63,7 @@ onMount(init);
63
63
  {rawPhysicsPipeline}
64
64
  {rawSerializationPipeline}
65
65
  {rawDebugRenderPipeline}
66
- {order}
66
+ {stage}
67
67
  >
68
68
  <slot />
69
69
  </InnerWorld>
@@ -13,8 +13,9 @@ import type {
13
13
  RawRigidBodySet,
14
14
  RawSerializationPipeline
15
15
  } from '@dimforge/rapier3d-compat/raw'
16
- import { SvelteComponentTyped } from 'svelte'
16
+ import { SvelteComponent } from 'svelte'
17
17
  import type { Vector3 } from 'three'
18
+ import type { Key, Stage } from '@threlte/core'
18
19
 
19
20
  export type WorldProps = {
20
21
  gravity?: Parameters<Vector3['set']>
@@ -31,7 +32,7 @@ export type WorldProps = {
31
32
  rawPhysicsPipeline?: RawPhysicsPipeline
32
33
  rawSerializationPipeline?: RawSerializationPipeline
33
34
  rawDebugRenderPipeline?: RawDebugRenderPipeline
34
- order?: number
35
+ stage?: Key | Stage
35
36
  }
36
37
 
37
- export default class World extends SvelteComponentTyped<WorldProps> {}
38
+ export default class World extends SvelteComponent<WorldProps> {}
@@ -1,2 +1,3 @@
1
+ import { type Stage, type Key } from '@threlte/core';
1
2
  import type { RapierContext } from '../types/types';
2
- export declare const useFrameHandler: (ctx: RapierContext, order?: number) => void;
3
+ export declare const useFrameHandler: (ctx: RapierContext, stage?: Stage | Key) => void;
@@ -1,31 +1,31 @@
1
- import { Collider, EventQueue } from '@dimforge/rapier3d-compat';
2
- import { useFrame } from '@threlte/core';
1
+ import { EventQueue } from '@dimforge/rapier3d-compat';
2
+ import { useTask } from '@threlte/core';
3
3
  import { derived } from 'svelte/store';
4
4
  import { Object3D, Quaternion, Vector3 } from 'three';
5
5
  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
- export const useFrameHandler = (ctx, order) => {
26
+ export const useFrameHandler = (ctx, stage) => {
27
27
  const eventQueue = new EventQueue(false);
28
- const { start, started, stop } = useFrame((_, delta) => {
28
+ const { start, started, stop } = useTask((delta) => {
29
29
  // if (!eventQueue) return
30
30
  const { world } = ctx;
31
31
  // Set timestep to current delta, to allow for variable frame rates
@@ -37,15 +37,15 @@ export const useFrameHandler = (ctx, order) => {
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, order) => {
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, order) => {
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, order) => {
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, order) => {
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,7 +121,10 @@ export const useFrameHandler = (ctx, order) => {
121
121
  if (!collider1 || !collider2) {
122
122
  return;
123
123
  }
124
- const { colliderDispatcher1, colliderDispatcher2, rigidBodyDispatcher1, rigidBodyDispatcher2 } = getEventDispatchers(ctx, collider1, collider2);
124
+ const { collider1Events, collider2Events, rigidBody1Events, rigidBody2Events } = getEventDispatchers(ctx, collider1, collider2);
125
+ if (!collider1Events && !collider2Events && !rigidBody1Events && !rigidBody2Events) {
126
+ return;
127
+ }
125
128
  const rigidBody1 = collider1.parent();
126
129
  const rigidBody2 = collider2.parent();
127
130
  if (started) {
@@ -129,20 +132,20 @@ export const useFrameHandler = (ctx, order) => {
129
132
  const isIntersection = world.intersectionPair(collider1, collider2);
130
133
  if (isIntersection) {
131
134
  // Collider Events
132
- colliderDispatcher1?.('sensorenter', {
135
+ collider1Events?.sensorenter?.({
133
136
  targetCollider: collider2,
134
137
  targetRigidBody: rigidBody2
135
138
  });
136
- colliderDispatcher2?.('sensorenter', {
139
+ collider2Events?.sensorenter?.({
137
140
  targetCollider: collider1,
138
141
  targetRigidBody: rigidBody1
139
142
  });
140
143
  // RigidBody Events
141
- rigidBodyDispatcher1?.('sensorenter', {
144
+ rigidBody1Events?.sensorenter?.({
142
145
  targetCollider: collider2,
143
146
  targetRigidBody: rigidBody2
144
147
  });
145
- rigidBodyDispatcher2?.('sensorenter', {
148
+ rigidBody2Events?.sensorenter?.({
146
149
  targetCollider: collider1,
147
150
  targetRigidBody: rigidBody1
148
151
  });
@@ -151,26 +154,26 @@ export const useFrameHandler = (ctx, order) => {
151
154
  }
152
155
  world.contactPair(collider1, collider2, (manifold, flipped) => {
153
156
  // Collider events
154
- colliderDispatcher1?.('collisionenter', {
157
+ collider1Events?.collisionenter?.({
155
158
  flipped,
156
159
  manifold,
157
160
  targetCollider: collider2,
158
161
  targetRigidBody: rigidBody2
159
162
  });
160
- colliderDispatcher2?.('collisionenter', {
163
+ collider2Events?.collisionenter?.({
161
164
  flipped,
162
165
  manifold,
163
166
  targetCollider: collider1,
164
167
  targetRigidBody: rigidBody1
165
168
  });
166
169
  // RigidBody Events
167
- rigidBodyDispatcher1?.('collisionenter', {
170
+ rigidBody1Events?.collisionenter?.({
168
171
  flipped,
169
172
  manifold,
170
173
  targetCollider: collider2,
171
174
  targetRigidBody: rigidBody2
172
175
  });
173
- rigidBodyDispatcher2?.('collisionenter', {
176
+ rigidBody2Events?.collisionenter?.({
174
177
  flipped,
175
178
  manifold,
176
179
  targetCollider: collider1,
@@ -185,20 +188,20 @@ export const useFrameHandler = (ctx, order) => {
185
188
  collider1.isSensor() ||
186
189
  collider2.isSensor();
187
190
  if (isIntersection) {
188
- colliderDispatcher1?.('sensorexit', {
191
+ collider1Events?.sensorexit?.({
189
192
  targetCollider: collider2,
190
193
  targetRigidBody: rigidBody2
191
194
  });
192
- colliderDispatcher2?.('sensorexit', {
195
+ collider2Events?.sensorexit?.({
193
196
  targetCollider: collider1,
194
197
  targetRigidBody: rigidBody1
195
198
  });
196
199
  // RigidBody Events
197
- rigidBodyDispatcher1?.('sensorexit', {
200
+ rigidBody1Events?.sensorexit?.({
198
201
  targetCollider: collider2,
199
202
  targetRigidBody: rigidBody2
200
203
  });
201
- rigidBodyDispatcher2?.('sensorexit', {
204
+ rigidBody2Events?.sensorexit?.({
202
205
  targetCollider: collider1,
203
206
  targetRigidBody: rigidBody1
204
207
  });
@@ -206,26 +209,26 @@ export const useFrameHandler = (ctx, order) => {
206
209
  return;
207
210
  }
208
211
  // Collider events
209
- colliderDispatcher1?.('collisionexit', {
212
+ collider1Events?.collisionexit?.({
210
213
  targetCollider: collider2,
211
214
  targetRigidBody: rigidBody2
212
215
  });
213
- colliderDispatcher2?.('collisionexit', {
216
+ collider2Events?.collisionexit?.({
214
217
  targetCollider: collider1,
215
218
  targetRigidBody: rigidBody1
216
219
  });
217
220
  // RigidBody Events
218
- rigidBodyDispatcher1?.('collisionexit', {
221
+ rigidBody1Events?.collisionexit?.({
219
222
  targetCollider: collider2,
220
223
  targetRigidBody: rigidBody2
221
224
  });
222
- rigidBodyDispatcher2?.('collisionexit', {
225
+ rigidBody2Events?.collisionexit?.({
223
226
  targetCollider: collider1,
224
227
  targetRigidBody: rigidBody1
225
228
  });
226
229
  }
227
230
  });
228
- }, { order });
231
+ }, { stage });
229
232
  // replacing the original pause and resume functions as well as the paused property
230
233
  ctx.pause = () => stop();
231
234
  ctx.resume = () => start();
@@ -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, useFrame } 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';
@@ -29,10 +29,8 @@ $: {
29
29
  grounded = true;
30
30
  }
31
31
  $: grounded ? dispatch('groundenter') : dispatch('groundexit');
32
- useFrame(() => {
33
- if (!rigidBody)
34
- return;
35
- t.fromArray([0, 0, 0]);
32
+ const { start } = useTask(() => {
33
+ t.set(0, 0, 0);
36
34
  if (keys.down)
37
35
  t.x += 1;
38
36
  if (keys.up)
@@ -53,18 +51,24 @@ useFrame(() => {
53
51
  t.y = linVel.y;
54
52
  rigidBody.setLinvel(t, true);
55
53
  });
54
+ $: if (rigidBody)
55
+ start();
56
56
  const onKeyDown = (e) => {
57
- switch (e.key) {
58
- case 'ArrowDown':
57
+ switch (e.key.toLowerCase()) {
58
+ case 's':
59
+ case 'arrowdown':
59
60
  keys.down = true;
60
61
  break;
61
- case 'ArrowUp':
62
+ case 'w':
63
+ case 'arrowup':
62
64
  keys.up = true;
63
65
  break;
64
- case 'ArrowLeft':
66
+ case 'a':
67
+ case 'arrowleft':
65
68
  keys.left = true;
66
69
  break;
67
- case 'ArrowRight':
70
+ case 'd':
71
+ case 'arrowright':
68
72
  keys.right = true;
69
73
  break;
70
74
  case ' ':
@@ -76,17 +80,21 @@ const onKeyDown = (e) => {
76
80
  }
77
81
  };
78
82
  const onKeyUp = (e) => {
79
- switch (e.key) {
80
- case 'ArrowDown':
83
+ switch (e.key.toLowerCase()) {
84
+ case 's':
85
+ case 'arrowdown':
81
86
  keys.down = false;
82
87
  break;
83
- case 'ArrowUp':
88
+ case 'w':
89
+ case 'arrowup':
84
90
  keys.up = false;
85
91
  break;
86
- case 'ArrowLeft':
92
+ case 'a':
93
+ case 'arrowleft':
87
94
  keys.left = false;
88
95
  break;
89
- case 'ArrowRight':
96
+ case 'd':
97
+ case 'arrowright':
90
98
  keys.right = false;
91
99
  break;
92
100
  default:
@@ -95,7 +103,10 @@ const onKeyUp = (e) => {
95
103
  };
96
104
  </script>
97
105
 
98
- <svelte:window on:keydown|preventDefault={onKeyDown} on:keyup|preventDefault={onKeyUp} />
106
+ <svelte:window
107
+ on:keydown|preventDefault={onKeyDown}
108
+ on:keyup|preventDefault={onKeyUp}
109
+ />
99
110
 
100
111
  <T.Group {position}>
101
112
  <RigidBody
@@ -105,7 +116,10 @@ const onKeyUp = (e) => {
105
116
  type={'dynamic'}
106
117
  >
107
118
  <CollisionGroups groups={playerCollisionGroups}>
108
- <Collider shape={'capsule'} args={[height / 2 - radius, radius]} />
119
+ <Collider
120
+ shape={'capsule'}
121
+ args={[height / 2 - radius, radius]}
122
+ />
109
123
  </CollisionGroups>
110
124
 
111
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": "1.1.4",
3
+ "version": "3.0.0-next.0",
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.4"
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.0.2",
12
+ "@types/node": "^20.12.4",
13
+ "@types/three": "^0.163.0",
14
+ "@typescript-eslint/eslint-plugin": "^7.5.0",
15
+ "@typescript-eslint/parser": "^7.5.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.35.1",
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.94",
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.4",
32
+ "vite": "^5.2.8",
33
+ "@threlte/core": "8.0.0-next.0"
31
34
  },
32
35
  "peerDependencies": {
36
+ "@dimforge/rapier3d-compat": ">=0.11",
33
37
  "svelte": ">=4",
34
- "three": ">=0.133",
35
- "@dimforge/rapier3d-compat": ">=0.11"
38
+ "three": ">=0.152"
36
39
  },
37
40
  "type": "module",
38
41
  "exports": {
@@ -47,6 +50,7 @@
47
50
  "dist"
48
51
  ],
49
52
  "scripts": {
53
+ "dev": "vite dev",
50
54
  "package": "svelte-kit sync && svelte-package && node ./scripts/cleanupPackage.js && publint",
51
55
  "check": "svelte-check --tsconfig ./tsconfig.json",
52
56
  "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",