@threlte/rapier 1.1.2 → 1.1.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.
- package/dist/components/Colliders/AutoColliders.svelte +6 -1
- package/dist/components/Colliders/Collider.svelte +30 -32
- package/dist/components/Debug/Debug.svelte +5 -11
- package/dist/components/RigidBody/RigidBody.svelte +8 -4
- package/dist/lib/createCollidersFromChildren.d.ts +1 -1
- package/dist/lib/createCollidersFromChildren.js +24 -25
- package/dist/lib/createRapierContext.js +0 -1
- package/dist/lib/rigidBodyObjectContext.d.ts +2 -0
- package/dist/lib/rigidBodyObjectContext.js +8 -0
- package/dist/lib/useCreateEvent.d.ts +3 -0
- package/dist/lib/useCreateEvent.js +31 -0
- package/dist/types/types.d.ts +4 -0
- package/package.json +2 -2
|
@@ -6,6 +6,8 @@ import { useCollisionGroups } from '../../hooks/useCollisionGroups';
|
|
|
6
6
|
import { useHasEventListeners } from '../../hooks/useHasEventListener';
|
|
7
7
|
import { useRapier } from '../../hooks/useRapier';
|
|
8
8
|
import { useRigidBody } from '../../hooks/useRigidBody';
|
|
9
|
+
import { useCreateEvent } from '../../lib/useCreateEvent';
|
|
10
|
+
import { useParentRigidbodyObject } from '../../lib/rigidBodyObjectContext';
|
|
9
11
|
import { applyColliderActiveEvents } from '../../lib/applyColliderActiveEvents';
|
|
10
12
|
import { createCollidersFromChildren } from '../../lib/createCollidersFromChildren';
|
|
11
13
|
import { eulerToQuaternion } from '../../lib/eulerToQuaternion';
|
|
@@ -22,7 +24,9 @@ export let centerOfMass = undefined;
|
|
|
22
24
|
export let principalAngularInertia = undefined;
|
|
23
25
|
export let angularInertiaLocalFrame = undefined;
|
|
24
26
|
const group = new Group();
|
|
27
|
+
const { updateRef } = useCreateEvent();
|
|
25
28
|
const rigidBody = useRigidBody();
|
|
29
|
+
const rigidBodyParentObject = useParentRigidbodyObject();
|
|
26
30
|
const { world, addColliderToContext, removeColliderFromContext } = useRapier();
|
|
27
31
|
export let colliders = [];
|
|
28
32
|
const collisionGroups = useCollisionGroups();
|
|
@@ -38,7 +42,7 @@ const cleanup = () => {
|
|
|
38
42
|
};
|
|
39
43
|
export const create = () => {
|
|
40
44
|
cleanup();
|
|
41
|
-
colliders = createCollidersFromChildren(group, shape ?? 'convexHull', world, rigidBody);
|
|
45
|
+
colliders = createCollidersFromChildren(group, shape ?? 'convexHull', world, rigidBody, rigidBodyParentObject);
|
|
42
46
|
colliders.forEach((c) => addColliderToContext(c, group, dispatcher));
|
|
43
47
|
collisionGroups.registerColliders(colliders);
|
|
44
48
|
colliders.forEach((collider) => {
|
|
@@ -63,6 +67,7 @@ export const create = () => {
|
|
|
63
67
|
collider.setMass(mass);
|
|
64
68
|
}
|
|
65
69
|
});
|
|
70
|
+
updateRef(colliders);
|
|
66
71
|
};
|
|
67
72
|
onMount(() => {
|
|
68
73
|
create();
|
|
@@ -6,6 +6,8 @@ import { useCollisionGroups } from '../../hooks/useCollisionGroups';
|
|
|
6
6
|
import { useHasEventListeners } from '../../hooks/useHasEventListener';
|
|
7
7
|
import { useRapier } from '../../hooks/useRapier';
|
|
8
8
|
import { useRigidBody } from '../../hooks/useRigidBody';
|
|
9
|
+
import { useParentRigidbodyObject } from '../../lib/rigidBodyObjectContext';
|
|
10
|
+
import { useCreateEvent } from '../../lib/useCreateEvent';
|
|
9
11
|
import { applyColliderActiveEvents } from '../../lib/applyColliderActiveEvents';
|
|
10
12
|
import { eulerToQuaternion } from '../../lib/eulerToQuaternion';
|
|
11
13
|
import { getWorldPosition, getWorldQuaternion } from '../../lib/getWorldTransforms';
|
|
@@ -25,7 +27,9 @@ export let centerOfMass = undefined;
|
|
|
25
27
|
export let principalAngularInertia = undefined;
|
|
26
28
|
export let angularInertiaLocalFrame = undefined;
|
|
27
29
|
const object = new Object3D();
|
|
30
|
+
const { updateRef } = useCreateEvent();
|
|
28
31
|
const rigidBody = useRigidBody();
|
|
32
|
+
const parentRigidBodyObject = useParentRigidbodyObject();
|
|
29
33
|
const hasRigidBodyParent = !!rigidBody;
|
|
30
34
|
const rapierContext = useRapier();
|
|
31
35
|
const { world } = rapierContext;
|
|
@@ -43,6 +47,8 @@ onMount(async () => {
|
|
|
43
47
|
// @ts-ignore
|
|
44
48
|
const colliderDesc = ColliderDesc[shape](...scaledArgs);
|
|
45
49
|
collider = world.createCollider(colliderDesc, rigidBody);
|
|
50
|
+
collider.setActiveCollisionTypes(ActiveCollisionTypes.ALL);
|
|
51
|
+
updateRef(collider);
|
|
46
52
|
/**
|
|
47
53
|
* Add collider to context
|
|
48
54
|
*/
|
|
@@ -54,13 +60,9 @@ onMount(async () => {
|
|
|
54
60
|
if (hasRigidBodyParent) {
|
|
55
61
|
const rigidBodyWorldPos = new Vector3();
|
|
56
62
|
const rigidBodyWorldQuatInversed = new Quaternion();
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
child.getWorldQuaternion(rigidBodyWorldQuatInversed);
|
|
61
|
-
rigidBodyWorldQuatInversed.invert();
|
|
62
|
-
}
|
|
63
|
-
});
|
|
63
|
+
parentRigidBodyObject?.getWorldPosition(rigidBodyWorldPos);
|
|
64
|
+
parentRigidBodyObject?.getWorldQuaternion(rigidBodyWorldQuatInversed);
|
|
65
|
+
rigidBodyWorldQuatInversed.invert();
|
|
64
66
|
const worldPosition = object.getWorldPosition(new Vector3()).sub(rigidBodyWorldPos);
|
|
65
67
|
const worldRotation = object
|
|
66
68
|
.getWorldQuaternion(new Quaternion())
|
|
@@ -74,33 +76,29 @@ onMount(async () => {
|
|
|
74
76
|
}
|
|
75
77
|
});
|
|
76
78
|
const { hasEventListeners: colliderHasEventListeners } = useHasEventListeners();
|
|
77
|
-
$:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
collider.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
z: principalAngularInertia[2]
|
|
96
|
-
}, eulerToQuaternion(angularInertiaLocalFrame));
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
collider.setMass(mass);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
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));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
collider.setMass(mass);
|
|
102
97
|
}
|
|
103
98
|
}
|
|
99
|
+
$: if (collider) {
|
|
100
|
+
applyColliderActiveEvents(collider, colliderHasEventListeners, rigidBody?.userData?.hasEventListeners);
|
|
101
|
+
}
|
|
104
102
|
export const refresh = () => {
|
|
105
103
|
if (!collider)
|
|
106
104
|
return;
|
|
@@ -3,12 +3,7 @@ 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
|
-
const buffers = world.debugRender();
|
|
7
|
-
const vertices = new BufferAttribute(buffers.vertices, 3);
|
|
8
|
-
const colors = new BufferAttribute(buffers.colors, 4);
|
|
9
6
|
const geometry = new BufferGeometry();
|
|
10
|
-
geometry.setAttribute('position', vertices);
|
|
11
|
-
geometry.setAttribute('color', colors);
|
|
12
7
|
debug.set(true);
|
|
13
8
|
useFrame(() => {
|
|
14
9
|
const buffers = world.debugRender();
|
|
@@ -18,16 +13,15 @@ useFrame(() => {
|
|
|
18
13
|
geometry.setAttribute('color', colors);
|
|
19
14
|
});
|
|
20
15
|
onDestroy(() => {
|
|
21
|
-
geometry.dispose();
|
|
22
16
|
debug.set(false);
|
|
23
17
|
});
|
|
24
18
|
</script>
|
|
25
19
|
|
|
26
|
-
<T.LineSegments
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/>
|
|
20
|
+
<T.LineSegments
|
|
21
|
+
frustumCulled={false}
|
|
22
|
+
renderOrder={Infinity}
|
|
23
|
+
>
|
|
24
|
+
<T is={geometry} />
|
|
31
25
|
<T.LineBasicMaterial
|
|
32
26
|
vertexColors
|
|
33
27
|
{...$$restProps}
|
|
@@ -5,6 +5,8 @@ import { useHasEventListeners } from '../../hooks/useHasEventListener';
|
|
|
5
5
|
import { useRapier } from '../../hooks/useRapier';
|
|
6
6
|
import { getWorldPosition, getWorldQuaternion, getWorldScale } from '../../lib/getWorldTransforms';
|
|
7
7
|
import { parseRigidBodyType } from '../../lib/parseRigidBodyType';
|
|
8
|
+
import { setParentRigidbodyObject } from '../../lib/rigidBodyObjectContext';
|
|
9
|
+
import { useCreateEvent } from '../../lib/useCreateEvent';
|
|
8
10
|
const { world, rapier, addRigidBodyToContext, removeRigidBodyFromContext } = useRapier();
|
|
9
11
|
export let linearVelocity = undefined;
|
|
10
12
|
export let angularVelocity = undefined;
|
|
@@ -22,11 +24,8 @@ export let dominance = 0;
|
|
|
22
24
|
export let enabled = true;
|
|
23
25
|
export let userData = {};
|
|
24
26
|
const dispatcher = createRawEventDispatcher();
|
|
27
|
+
const { updateRef } = useCreateEvent();
|
|
25
28
|
const object = new Object3D();
|
|
26
|
-
/**
|
|
27
|
-
* Used to traverseAncestors to restore transform
|
|
28
|
-
*/
|
|
29
|
-
object.userData.isRigidBody = true;
|
|
30
29
|
/**
|
|
31
30
|
* isSleeping used for events "sleep" and "wake" in `useFrameHandler`
|
|
32
31
|
*/
|
|
@@ -56,6 +55,7 @@ const initPosition = async () => {
|
|
|
56
55
|
rigidBodyTemp.setTranslation(worldPosition, true);
|
|
57
56
|
rigidBodyTemp.setRotation(worldQuaternion, true);
|
|
58
57
|
rigidBody = rigidBodyTemp;
|
|
58
|
+
updateRef(rigidBody);
|
|
59
59
|
};
|
|
60
60
|
initPosition();
|
|
61
61
|
/**
|
|
@@ -93,6 +93,10 @@ $: rigidBodyTemp.userData = {
|
|
|
93
93
|
* hook onto.
|
|
94
94
|
*/
|
|
95
95
|
setContext('threlte-rapier-rigidbody', rigidBodyTemp);
|
|
96
|
+
/**
|
|
97
|
+
* Used by child colliders to restore transform
|
|
98
|
+
*/
|
|
99
|
+
setParentRigidbodyObject(object);
|
|
96
100
|
/**
|
|
97
101
|
* Add the mesh to the context
|
|
98
102
|
*/
|
|
@@ -13,4 +13,4 @@ import type { AutoCollidersShapes } from '../types/types';
|
|
|
13
13
|
* @param rigidBody
|
|
14
14
|
* @returns
|
|
15
15
|
*/
|
|
16
|
-
export declare const createCollidersFromChildren: (object: Object3D, collidersType: AutoCollidersShapes, world: World, rigidBody?: RigidBody) => Collider[];
|
|
16
|
+
export declare const createCollidersFromChildren: (object: Object3D, collidersType: AutoCollidersShapes, world: World, rigidBody?: RigidBody, rigidBodyParentObject?: Object3D) => Collider[];
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { ActiveEvents, Collider, ColliderDesc, World, RigidBody } from '@dimforge/rapier3d-compat';
|
|
2
2
|
import { Mesh, Quaternion, Vector3 } from 'three';
|
|
3
|
+
const offset = new Vector3();
|
|
4
|
+
const worldPosition = new Vector3();
|
|
5
|
+
const worldQuaternion = new Quaternion();
|
|
6
|
+
const worldScale = new Vector3();
|
|
7
|
+
const size = new Vector3();
|
|
8
|
+
const rigidBodyWorldPos = new Vector3();
|
|
9
|
+
const rigidBodyWorldQuatInversed = new Quaternion();
|
|
3
10
|
/**
|
|
4
11
|
*
|
|
5
12
|
* Creates collider descriptions including default translations
|
|
@@ -12,39 +19,34 @@ import { Mesh, Quaternion, Vector3 } from 'three';
|
|
|
12
19
|
* @param rigidBody
|
|
13
20
|
* @returns
|
|
14
21
|
*/
|
|
15
|
-
export const createCollidersFromChildren = (object, collidersType, world, rigidBody) => {
|
|
22
|
+
export const createCollidersFromChildren = (object, collidersType, world, rigidBody, rigidBodyParentObject) => {
|
|
16
23
|
const colliders = [];
|
|
17
24
|
let description;
|
|
18
|
-
const offset = new Vector3();
|
|
19
25
|
/**
|
|
20
26
|
* Trying to find the parent RigidBody.
|
|
21
27
|
* If we find something, good. If not,
|
|
22
28
|
* the Colliders are created on the world positions
|
|
23
29
|
* of the meshes they resemble.
|
|
24
30
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
child.getWorldPosition(rigidBodyWorldPos);
|
|
30
|
-
child.getWorldQuaternion(rigidBodyWorldQuatInversed);
|
|
31
|
-
rigidBodyWorldQuatInversed.invert();
|
|
32
|
-
}
|
|
33
|
-
});
|
|
31
|
+
rigidBodyWorldPos.set(0, 0, 0);
|
|
32
|
+
rigidBodyWorldQuatInversed.set(0, 0, 0, 1);
|
|
33
|
+
rigidBodyParentObject?.getWorldPosition(rigidBodyWorldPos);
|
|
34
|
+
rigidBodyParentObject?.getWorldQuaternion(rigidBodyWorldQuatInversed).invert();
|
|
34
35
|
object.traverse((child) => {
|
|
35
36
|
if ('isMesh' in child) {
|
|
36
37
|
const { geometry } = child;
|
|
37
|
-
const worldPos = child.getWorldPosition(
|
|
38
|
-
const
|
|
39
|
-
const worldQuat = child.getWorldQuaternion(
|
|
40
|
-
const
|
|
41
|
-
const scale = child.getWorldScale(
|
|
38
|
+
const worldPos = child.getWorldPosition(worldPosition);
|
|
39
|
+
const translation = worldPos.sub(rigidBodyWorldPos);
|
|
40
|
+
const worldQuat = child.getWorldQuaternion(worldQuaternion);
|
|
41
|
+
const rotation = worldQuat.clone().premultiply(rigidBodyWorldQuatInversed);
|
|
42
|
+
const scale = child.getWorldScale(worldScale);
|
|
43
|
+
offset.set(0, 0, 0);
|
|
42
44
|
switch (collidersType) {
|
|
43
45
|
case 'cuboid':
|
|
44
46
|
{
|
|
45
47
|
geometry.computeBoundingBox();
|
|
46
48
|
const { boundingBox } = geometry;
|
|
47
|
-
|
|
49
|
+
boundingBox.getSize(size);
|
|
48
50
|
boundingBox.getCenter(offset);
|
|
49
51
|
description = ColliderDesc.cuboid((size.x / 2) * scale.x, (size.y / 2) * scale.y, (size.z / 2) * scale.z);
|
|
50
52
|
}
|
|
@@ -60,31 +62,28 @@ export const createCollidersFromChildren = (object, collidersType, world, rigidB
|
|
|
60
62
|
break;
|
|
61
63
|
case 'trimesh':
|
|
62
64
|
{
|
|
63
|
-
|
|
64
|
-
description = ColliderDesc.trimesh(g.attributes.position.array, g.index?.array);
|
|
65
|
+
description = ColliderDesc.trimesh(new Float32Array(geometry.attributes.position.array), new Uint32Array(geometry.index?.array ?? []));
|
|
65
66
|
}
|
|
66
67
|
break;
|
|
67
68
|
case 'capsule':
|
|
68
69
|
{
|
|
69
70
|
geometry.computeBoundingBox();
|
|
70
71
|
const { boundingBox } = geometry;
|
|
71
|
-
|
|
72
|
+
boundingBox.getSize(size);
|
|
72
73
|
boundingBox.getCenter(offset);
|
|
73
74
|
const radius = Math.max((size.x / 2) * scale.x, (size.z / 2) * scale.z);
|
|
74
75
|
description = ColliderDesc.capsule((size.y / 2) * scale.y - radius, radius);
|
|
75
76
|
}
|
|
76
77
|
break;
|
|
77
78
|
case 'convexHull':
|
|
78
|
-
// eslint-disable-next-line no-case-declarations
|
|
79
|
-
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
|
80
79
|
{
|
|
81
|
-
description = ColliderDesc.convexHull(
|
|
80
|
+
description = ColliderDesc.convexHull(new Float32Array(geometry.attributes.position.array));
|
|
82
81
|
}
|
|
83
82
|
break;
|
|
84
83
|
}
|
|
85
84
|
description
|
|
86
|
-
.setTranslation(x + offset.x, y + offset.y, z + offset.z)
|
|
87
|
-
.setRotation(
|
|
85
|
+
.setTranslation(translation.x + offset.x, translation.y + offset.y, translation.z + offset.z)
|
|
86
|
+
.setRotation(rotation)
|
|
88
87
|
.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
|
89
88
|
const collider = world.createCollider(description, rigidBody);
|
|
90
89
|
colliders.push(collider);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
const key = Symbol('threlte-rapier-rigidbody-object3d');
|
|
3
|
+
export const useParentRigidbodyObject = () => {
|
|
4
|
+
return getContext(key);
|
|
5
|
+
};
|
|
6
|
+
export const setParentRigidbodyObject = (object3d) => {
|
|
7
|
+
setContext(key, object3d);
|
|
8
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { onDestroy } from 'svelte';
|
|
2
|
+
import { createRawEventDispatcher } from '@threlte/core';
|
|
3
|
+
export const useCreateEvent = () => {
|
|
4
|
+
const dispatchRaw = createRawEventDispatcher();
|
|
5
|
+
const cleanupFunctions = [];
|
|
6
|
+
let ref = undefined;
|
|
7
|
+
const dispatchCreateEvent = () => {
|
|
8
|
+
// call every cleanup function
|
|
9
|
+
cleanupFunctions.forEach((cleanup) => cleanup());
|
|
10
|
+
// clear the cleanup functions array
|
|
11
|
+
cleanupFunctions.length = 0;
|
|
12
|
+
const cleanup = (callback) => {
|
|
13
|
+
// add cleanup function to array
|
|
14
|
+
cleanupFunctions.push(callback);
|
|
15
|
+
};
|
|
16
|
+
if (ref === undefined)
|
|
17
|
+
return;
|
|
18
|
+
dispatchRaw('create', { ref, cleanup });
|
|
19
|
+
};
|
|
20
|
+
const updateRef = (newRef) => {
|
|
21
|
+
ref = newRef;
|
|
22
|
+
dispatchCreateEvent();
|
|
23
|
+
};
|
|
24
|
+
onDestroy(() => {
|
|
25
|
+
// call every cleanup function
|
|
26
|
+
cleanupFunctions.forEach((cleanup) => cleanup());
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
updateRef
|
|
30
|
+
};
|
|
31
|
+
};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ import type { createRapierContext } from '../lib/createRapierContext';
|
|
|
6
6
|
export type ColliderShapes = 'ball' | 'capsule' | 'segment' | 'triangle' | 'roundTriangle' | 'polyline' | 'trimesh' | 'cuboid' | 'roundCuboid' | 'heightfield' | 'cylinder' | 'roundCylinder' | 'cone' | 'roundCone' | 'convexHull' | 'convexMesh' | 'roundConvexHull' | 'roundConvexMesh';
|
|
7
7
|
export type AutoCollidersShapes = 'cuboid' | 'ball' | 'trimesh' | 'convexHull' | 'capsule';
|
|
8
8
|
export type ColliderEventMap = {
|
|
9
|
+
create: {
|
|
10
|
+
ref: Collider;
|
|
11
|
+
cleanup: (callback: () => void) => void;
|
|
12
|
+
};
|
|
9
13
|
collisionenter: {
|
|
10
14
|
targetCollider: Collider;
|
|
11
15
|
targetRigidBody: RigidBody | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threlte/rapier",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"author": "Grischa Erbe <hello@legrisch.com> (https://legrisch.com)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"devDependencies": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"type-fest": "^2.13.0",
|
|
28
28
|
"typescript": "^5.0.0",
|
|
29
29
|
"vite": "^4.3.6",
|
|
30
|
-
"@threlte/core": "6.
|
|
30
|
+
"@threlte/core": "6.1.1"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"svelte": ">=4",
|