@threlte/rapier 3.0.0-next.1 → 3.0.0-next.3

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.
@@ -1,7 +1,7 @@
1
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
- let { strength = 1, range = 50, gravityType = 'static', gravitationalConstant = 6.673e-11, ref = $bindable(), ...props } = $props();
4
+ let { strength = 1, range = 50, gravityType = 'static', gravitationalConstant = 6.673e-11, ref = $bindable(), children, ...props } = $props();
5
5
  const { world, debug } = useRapier();
6
6
  const gravitySource = new Vector3();
7
7
  const group = new Group();
@@ -37,7 +37,7 @@ useTask(() => {
37
37
  bind:ref
38
38
  {...props}
39
39
  >
40
- <slot ref={group} />
40
+ {@render children?.({ ref: group })}
41
41
 
42
42
  {#if $debug}
43
43
  <T.Mesh>
@@ -1,4 +1,4 @@
1
- import { Props, type Events, type Slots } from '@threlte/core'
1
+ import { Props } from '@threlte/core'
2
2
  import { SvelteComponent } from 'svelte'
3
3
  import type { Group } from 'three'
4
4
  import type { GravityType } from '../../types/types'
@@ -31,12 +31,4 @@ type AttractorProps = Props<Group> & {
31
31
  gravitationalConstant?: number
32
32
  }
33
33
 
34
- type AttractorEvents = Events<Group>
35
-
36
- type AttractorSlots = Slots<Group>
37
-
38
- export default class Attractor extends SvelteComponent<
39
- AttractorProps,
40
- AttractorEvents,
41
- AttractorSlots
42
- > {}
34
+ export default class Attractor extends SvelteComponent<AttractorProps> {}
@@ -10,9 +10,9 @@ import { useParentRigidbodyObject } from '../../lib/rigidBodyObjectContext';
10
10
  import { applyColliderActiveEvents } from '../../lib/applyColliderActiveEvents';
11
11
  import { createCollidersFromChildren } from '../../lib/createCollidersFromChildren';
12
12
  import { eulerToQuaternion } from '../../lib/eulerToQuaternion';
13
- let { shape = 'convexHull', restitution, restitutionCombineRule, friction, frictionCombineRule, sensor, contactForceEventThreshold, density, mass, centerOfMass, principalAngularInertia, angularInertiaLocalFrame, refresh = $bindable(() => create()), colliders = $bindable(), ...props } = $props();
13
+ let { shape = 'convexHull', restitution, restitutionCombineRule, friction, frictionCombineRule, sensor, contactForceEventThreshold, density, mass, centerOfMass, principalAngularInertia, angularInertiaLocalFrame, refresh = $bindable(() => create()), colliders = $bindable(), oncreate, oncollisionenter, oncollisionexit, oncontact, onsensorenter, onsensorexit, children, } = $props();
14
14
  const group = new Group();
15
- const { updateRef } = useCreateEvent(props.$$events);
15
+ const { updateRef } = useCreateEvent(oncreate);
16
16
  const rigidBody = useRigidBody();
17
17
  const rigidBodyParentObject = useParentRigidbodyObject();
18
18
  const { world, addColliderToContext, removeColliderFromContext } = useRapier();
@@ -27,13 +27,20 @@ const cleanup = () => {
27
27
  });
28
28
  colliders.length = 0;
29
29
  };
30
+ const events = {
31
+ oncollisionenter,
32
+ oncollisionexit,
33
+ oncontact,
34
+ onsensorenter,
35
+ onsensorexit
36
+ };
30
37
  const create = () => {
31
38
  cleanup();
32
39
  colliders = createCollidersFromChildren(group, shape ?? 'convexHull', world, rigidBody, rigidBodyParentObject);
33
- colliders.forEach((c) => addColliderToContext(c, group, props.$$events));
40
+ colliders.forEach((c) => addColliderToContext(c, group, events));
34
41
  collisionGroups.registerColliders(colliders);
35
42
  colliders.forEach((collider) => {
36
- applyColliderActiveEvents(collider, props.$$events, rigidBody?.userData?.events);
43
+ applyColliderActiveEvents(collider, events, rigidBody?.userData?.events);
37
44
  collider.setActiveCollisionTypes(ActiveCollisionTypes.ALL);
38
45
  collider.setRestitution(restitution ?? 0);
39
46
  collider.setRestitutionCombineRule(restitutionCombineRule ?? CoefficientCombineRule.Average);
@@ -66,8 +73,5 @@ onDestroy(cleanup);
66
73
  </script>
67
74
 
68
75
  <SceneGraphObject object={group}>
69
- <slot
70
- {colliders}
71
- {refresh}
72
- />
76
+ {@render children?.({ colliders: colliders ?? [], refresh })}
73
77
  </SceneGraphObject>
@@ -1,7 +1,7 @@
1
1
  import type { CoefficientCombineRule, Collider } from '@dimforge/rapier3d-compat'
2
- import { SvelteComponent } from 'svelte'
2
+ import { SvelteComponent, type Snippet } from 'svelte'
3
3
  import type { Euler, Vector3 } from 'three'
4
- import type { AutoCollidersShapes, ColliderEventMap } from '../../types/types'
4
+ import type { AutoCollidersShapes, ColliderEvents } from '../../types/types'
5
5
 
6
6
  // ------------------ BASE ------------------
7
7
 
@@ -14,7 +14,10 @@ type BaseProps = {
14
14
  sensor?: boolean
15
15
  colliders?: Collider[]
16
16
  contactForceEventThreshold?: number
17
+
17
18
  refresh?: () => void
19
+
20
+ oncreate?: () => void
18
21
  }
19
22
 
20
23
  // ------------------ MASS ------------------
@@ -64,17 +67,18 @@ type MassProps<TMassDef extends MassDef> = TMassDef extends Density
64
67
 
65
68
  // ------------------ COLLIDER ------------------
66
69
 
67
- export type AutoCollidersProps<TMassDef extends MassDef> = BaseProps & MassProps<TMassDef>
68
-
69
- type AutoCollidersSlots = {
70
- default: {
71
- colliders: Collider[]
72
- refresh: () => void
70
+ export type AutoCollidersProps<TMassDef extends MassDef> = BaseProps &
71
+ MassProps<TMassDef> & {
72
+ children?: Snippet<
73
+ [
74
+ {
75
+ colliders: Collider[]
76
+ refresh: () => void
77
+ }
78
+ ]
79
+ >
73
80
  }
74
- }
75
81
 
76
82
  export default class AutoColliders<TMassDef extends MassDef> extends SvelteComponent<
77
- AutoCollidersProps<TMassDef>,
78
- ColliderEventMap,
79
- AutoCollidersSlots
83
+ AutoCollidersProps<TMassDef>
80
84
  > {}
@@ -16,15 +16,22 @@ let { shape, args, type, restitution, restitutionCombineRule, friction, friction
16
16
  return;
17
17
  collider.setTranslation(getWorldPosition(object));
18
18
  collider.setRotation(getWorldQuaternion(object));
19
- }), ...props } = $props();
19
+ }), oncreate, oncollisionenter, oncollisionexit, oncontact, onsensorenter, onsensorexit, children, } = $props();
20
20
  const object = new Object3D();
21
- const { updateRef } = useCreateEvent(props.$$events);
21
+ const { updateRef } = useCreateEvent(oncreate);
22
22
  const rigidBody = useRigidBody();
23
23
  const parentRigidBodyObject = useParentRigidbodyObject();
24
24
  const hasRigidBodyParent = !!rigidBody;
25
25
  const rapierContext = useRapier();
26
26
  const { world } = rapierContext;
27
27
  const collisionGroups = useCollisionGroups();
28
+ const events = {
29
+ oncollisionenter,
30
+ oncollisionexit,
31
+ oncontact,
32
+ onsensorenter,
33
+ onsensorexit
34
+ };
28
35
  /**
29
36
  * Actual collider setup happens onMount as only then
30
37
  * the transforms are finished.
@@ -41,7 +48,7 @@ onMount(async () => {
41
48
  /**
42
49
  * Add collider to context
43
50
  */
44
- rapierContext.addColliderToContext(collider, object, props.$$events);
51
+ rapierContext.addColliderToContext(collider, object, events);
45
52
  /**
46
53
  * For use in conjunction with component <CollisionGroups>
47
54
  */
@@ -98,7 +105,7 @@ $effect.pre(() => {
98
105
  });
99
106
  $effect.pre(() => {
100
107
  if (collider) {
101
- applyColliderActiveEvents(collider, props.$$events, rigidBody?.userData?.events);
108
+ applyColliderActiveEvents(collider, events, rigidBody?.userData?.events);
102
109
  }
103
110
  });
104
111
  /**
@@ -130,5 +137,5 @@ onDestroy(() => {
130
137
  </script>
131
138
 
132
139
  <SceneGraphObject {object}>
133
- <slot {collider} />
140
+ {@render children?.({ collider })}
134
141
  </SceneGraphObject>
@@ -1,11 +1,11 @@
1
+ import type { ColliderEvents } from '../../types/types'
1
2
  import type {
2
3
  CoefficientCombineRule,
3
4
  Collider as RapierCollider,
4
5
  ColliderDesc
5
6
  } from '@dimforge/rapier3d-compat'
6
- import { SvelteComponent } from 'svelte'
7
+ import { SvelteComponent, type Snippet } from 'svelte'
7
8
  import type { Euler, Vector3 } from 'three'
8
- import type { ColliderEventMap } from '../../types/types'
9
9
 
10
10
  // ------------------ BASE ------------------
11
11
 
@@ -97,16 +97,13 @@ type MassProps<TMassDef extends MassDef> = TMassDef extends Density
97
97
  // ------------------ COLLIDER ------------------
98
98
 
99
99
  export type ColliderProps<TShape extends Shape, TMassDef extends MassDef> = BaseProps &
100
+ ColliderEvents &
100
101
  ShapeProps<TShape> &
101
- MassProps<TMassDef>
102
-
103
- export type ColliderSlots = {
104
- default: {
105
- collider: RapierCollider
102
+ MassProps<TMassDef> & {
103
+ children?: Snippet<[{ collider?: RapierCollider }]>
106
104
  }
107
- }
108
105
 
109
106
  export default class Collider<
110
107
  TShape extends Shape,
111
108
  TMassDef extends MassDef
112
- > extends SvelteComponent<ColliderProps<TShape, TMassDef>, ColliderEventMap, ColliderSlots> {}
109
+ > extends SvelteComponent<ColliderProps<TShape, TMassDef>> {}
@@ -1,10 +1,10 @@
1
1
  <script lang="ts">import { setContext } from 'svelte';
2
2
  import { writable } from 'svelte/store';
3
3
  import { computeBitMask } from '../../lib/computeBitMask';
4
- let { groups, filter, memberships } = $props();
4
+ let { groups, filter, memberships, children } = $props();
5
5
  const store = writable(computeBitMask(groups, filter, memberships));
6
6
  $effect.pre(() => store.set(computeBitMask(groups, filter, memberships)));
7
7
  setContext('threlte-rapier-collision-group', store);
8
8
  </script>
9
9
 
10
- <slot />
10
+ {@render children?.()}
@@ -1,4 +1,4 @@
1
- import { SvelteComponent } from 'svelte'
1
+ import { SvelteComponent, type Snippet } from 'svelte'
2
2
 
3
3
  type N = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15
4
4
 
@@ -11,6 +11,8 @@ type GroupsProps = {
11
11
 
12
12
  filter?: never
13
13
  memberships?: never
14
+
15
+ children?: Snippet
14
16
  }
15
17
 
16
18
  type MembershipsAndFilterProps = {
@@ -18,6 +20,8 @@ type MembershipsAndFilterProps = {
18
20
  memberships: N[]
19
21
 
20
22
  groups?: never
23
+
24
+ children?: Snippet
21
25
  }
22
26
 
23
27
  type GroupsDef = GroupsProps | MembershipsAndFilterProps
@@ -7,8 +7,11 @@ import { parseRigidBodyType } from '../../lib/parseRigidBodyType';
7
7
  import { setParentRigidbodyObject } from '../../lib/rigidBodyObjectContext';
8
8
  import { useCreateEvent } from '../../lib/useCreateEvent';
9
9
  const { world, rapier, addRigidBodyToContext, removeRigidBodyFromContext } = useRapier();
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);
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(), oncreate, oncollisionenter, oncollisionexit, oncontact, onsensorenter, onsensorexit, onsleep, onwake } = $props();
11
+ /**
12
+ * Every RigidBody receives and forwards collision-related events
13
+ */
14
+ const { updateRef } = useCreateEvent(oncreate);
12
15
  const object = new Object3D();
13
16
  /**
14
17
  * isSleeping used for events "sleep" and "wake" in `useFrameHandler`
@@ -68,7 +71,15 @@ $effect.pre(() => rigidBodyInternal.setEnabled(enabled));
68
71
  */
69
72
  $effect.pre(() => {
70
73
  rigidBodyInternal.userData = {
71
- events: props.$$events,
74
+ events: {
75
+ oncollisionenter,
76
+ oncollisionexit,
77
+ oncontact,
78
+ onsensorenter,
79
+ onsensorexit,
80
+ onsleep,
81
+ onwake
82
+ },
72
83
  ...userData
73
84
  };
74
85
  });
@@ -84,7 +95,15 @@ setParentRigidbodyObject(object);
84
95
  /**
85
96
  * Add the mesh to the context
86
97
  */
87
- addRigidBodyToContext(rigidBodyInternal, object, props.$$events);
98
+ addRigidBodyToContext(rigidBodyInternal, object, {
99
+ oncollisionenter,
100
+ oncollisionexit,
101
+ oncontact,
102
+ onsensorenter,
103
+ onsensorexit,
104
+ onsleep,
105
+ onwake
106
+ });
88
107
  /**
89
108
  * cleanup
90
109
  */
@@ -1,13 +1,13 @@
1
1
  import { RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat'
2
- import { SvelteComponent } from 'svelte'
2
+ import { SvelteComponent, type Snippet } from 'svelte'
3
3
  import type { Euler, Vector3 } from 'three'
4
4
  import type { RigidBodyTypeString } from '../../lib/parseRigidBodyType'
5
- import type { RigidBodyEventMap } from '../../types/types'
5
+ import type { RigidBodyEvents } from '../../types/types'
6
6
 
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
@@ -95,18 +95,8 @@ export type RigidBodyProps = {
95
95
  * An arbitrary user-defined object associated with this rigid-body.
96
96
  */
97
97
  userData?: Record<string, any>
98
- }
99
-
100
- type RigidBodyEvents = RigidBodyEventMap
101
98
 
102
- type RigidBodySlots = {
103
- default: {
104
- rigidBody: RapierRigidBody
105
- }
99
+ children?: Snippet<[{ rigidBody: RapierRigidBody }]>
106
100
  }
107
101
 
108
- export default class RigidBody extends SvelteComponent<
109
- RigidBodyProps,
110
- RigidBodyEvents,
111
- RigidBodySlots
112
- > {}
102
+ export default class RigidBody extends SvelteComponent<RigidBodyProps & RigidBodyEvents> {}
@@ -17,7 +17,7 @@ let { gravity, rawIntegrationParameters, rawIslands, rawBroadPhase, rawNarrowPha
17
17
  * Use this to control when the rapier physics engine is updating the scene.
18
18
  * @default undefined
19
19
  */
20
- stage } = $props();
20
+ stage, fallback, children } = $props();
21
21
  let error = $state(false);
22
22
  const init = async () => {
23
23
  if ($initialized)
@@ -51,10 +51,10 @@ onMount(init);
51
51
  {rawDebugRenderPipeline}
52
52
  {stage}
53
53
  >
54
- <slot />
54
+ {@render children?.()}
55
55
  </InnerWorld>
56
56
  {/if}
57
57
 
58
58
  {#if error}
59
- <slot name="fallback" />
59
+ {@render fallback?.()}
60
60
  {/if}
@@ -13,7 +13,7 @@ import type {
13
13
  RawRigidBodySet,
14
14
  RawSerializationPipeline
15
15
  } from '@dimforge/rapier3d-compat/raw'
16
- import { SvelteComponent } from 'svelte'
16
+ import { SvelteComponent, type Snippet } from 'svelte'
17
17
  import type { Vector3 } from 'three'
18
18
  import type { Key, Stage } from '@threlte/core'
19
19
 
@@ -33,6 +33,9 @@ export type WorldProps = {
33
33
  rawSerializationPipeline?: RawSerializationPipeline
34
34
  rawDebugRenderPipeline?: RawDebugRenderPipeline
35
35
  stage?: Key | Stage
36
+
37
+ children?: Snippet
38
+ fallback?: Snippet
36
39
  }
37
40
 
38
41
  export default class World extends SvelteComponent<WorldProps> {}
@@ -35,21 +35,19 @@ export const useFrameHandler = (ctx, stage) => {
35
35
  // Update meshes
36
36
  ctx.rigidBodyObjects.forEach((mesh, handle) => {
37
37
  const rigidBody = world.getRigidBody(handle);
38
- if (!rigidBody)
39
- return;
40
- const events = ctx.rigidBodyEventDispatchers.get(handle);
41
38
  if (!rigidBody || !rigidBody.isValid())
42
39
  return;
40
+ const events = ctx.rigidBodyEventDispatchers.get(handle);
43
41
  if (events) {
44
42
  if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
45
- events.sleep?.();
43
+ events.onsleep?.();
46
44
  }
47
45
  if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
48
- events.wake?.();
46
+ events.onwake?.();
49
47
  }
50
48
  mesh.userData.isSleeping = rigidBody.isSleeping();
51
49
  }
52
- if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
50
+ if (rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
53
51
  return;
54
52
  }
55
53
  // Position
@@ -79,7 +77,7 @@ export const useFrameHandler = (ctx, stage) => {
79
77
  const rigidBody1 = collider1.parent();
80
78
  const rigidBody2 = collider2.parent();
81
79
  // Collider events
82
- collider1Events?.contact?.({
80
+ collider1Events?.oncontact?.({
83
81
  targetCollider: collider2,
84
82
  targetRigidBody: rigidBody2,
85
83
  maxForceDirection: e.maxForceDirection(),
@@ -87,7 +85,7 @@ export const useFrameHandler = (ctx, stage) => {
87
85
  totalForce: e.totalForce(),
88
86
  totalForceMagnitude: e.totalForceMagnitude()
89
87
  });
90
- collider2Events?.contact?.({
88
+ collider2Events?.oncontact?.({
91
89
  targetCollider: collider1,
92
90
  targetRigidBody: rigidBody1,
93
91
  maxForceDirection: e.maxForceDirection(),
@@ -96,7 +94,7 @@ export const useFrameHandler = (ctx, stage) => {
96
94
  totalForceMagnitude: e.totalForceMagnitude()
97
95
  });
98
96
  // RigidBody Events
99
- rigidBody1Events?.contact?.({
97
+ rigidBody1Events?.oncontact?.({
100
98
  targetCollider: collider2,
101
99
  targetRigidBody: rigidBody2,
102
100
  maxForceDirection: e.maxForceDirection(),
@@ -104,7 +102,7 @@ export const useFrameHandler = (ctx, stage) => {
104
102
  totalForce: e.totalForce(),
105
103
  totalForceMagnitude: e.totalForceMagnitude()
106
104
  });
107
- rigidBody2Events?.contact?.({
105
+ rigidBody2Events?.oncontact?.({
108
106
  targetCollider: collider1,
109
107
  targetRigidBody: rigidBody1,
110
108
  maxForceDirection: e.maxForceDirection(),
@@ -132,20 +130,20 @@ export const useFrameHandler = (ctx, stage) => {
132
130
  const isIntersection = world.intersectionPair(collider1, collider2);
133
131
  if (isIntersection) {
134
132
  // Collider Events
135
- collider1Events?.sensorenter?.({
133
+ collider1Events?.onsensorenter?.({
136
134
  targetCollider: collider2,
137
135
  targetRigidBody: rigidBody2
138
136
  });
139
- collider2Events?.sensorenter?.({
137
+ collider2Events?.onsensorenter?.({
140
138
  targetCollider: collider1,
141
139
  targetRigidBody: rigidBody1
142
140
  });
143
141
  // RigidBody Events
144
- rigidBody1Events?.sensorenter?.({
142
+ rigidBody1Events?.onsensorenter?.({
145
143
  targetCollider: collider2,
146
144
  targetRigidBody: rigidBody2
147
145
  });
148
- rigidBody2Events?.sensorenter?.({
146
+ rigidBody2Events?.onsensorenter?.({
149
147
  targetCollider: collider1,
150
148
  targetRigidBody: rigidBody1
151
149
  });
@@ -154,26 +152,26 @@ export const useFrameHandler = (ctx, stage) => {
154
152
  }
155
153
  world.contactPair(collider1, collider2, (manifold, flipped) => {
156
154
  // Collider events
157
- collider1Events?.collisionenter?.({
155
+ collider1Events?.oncollisionenter?.({
158
156
  flipped,
159
157
  manifold,
160
158
  targetCollider: collider2,
161
159
  targetRigidBody: rigidBody2
162
160
  });
163
- collider2Events?.collisionenter?.({
161
+ collider2Events?.oncollisionenter?.({
164
162
  flipped,
165
163
  manifold,
166
164
  targetCollider: collider1,
167
165
  targetRigidBody: rigidBody1
168
166
  });
169
167
  // RigidBody Events
170
- rigidBody1Events?.collisionenter?.({
168
+ rigidBody1Events?.oncollisionenter?.({
171
169
  flipped,
172
170
  manifold,
173
171
  targetCollider: collider2,
174
172
  targetRigidBody: rigidBody2
175
173
  });
176
- rigidBody2Events?.collisionenter?.({
174
+ rigidBody2Events?.oncollisionenter?.({
177
175
  flipped,
178
176
  manifold,
179
177
  targetCollider: collider1,
@@ -188,20 +186,20 @@ export const useFrameHandler = (ctx, stage) => {
188
186
  collider1.isSensor() ||
189
187
  collider2.isSensor();
190
188
  if (isIntersection) {
191
- collider1Events?.sensorexit?.({
189
+ collider1Events?.onsensorexit?.({
192
190
  targetCollider: collider2,
193
191
  targetRigidBody: rigidBody2
194
192
  });
195
- collider2Events?.sensorexit?.({
193
+ collider2Events?.onsensorexit?.({
196
194
  targetCollider: collider1,
197
195
  targetRigidBody: rigidBody1
198
196
  });
199
197
  // RigidBody Events
200
- rigidBody1Events?.sensorexit?.({
198
+ rigidBody1Events?.onsensorexit?.({
201
199
  targetCollider: collider2,
202
200
  targetRigidBody: rigidBody2
203
201
  });
204
- rigidBody2Events?.sensorexit?.({
202
+ rigidBody2Events?.onsensorexit?.({
205
203
  targetCollider: collider1,
206
204
  targetRigidBody: rigidBody1
207
205
  });
@@ -209,20 +207,20 @@ export const useFrameHandler = (ctx, stage) => {
209
207
  return;
210
208
  }
211
209
  // Collider events
212
- collider1Events?.collisionexit?.({
210
+ collider1Events?.oncollisionexit?.({
213
211
  targetCollider: collider2,
214
212
  targetRigidBody: rigidBody2
215
213
  });
216
- collider2Events?.collisionexit?.({
214
+ collider2Events?.oncollisionexit?.({
217
215
  targetCollider: collider1,
218
216
  targetRigidBody: rigidBody1
219
217
  });
220
218
  // RigidBody Events
221
- rigidBody1Events?.collisionexit?.({
219
+ rigidBody1Events?.oncollisionexit?.({
222
220
  targetCollider: collider2,
223
221
  targetRigidBody: rigidBody2
224
222
  });
225
- rigidBody2Events?.collisionexit?.({
223
+ rigidBody2Events?.oncollisionexit?.({
226
224
  targetCollider: collider1,
227
225
  targetRigidBody: rigidBody1
228
226
  });
@@ -1,2 +1,3 @@
1
+ import type { ColliderEvents, RigidBodyEvents } from '../types/types';
1
2
  import { type Collider } from '@dimforge/rapier3d-compat';
2
- export declare const applyColliderActiveEvents: (collider: Collider, colliderEvents?: Record<string, (arg: unknown) => void>, rigidBodyEvents?: Record<string, (arg: unknown) => void>) => void;
3
+ export declare const applyColliderActiveEvents: (collider: Collider, colliderEvents?: ColliderEvents, rigidBodyEvents?: RigidBodyEvents) => void;
@@ -1,17 +1,17 @@
1
1
  import { ActiveEvents } from '@dimforge/rapier3d-compat';
2
2
  export const applyColliderActiveEvents = (collider, colliderEvents = {}, rigidBodyEvents = {}) => {
3
3
  let events = 0;
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) {
4
+ if (colliderEvents.oncollisionenter ||
5
+ colliderEvents.oncollisionexit ||
6
+ rigidBodyEvents.oncollisionenter ||
7
+ rigidBodyEvents.oncollisionexit ||
8
+ colliderEvents.onsensorenter ||
9
+ colliderEvents.onsensorexit ||
10
+ rigidBodyEvents.onsensorenter ||
11
+ rigidBodyEvents.onsensorexit) {
12
12
  events = events | ActiveEvents.COLLISION_EVENTS;
13
13
  }
14
- if (colliderEvents.contact || rigidBodyEvents.contact) {
14
+ if (colliderEvents.oncontact || rigidBodyEvents.oncontact) {
15
15
  events = events | ActiveEvents.CONTACT_FORCE_EVENTS;
16
16
  }
17
17
  if (events > 0) {
@@ -2,17 +2,17 @@
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 { ColliderEventDispatchers, RigidBodyEventDispatchers } from '../types/types';
5
+ import type { ColliderEvents, RigidBodyEvents } 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;
9
9
  colliderObjects: Map<number, Object3D<import("three").Object3DEventMap>>;
10
10
  rigidBodyObjects: Map<number, Object3D<import("three").Object3DEventMap>>;
11
- rigidBodyEventDispatchers: RigidBodyEventDispatchers;
12
- colliderEventDispatchers: ColliderEventDispatchers;
13
- addColliderToContext: (collider: Collider, object: Object3D, events: Record<string, (arg: unknown) => void>) => void;
11
+ rigidBodyEventDispatchers: Map<number, RigidBodyEvents>;
12
+ colliderEventDispatchers: Map<number, ColliderEvents>;
13
+ addColliderToContext: (collider: Collider, object: Object3D, props: ColliderEvents) => void;
14
14
  removeColliderFromContext: (collider: Collider) => void;
15
- addRigidBodyToContext: (rigidBody: RigidBody, object: Object3D, events: Record<string, (arg: unknown) => void>) => void;
15
+ addRigidBodyToContext: (rigidBody: RigidBody, object: Object3D, events: RigidBodyEvents) => 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, events) => {
15
+ const addColliderToContext = (collider, object, props) => {
16
16
  colliderObjects.set(collider.handle, object);
17
- colliderEventDispatchers.set(collider.handle, events);
17
+ colliderEventDispatchers.set(collider.handle, props);
18
18
  };
19
19
  /**
20
20
  * Removes the collider from the context
@@ -1,2 +1,3 @@
1
- export declare const useParentRigidbodyObject: () => THREE.Object3D | undefined;
2
- export declare const setParentRigidbodyObject: (object3d: THREE.Object3D) => void;
1
+ import type { Object3D } from 'three';
2
+ export declare const useParentRigidbodyObject: () => Object3D | undefined;
3
+ export declare const setParentRigidbodyObject: (object3d: Object3D) => void;
@@ -1,3 +1,4 @@
1
- export declare const useCreateEvent: <T>(events: Record<string, (arg: unknown) => void>) => {
1
+ import type { ColliderEvents } from '../types/types';
2
+ export declare const useCreateEvent: <T>(oncreate?: ColliderEvents['oncreate']) => {
2
3
  updateRef: (newRef: T) => void;
3
4
  };
@@ -1,7 +1,7 @@
1
1
  import { onDestroy } from 'svelte';
2
- export const useCreateEvent = (events) => {
2
+ export const useCreateEvent = (oncreate) => {
3
3
  const cleanupFunctions = [];
4
- let ref = undefined;
4
+ let ref;
5
5
  const dispatchCreateEvent = () => {
6
6
  // call every cleanup function
7
7
  cleanupFunctions.forEach((cleanup) => cleanup());
@@ -13,7 +13,7 @@ export const useCreateEvent = (events) => {
13
13
  };
14
14
  if (ref === undefined)
15
15
  return;
16
- events?.create?.({ ref, cleanup });
16
+ oncreate?.({ ref, cleanup });
17
17
  };
18
18
  const updateRef = (newRef) => {
19
19
  ref = newRef;
@@ -1,4 +1,4 @@
1
- <script lang="ts">import { createRawEventDispatcher, T, useTask } from '@threlte/core';
1
+ <script lang="ts">import { 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';
@@ -10,6 +10,8 @@ export let speed = 1;
10
10
  export let jumpStrength = 3;
11
11
  export let playerCollisionGroups = [0];
12
12
  export let groundCollisionGroups = [15];
13
+ export let ongroundenter = undefined;
14
+ export let ongroundexit = undefined;
13
15
  let rigidBody;
14
16
  const keys = {
15
17
  up: false,
@@ -19,7 +21,6 @@ const keys = {
19
21
  };
20
22
  const t = new Vector3();
21
23
  const t2 = new Vector2();
22
- const dispatch = createRawEventDispatcher();
23
24
  let grounded = false;
24
25
  let groundsSensored = 0;
25
26
  $: {
@@ -28,7 +29,7 @@ $: {
28
29
  else
29
30
  grounded = true;
30
31
  }
31
- $: grounded ? dispatch('groundenter') : dispatch('groundexit');
32
+ $: grounded ? ongroundenter?.() : ongroundexit?.();
32
33
  const { start } = useTask(() => {
33
34
  t.set(0, 0, 0);
34
35
  if (keys.down)
@@ -126,8 +127,8 @@ const onKeyUp = (e) => {
126
127
  <T.Group position={[0, -height / 2 + radius, 0]}>
127
128
  <Collider
128
129
  sensor
129
- on:sensorenter={() => (groundsSensored += 1)}
130
- on:sensorexit={() => (groundsSensored -= 1)}
130
+ onsensorenter={() => (groundsSensored += 1)}
131
+ onsensorexit={() => (groundsSensored -= 1)}
131
132
  shape={'ball'}
132
133
  args={[radius * 1.2]}
133
134
  />
@@ -10,6 +10,8 @@ declare const __propDef: {
10
10
  jumpStrength?: number | undefined;
11
11
  playerCollisionGroups?: CollisionGroupsBitMask | undefined;
12
12
  groundCollisionGroups?: CollisionGroupsBitMask | undefined;
13
+ ongroundenter?: (() => void) | undefined;
14
+ ongroundexit?: (() => void) | undefined;
13
15
  children?: ((this: void) => typeof import("svelte").SnippetReturn & {
14
16
  _: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
15
17
  }) | undefined;
@@ -1,56 +1,54 @@
1
1
  /// <reference types="svelte" />
2
- import type { Collider, ColliderHandle, RigidBody, RigidBodyHandle, TempContactManifold, Vector } from '@dimforge/rapier3d-compat';
2
+ import type { Collider, RigidBody, TempContactManifold, Vector } from '@dimforge/rapier3d-compat';
3
3
  import type { Writable } from 'svelte/store';
4
4
  import type { createRapierContext } from '../lib/createRapierContext';
5
5
  export type ColliderShapes = 'ball' | 'capsule' | 'segment' | 'triangle' | 'roundTriangle' | 'polyline' | 'trimesh' | 'cuboid' | 'roundCuboid' | 'heightfield' | 'cylinder' | 'roundCylinder' | 'cone' | 'roundCone' | 'convexHull' | 'convexMesh' | 'roundConvexHull' | 'roundConvexMesh';
6
6
  export type AutoCollidersShapes = 'cuboid' | 'ball' | 'trimesh' | 'convexHull' | 'capsule';
7
- export type ColliderEventMap = {
8
- create: {
7
+ export type ColliderEvents = {
8
+ oncreate?: (event: {
9
9
  ref: Collider;
10
10
  cleanup: (callback: () => void) => void;
11
- };
12
- collisionenter: {
11
+ }) => void;
12
+ oncollisionenter?: (event: {
13
13
  targetCollider: Collider;
14
14
  targetRigidBody: RigidBody | null;
15
15
  manifold: TempContactManifold;
16
16
  flipped: boolean;
17
- };
18
- collisionexit: {
17
+ }) => void;
18
+ oncollisionexit?: (event: {
19
19
  targetCollider: Collider;
20
20
  targetRigidBody: RigidBody | null;
21
- };
22
- sensorenter: {
21
+ }) => void;
22
+ onsensorenter?: (event: {
23
23
  targetCollider: Collider;
24
24
  targetRigidBody: RigidBody | null;
25
- };
26
- sensorexit: {
25
+ }) => void;
26
+ onsensorexit?: (event: {
27
27
  targetCollider: Collider;
28
28
  targetRigidBody: RigidBody | null;
29
- };
30
- contact: {
29
+ }) => void;
30
+ oncontact?: (event: {
31
31
  targetCollider: Collider;
32
32
  targetRigidBody: RigidBody | null;
33
33
  maxForceDirection: Vector;
34
34
  maxForceMagnitude: number;
35
35
  totalForce: Vector;
36
36
  totalForceMagnitude: number;
37
- };
37
+ }) => void;
38
38
  };
39
- export type CollisionEnterEvent = ColliderEventMap['collisionenter'];
40
- export type CollisionExitEvent = ColliderEventMap['collisionexit'];
41
- export type SensorEnterEvent = ColliderEventMap['sensorenter'];
42
- export type SensorExitEvent = ColliderEventMap['sensorexit'];
43
- export type ContactEvent = ColliderEventMap['contact'];
44
- export type RigidBodyEventMap = ColliderEventMap & {
45
- sleep: void;
46
- wake: void;
39
+ export type CollisionEnterEvent = ColliderEvents['oncollisionenter'];
40
+ export type CollisionExitEvent = ColliderEvents['oncollisionexit'];
41
+ export type SensorEnterEvent = ColliderEvents['onsensorenter'];
42
+ export type SensorExitEvent = ColliderEvents['onsensorexit'];
43
+ export type ContactEvent = ColliderEvents['oncontact'];
44
+ export type RigidBodyEvents = ColliderEvents & {
45
+ onsleep?: () => void;
46
+ onwake?: () => void;
47
47
  };
48
- export type RigidBodyEventDispatchers = Map<RigidBodyHandle, Record<string, (arg: unknown) => void>>;
49
- export type ColliderEventDispatchers = Map<ColliderHandle, Record<string, (arg: unknown) => void>>;
50
48
  export type RapierContext = ReturnType<typeof createRapierContext>;
51
49
  export type CollisionGroupsContext = Writable<number> | undefined;
52
50
  export type RigidBodyUserData = {
53
- events?: Record<string, (arg: unknown) => void>;
51
+ events?: RigidBodyEvents;
54
52
  };
55
53
  export type ThrelteRigidBody = RigidBody & {
56
54
  userData?: RigidBodyUserData;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threlte/rapier",
3
- "version": "3.0.0-next.1",
3
+ "version": "3.0.0-next.3",
4
4
  "author": "Grischa Erbe <hello@legrisch.com> (https://legrisch.com)",
5
5
  "license": "MIT",
6
6
  "devDependencies": {
@@ -10,7 +10,7 @@
10
10
  "@sveltejs/package": "^2.3.1",
11
11
  "@sveltejs/vite-plugin-svelte": "^3.1.0",
12
12
  "@types/node": "^20.12.7",
13
- "@types/three": "^0.163.0",
13
+ "@types/three": "^0.165.0",
14
14
  "@typescript-eslint/eslint-plugin": "^7.6.0",
15
15
  "@typescript-eslint/parser": "^7.6.0",
16
16
  "@yushijinhun/three-minifier-rollup": "^0.4.0",
@@ -21,16 +21,16 @@
21
21
  "prettier-plugin-svelte": "^3.2.2",
22
22
  "publint": "^0.2.7",
23
23
  "rimraf": "^5.0.5",
24
- "svelte": "5.0.0-next.97",
24
+ "svelte": "5.0.0-next.107",
25
25
  "svelte-check": "^3.6.9",
26
26
  "svelte-preprocess": "^5.1.3",
27
27
  "svelte2tsx": "^0.7.6",
28
- "three": "^0.163.0",
28
+ "three": "^0.165.0",
29
29
  "tslib": "^2.6.2",
30
30
  "type-fest": "^4.15.0",
31
31
  "typescript": "^5.4.5",
32
32
  "vite": "^5.2.8",
33
- "@threlte/core": "8.0.0-next.2"
33
+ "@threlte/core": "8.0.0-next.7"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@dimforge/rapier3d-compat": ">=0.12",