@threlte/rapier 3.1.5 → 3.3.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.
- package/README.md +0 -4
- package/dist/components/Attractor/Attractor.svelte +58 -32
- package/dist/components/Attractor/Attractor.svelte.d.ts +2 -1
- package/dist/components/Attractor/types.d.ts +1 -1
- package/dist/components/Colliders/AutoColliders/AutoColliders.svelte +123 -76
- package/dist/components/Colliders/AutoColliders/AutoColliders.svelte.d.ts +15 -4
- package/dist/components/Colliders/AutoColliders/types.d.ts +1 -1
- package/dist/components/Colliders/Collider/Collider.svelte +176 -126
- package/dist/components/Colliders/Collider/Collider.svelte.d.ts +13 -4
- package/dist/components/Colliders/Collider/types.d.ts +1 -1
- package/dist/components/CollisionGroups/CollisionGroups.svelte +27 -7
- package/dist/components/CollisionGroups/CollisionGroups.svelte.d.ts +11 -4
- package/dist/components/Debug/Debug.svelte +28 -18
- package/dist/components/Debug/Debug.svelte.d.ts +2 -1
- package/dist/components/RigidBody/RigidBody.svelte +173 -113
- package/dist/components/RigidBody/RigidBody.svelte.d.ts +2 -1
- package/dist/components/RigidBody/types.d.ts +2 -2
- package/dist/components/World/InnerWorld.svelte +53 -22
- package/dist/components/World/InnerWorld.svelte.d.ts +2 -1
- package/dist/components/World/World.svelte +6 -3
- package/dist/components/World/World.svelte.d.ts +2 -1
- package/dist/components/World/types.d.ts +1 -1
- package/dist/hooks/useFixedJoint.js +2 -2
- package/dist/hooks/useJoint.d.ts +1 -1
- package/dist/hooks/useJoint.js +1 -1
- package/dist/hooks/usePhysicsTask.js +1 -1
- package/dist/hooks/usePrismaticJoint.js +2 -2
- package/dist/hooks/useRapier.d.ts +1 -1
- package/dist/hooks/useRevoluteJoint.js +2 -2
- package/dist/hooks/useRigidBody.d.ts +1 -1
- package/dist/hooks/useRopeJoint.js +2 -2
- package/dist/hooks/useSphericalJoint.js +2 -2
- package/dist/index.d.ts +12 -12
- package/dist/index.js +11 -11
- package/dist/lib/applyColliderActiveEvents.d.ts +1 -1
- package/dist/lib/createCollidersFromChildren.d.ts +1 -1
- package/dist/lib/createPhysicsStages.d.ts +1 -1
- package/dist/lib/createPhysicsStages.js +1 -1
- package/dist/lib/createPhysicsTasks.d.ts +1 -1
- package/dist/lib/createPhysicsTasks.js +1 -1
- package/dist/lib/createRapierContext.d.ts +1 -1
- package/dist/lib/createRapierContext.js +2 -2
- package/dist/lib/scaleColliderArgs.d.ts +1 -1
- package/dist/lib/useCreateEvent.d.ts +1 -1
- package/package.json +10 -11
|
@@ -1,151 +1,201 @@
|
|
|
1
1
|
<script
|
|
2
2
|
lang="ts"
|
|
3
3
|
generics="TShape extends Shape, TMassDef extends MassDef"
|
|
4
|
-
>
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
4
|
+
>
|
|
5
|
+
import {
|
|
6
|
+
ActiveCollisionTypes,
|
|
7
|
+
CoefficientCombineRule,
|
|
8
|
+
ColliderDesc
|
|
9
|
+
} from '@dimforge/rapier3d-compat'
|
|
10
|
+
import { createParentObject3DContext, useParentObject3D, useTask, watch } from '@threlte/core'
|
|
11
|
+
import { onDestroy, onMount, tick } from 'svelte'
|
|
12
|
+
import { Object3D, Quaternion, Vector3 } from 'three'
|
|
13
|
+
import { useCollisionGroups } from '../../../hooks/useCollisionGroups.js'
|
|
14
|
+
import { useRapier } from '../../../hooks/useRapier.js'
|
|
15
|
+
import { useRigidBody } from '../../../hooks/useRigidBody.js'
|
|
16
|
+
import { applyColliderActiveEvents } from '../../../lib/applyColliderActiveEvents.js'
|
|
17
|
+
import { eulerToQuaternion } from '../../../lib/eulerToQuaternion.js'
|
|
18
|
+
import { getWorldPosition, getWorldQuaternion } from '../../../lib/getWorldTransforms.js'
|
|
19
|
+
import { useParentRigidbodyObject } from '../../../lib/rigidBodyObjectContext.js'
|
|
20
|
+
import { scaleColliderArgs } from '../../../lib/scaleColliderArgs.js'
|
|
21
|
+
import { useCreateEvent } from '../../../lib/useCreateEvent.js'
|
|
22
|
+
import type { ColliderProps, MassDef, Shape } from './types.js'
|
|
23
|
+
|
|
24
|
+
let {
|
|
25
|
+
shape,
|
|
26
|
+
args,
|
|
27
|
+
type,
|
|
28
|
+
restitution,
|
|
29
|
+
restitutionCombineRule,
|
|
30
|
+
friction,
|
|
31
|
+
frictionCombineRule,
|
|
32
|
+
sensor,
|
|
33
|
+
contactForceEventThreshold,
|
|
34
|
+
density,
|
|
35
|
+
mass,
|
|
36
|
+
centerOfMass,
|
|
37
|
+
principalAngularInertia,
|
|
38
|
+
angularInertiaLocalFrame,
|
|
39
|
+
collider = $bindable(),
|
|
40
|
+
oncreate,
|
|
41
|
+
oncollisionenter,
|
|
42
|
+
oncollisionexit,
|
|
43
|
+
oncontact,
|
|
44
|
+
onsensorenter,
|
|
45
|
+
onsensorexit,
|
|
46
|
+
children
|
|
47
|
+
}: ColliderProps<TShape, TMassDef> = $props()
|
|
48
|
+
|
|
49
|
+
const object = new Object3D()
|
|
50
|
+
|
|
51
|
+
const { updateRef } = useCreateEvent(oncreate)
|
|
52
|
+
const rigidBody = useRigidBody()
|
|
53
|
+
const parentRigidBodyObject = useParentRigidbodyObject()
|
|
54
|
+
const hasRigidBodyParent = !!rigidBody
|
|
55
|
+
|
|
56
|
+
const rapierContext = useRapier()
|
|
57
|
+
const { world } = rapierContext
|
|
58
|
+
|
|
59
|
+
const collisionGroups = useCollisionGroups()
|
|
60
|
+
|
|
61
|
+
const events = {
|
|
27
62
|
oncollisionenter,
|
|
28
63
|
oncollisionexit,
|
|
29
64
|
oncontact,
|
|
30
65
|
onsensorenter,
|
|
31
66
|
onsensorexit
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Actual collider setup happens onMount as only then
|
|
71
|
+
* the transforms are finished.
|
|
72
|
+
*/
|
|
73
|
+
onMount(async () => {
|
|
74
|
+
await tick()
|
|
75
|
+
|
|
76
|
+
const scale = object.getWorldScale(new Vector3())
|
|
77
|
+
|
|
78
|
+
const scaledArgs = scaleColliderArgs(shape, args, scale)
|
|
79
|
+
|
|
41
80
|
// @ts-expect-error
|
|
42
|
-
const colliderDesc = ColliderDesc[shape](...scaledArgs)
|
|
43
|
-
|
|
44
|
-
collider.
|
|
45
|
-
|
|
81
|
+
const colliderDesc = ColliderDesc[shape](...scaledArgs) as ColliderDesc
|
|
82
|
+
|
|
83
|
+
collider = world.createCollider(colliderDesc, rigidBody)
|
|
84
|
+
collider.setActiveCollisionTypes(ActiveCollisionTypes.ALL)
|
|
85
|
+
updateRef(collider)
|
|
86
|
+
|
|
46
87
|
/**
|
|
47
88
|
* Add collider to context
|
|
48
89
|
*/
|
|
49
|
-
rapierContext.addColliderToContext(collider, object, events)
|
|
90
|
+
rapierContext.addColliderToContext(collider, object, events)
|
|
91
|
+
|
|
50
92
|
/**
|
|
51
93
|
* For use in conjunction with component <CollisionGroups>
|
|
52
94
|
*/
|
|
53
|
-
collisionGroups.registerColliders([collider])
|
|
95
|
+
collisionGroups.registerColliders([collider])
|
|
96
|
+
|
|
54
97
|
if (hasRigidBodyParent) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
98
|
+
const rigidBodyWorldPos = new Vector3()
|
|
99
|
+
const rigidBodyWorldQuatInversed = new Quaternion()
|
|
100
|
+
|
|
101
|
+
parentRigidBodyObject?.getWorldPosition(rigidBodyWorldPos)
|
|
102
|
+
parentRigidBodyObject?.getWorldQuaternion(rigidBodyWorldQuatInversed)
|
|
103
|
+
rigidBodyWorldQuatInversed.invert()
|
|
104
|
+
|
|
105
|
+
const worldPosition = object.getWorldPosition(new Vector3()).sub(rigidBodyWorldPos)
|
|
106
|
+
const worldRotation = object
|
|
107
|
+
.getWorldQuaternion(new Quaternion())
|
|
108
|
+
.premultiply(rigidBodyWorldQuatInversed)
|
|
109
|
+
|
|
110
|
+
collider.setTranslationWrtParent(worldPosition)
|
|
111
|
+
collider.setRotationWrtParent(worldRotation)
|
|
112
|
+
} else {
|
|
113
|
+
collider.setTranslation(object.getWorldPosition(new Vector3()))
|
|
114
|
+
collider.setRotation(object.getWorldQuaternion(new Quaternion()))
|
|
70
115
|
}
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
$effect.pre(() => collider?.
|
|
86
|
-
$effect.pre(() =>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})
|
|
90
|
-
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
$effect.pre(() => {
|
|
119
|
+
collider?.setRestitution(restitution ?? 0)
|
|
120
|
+
})
|
|
121
|
+
$effect.pre(() => {
|
|
122
|
+
collider?.setRestitutionCombineRule(restitutionCombineRule ?? CoefficientCombineRule.Average)
|
|
123
|
+
})
|
|
124
|
+
$effect.pre(() => {
|
|
125
|
+
collider?.setFriction(friction ?? 0.7)
|
|
126
|
+
})
|
|
127
|
+
$effect.pre(() => {
|
|
128
|
+
collider?.setFrictionCombineRule(frictionCombineRule ?? CoefficientCombineRule.Average)
|
|
129
|
+
})
|
|
130
|
+
$effect.pre(() => collider?.setSensor(sensor ?? false))
|
|
131
|
+
$effect.pre(() => collider?.setContactForceEventThreshold(contactForceEventThreshold ?? 0))
|
|
132
|
+
$effect.pre(() => {
|
|
133
|
+
if (density !== undefined) collider?.setDensity(density)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
$effect.pre(() => {
|
|
91
137
|
if (collider && mass) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
138
|
+
if (centerOfMass && principalAngularInertia && angularInertiaLocalFrame) {
|
|
139
|
+
collider.setMassProperties(
|
|
140
|
+
mass,
|
|
141
|
+
{ x: centerOfMass[0], y: centerOfMass[1], z: centerOfMass[2] },
|
|
142
|
+
{
|
|
143
|
+
x: principalAngularInertia[0],
|
|
144
|
+
y: principalAngularInertia[1],
|
|
145
|
+
z: principalAngularInertia[2]
|
|
146
|
+
},
|
|
147
|
+
eulerToQuaternion(angularInertiaLocalFrame)
|
|
148
|
+
)
|
|
149
|
+
} else {
|
|
150
|
+
collider.setMass(mass)
|
|
151
|
+
}
|
|
102
152
|
}
|
|
103
|
-
})
|
|
104
|
-
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
$effect.pre(() => {
|
|
105
156
|
if (collider) {
|
|
106
|
-
|
|
157
|
+
applyColliderActiveEvents(collider, events, rigidBody?.userData?.events)
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
export const refresh = () => {
|
|
162
|
+
if (!collider) return
|
|
163
|
+
collider.setTranslation(getWorldPosition(object))
|
|
164
|
+
collider.setRotation(getWorldQuaternion(object))
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* If the Collider isAttached (i.e. NOT child of a RigidBody), update the
|
|
169
|
+
* transforms on every frame.
|
|
170
|
+
*/
|
|
171
|
+
useTask(
|
|
172
|
+
() => {
|
|
173
|
+
refresh()
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
running: () => !hasRigidBodyParent && type === 'dynamic'
|
|
107
177
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (!hasRigidBodyParent && type === 'dynamic')
|
|
126
|
-
start();
|
|
127
|
-
else
|
|
128
|
-
stop();
|
|
129
|
-
});
|
|
130
|
-
/**
|
|
131
|
-
* Cleanup
|
|
132
|
-
*/
|
|
133
|
-
onDestroy(() => {
|
|
134
|
-
if (!collider)
|
|
135
|
-
return;
|
|
136
|
-
rapierContext.removeColliderFromContext(collider);
|
|
137
|
-
collisionGroups.removeColliders([collider]);
|
|
138
|
-
world.removeCollider(collider, true);
|
|
139
|
-
collider = undefined;
|
|
140
|
-
});
|
|
141
|
-
const parent3DObject = useParentObject3D();
|
|
142
|
-
createParentObject3DContext(object);
|
|
143
|
-
watch(parent3DObject, (parent) => {
|
|
144
|
-
parent?.add(object);
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Cleanup
|
|
182
|
+
*/
|
|
183
|
+
onDestroy(() => {
|
|
184
|
+
if (!collider) return
|
|
185
|
+
rapierContext.removeColliderFromContext(collider)
|
|
186
|
+
collisionGroups.removeColliders([collider])
|
|
187
|
+
world.removeCollider(collider, true)
|
|
188
|
+
collider = undefined
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
const parent3DObject = useParentObject3D()
|
|
192
|
+
createParentObject3DContext(object)
|
|
193
|
+
watch(parent3DObject, (parent) => {
|
|
194
|
+
parent?.add(object)
|
|
145
195
|
return () => {
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
})
|
|
196
|
+
parent?.remove(object)
|
|
197
|
+
}
|
|
198
|
+
})
|
|
149
199
|
</script>
|
|
150
200
|
|
|
151
201
|
{@render children?.({ collider })}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import type { ColliderProps, MassDef, Shape } from './types';
|
|
1
|
+
import type { ColliderProps, MassDef, Shape } from './types.js';
|
|
2
|
+
declare function $$render<TShape extends Shape, TMassDef extends MassDef>(): {
|
|
3
|
+
props: ColliderProps<TShape, TMassDef>;
|
|
4
|
+
exports: {
|
|
5
|
+
refresh: () => void;
|
|
6
|
+
};
|
|
7
|
+
bindings: "collider";
|
|
8
|
+
slots: {};
|
|
9
|
+
events: {};
|
|
10
|
+
};
|
|
2
11
|
declare class __sveltets_Render<TShape extends Shape, TMassDef extends MassDef> {
|
|
3
|
-
props():
|
|
4
|
-
events():
|
|
5
|
-
slots():
|
|
12
|
+
props(): ReturnType<typeof $$render<TShape, TMassDef>>['props'];
|
|
13
|
+
events(): ReturnType<typeof $$render<TShape, TMassDef>>['events'];
|
|
14
|
+
slots(): ReturnType<typeof $$render<TShape, TMassDef>>['slots'];
|
|
6
15
|
bindings(): "collider";
|
|
7
16
|
exports(): {
|
|
8
17
|
refresh: () => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CoefficientCombineRule, Collider, ColliderDesc, Collider as RapierCollider } from '@dimforge/rapier3d-compat';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { Euler, Vector3 } from 'three';
|
|
4
|
-
import type { ColliderEvents, CreateEvent } from '../../../types/types';
|
|
4
|
+
import type { ColliderEvents, CreateEvent } from '../../../types/types.js';
|
|
5
5
|
type Type = 'static' | 'dynamic';
|
|
6
6
|
type BaseProps = {
|
|
7
7
|
/**
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
<script
|
|
2
2
|
lang="ts"
|
|
3
3
|
generics="TGroupsDef extends GroupsDef"
|
|
4
|
-
>
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
>
|
|
5
|
+
import { setContext } from 'svelte'
|
|
6
|
+
import { writable } from 'svelte/store'
|
|
7
|
+
import { computeBitMask } from '../../lib/computeBitMask.js'
|
|
8
|
+
import type { CollisionGroupsContext } from '../../types/types.js'
|
|
9
|
+
import type { CollisionGroupsProps, Groups, GroupsDef, MembershipsAndFilter } from './types.js'
|
|
10
|
+
|
|
11
|
+
let { groups, filter, memberships, children }: CollisionGroupsProps<TGroupsDef> = $props()
|
|
12
|
+
|
|
13
|
+
const store = writable<number>(
|
|
14
|
+
computeBitMask(
|
|
15
|
+
groups as Groups,
|
|
16
|
+
filter as MembershipsAndFilter,
|
|
17
|
+
memberships as MembershipsAndFilter
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
$effect.pre(() =>
|
|
21
|
+
store.set(
|
|
22
|
+
computeBitMask(
|
|
23
|
+
groups as Groups,
|
|
24
|
+
filter as MembershipsAndFilter,
|
|
25
|
+
memberships as MembershipsAndFilter
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
setContext<NonNullable<CollisionGroupsContext>>('threlte-rapier-collision-group', store)
|
|
11
31
|
</script>
|
|
12
32
|
|
|
13
33
|
{@render children?.()}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import type { CollisionGroupsProps, GroupsDef } from './types';
|
|
1
|
+
import type { CollisionGroupsProps, GroupsDef } from './types.js';
|
|
2
|
+
declare function $$render<TGroupsDef extends GroupsDef>(): {
|
|
3
|
+
props: CollisionGroupsProps<TGroupsDef>;
|
|
4
|
+
exports: {};
|
|
5
|
+
bindings: "";
|
|
6
|
+
slots: {};
|
|
7
|
+
events: {};
|
|
8
|
+
};
|
|
2
9
|
declare class __sveltets_Render<TGroupsDef extends GroupsDef> {
|
|
3
|
-
props():
|
|
4
|
-
events():
|
|
5
|
-
slots():
|
|
10
|
+
props(): ReturnType<typeof $$render<TGroupsDef>>['props'];
|
|
11
|
+
events(): ReturnType<typeof $$render<TGroupsDef>>['events'];
|
|
12
|
+
slots(): ReturnType<typeof $$render<TGroupsDef>>['slots'];
|
|
6
13
|
bindings(): "";
|
|
7
14
|
exports(): {};
|
|
8
15
|
}
|
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { T, useTask } from '@threlte/core'
|
|
3
|
+
import { onDestroy } from 'svelte'
|
|
4
|
+
import { BufferAttribute, BufferGeometry, LineSegments } from 'three'
|
|
5
|
+
import { useRapier } from '../../hooks/useRapier.js'
|
|
6
|
+
import type { DebugProps } from './types.js'
|
|
7
|
+
|
|
8
|
+
let { ref = $bindable(new LineSegments()), ...props }: DebugProps = $props()
|
|
9
|
+
|
|
10
|
+
const { world, debug } = useRapier()
|
|
11
|
+
|
|
12
|
+
const geometry = new BufferGeometry()
|
|
13
|
+
|
|
14
|
+
debug.set(true)
|
|
15
|
+
|
|
16
|
+
useTask(() => {
|
|
17
|
+
const buffers = world.debugRender()
|
|
18
|
+
|
|
19
|
+
const vertices = new BufferAttribute(buffers.vertices, 3)
|
|
20
|
+
const colors = new BufferAttribute(buffers.colors, 4)
|
|
21
|
+
|
|
22
|
+
geometry.setAttribute('position', vertices)
|
|
23
|
+
geometry.setAttribute('color', colors)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
onDestroy(() => {
|
|
27
|
+
debug.set(false)
|
|
28
|
+
})
|
|
19
29
|
</script>
|
|
20
30
|
|
|
21
31
|
<T
|