angular-three-cannon 1.5.2 → 2.0.0-beta.2
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 +4 -12
- package/debug/{lib/debug.d.ts → debug.d.ts} +10 -10
- package/debug/index.d.ts +1 -1
- package/esm2022/angular-three-cannon.mjs +5 -0
- package/esm2022/debug/angular-three-cannon-debug.mjs +5 -0
- package/esm2022/debug/debug.mjs +99 -0
- package/esm2022/debug/index.mjs +2 -0
- package/esm2022/index.mjs +2 -0
- package/esm2022/physics.mjs +297 -0
- package/esm2022/services/angular-three-cannon-services.mjs +5 -0
- package/esm2022/services/body.mjs +289 -0
- package/esm2022/services/constraint.mjs +59 -0
- package/esm2022/services/contact-material.mjs +20 -0
- package/esm2022/services/index.mjs +7 -0
- package/esm2022/services/ray.mjs +30 -0
- package/esm2022/services/raycast-vehicle.mjs +72 -0
- package/esm2022/services/spring.mjs +34 -0
- package/fesm2022/angular-three-cannon-debug.mjs +105 -0
- package/fesm2022/angular-three-cannon-debug.mjs.map +1 -0
- package/fesm2022/angular-three-cannon-services.mjs +494 -0
- package/fesm2022/angular-three-cannon-services.mjs.map +1 -0
- package/fesm2022/angular-three-cannon.mjs +303 -0
- package/fesm2022/angular-three-cannon.mjs.map +1 -0
- package/index.d.ts +1 -3
- package/package.json +19 -29
- package/physics.d.ts +97 -0
- package/plugin/package.json +2 -2
- package/plugin/src/generators/init/compat.js +1 -1
- package/plugin/src/generators/init/compat.js.map +1 -1
- package/plugin/src/generators/init/init.d.ts +2 -2
- package/plugin/src/generators/init/init.js +16 -20
- package/plugin/src/generators/init/init.js.map +1 -1
- package/plugin/src/index.js.map +1 -1
- package/services/{lib/body.d.ts → body.d.ts} +19 -39
- package/services/constraint.d.ts +31 -0
- package/services/contact-material.d.ts +9 -0
- package/services/index.d.ts +6 -6
- package/services/ray.d.ts +12 -0
- package/services/{lib/raycast-vehicle.d.ts → raycast-vehicle.d.ts} +8 -3
- package/services/{lib/spring.d.ts → spring.d.ts} +8 -3
- package/esm2020/angular-three-cannon.mjs +0 -5
- package/esm2020/debug/angular-three-cannon-debug.mjs +0 -5
- package/esm2020/debug/index.mjs +0 -2
- package/esm2020/debug/lib/debug.mjs +0 -117
- package/esm2020/index.mjs +0 -4
- package/esm2020/lib/physics.mjs +0 -261
- package/esm2020/lib/store.mjs +0 -21
- package/esm2020/lib/utils.mjs +0 -47
- package/esm2020/services/angular-three-cannon-services.mjs +0 -5
- package/esm2020/services/index.mjs +0 -7
- package/esm2020/services/lib/body.mjs +0 -271
- package/esm2020/services/lib/constraint.mjs +0 -69
- package/esm2020/services/lib/contact-material.mjs +0 -18
- package/esm2020/services/lib/ray.mjs +0 -32
- package/esm2020/services/lib/raycast-vehicle.mjs +0 -76
- package/esm2020/services/lib/spring.mjs +0 -37
- package/esm2020/services/lib/utils.mjs +0 -5
- package/fesm2015/angular-three-cannon-debug.mjs +0 -124
- package/fesm2015/angular-three-cannon-debug.mjs.map +0 -1
- package/fesm2015/angular-three-cannon-services.mjs +0 -488
- package/fesm2015/angular-three-cannon-services.mjs.map +0 -1
- package/fesm2015/angular-three-cannon.mjs +0 -333
- package/fesm2015/angular-three-cannon.mjs.map +0 -1
- package/fesm2020/angular-three-cannon-debug.mjs +0 -124
- package/fesm2020/angular-three-cannon-debug.mjs.map +0 -1
- package/fesm2020/angular-three-cannon-services.mjs +0 -489
- package/fesm2020/angular-three-cannon-services.mjs.map +0 -1
- package/fesm2020/angular-three-cannon.mjs +0 -331
- package/fesm2020/angular-three-cannon.mjs.map +0 -1
- package/lib/physics.d.ts +0 -43
- package/lib/store.d.ts +0 -34
- package/lib/utils.d.ts +0 -16
- package/services/lib/constraint.d.ts +0 -25
- package/services/lib/contact-material.d.ts +0 -3
- package/services/lib/ray.d.ts +0 -4
- package/services/lib/utils.d.ts +0 -2
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { computed, effect, inject, runInInjectionContext, untracked } from '@angular/core';
|
|
2
|
+
import { assertInjectionContext, injectNgtRef, is, makeId } from 'angular-three';
|
|
3
|
+
import { NGTC_PHYSICS_API } from 'angular-three-cannon';
|
|
4
|
+
export function injectSpring(bodyA, bodyB, { injector, opts = () => ({}), deps = () => ({}), } = {}) {
|
|
5
|
+
injector = assertInjectionContext(injectSpring, injector);
|
|
6
|
+
return runInInjectionContext(injector, () => {
|
|
7
|
+
const physicsApi = inject(NGTC_PHYSICS_API);
|
|
8
|
+
const { worker } = physicsApi();
|
|
9
|
+
const uuid = makeId();
|
|
10
|
+
const bodyARef = is.ref(bodyA) ? bodyA : injectNgtRef(bodyA);
|
|
11
|
+
const bodyBRef = is.ref(bodyB) ? bodyB : injectNgtRef(bodyB);
|
|
12
|
+
effect((onCleanup) => {
|
|
13
|
+
deps();
|
|
14
|
+
if (bodyARef.nativeElement && bodyBRef.nativeElement) {
|
|
15
|
+
worker.addSpring({
|
|
16
|
+
props: [bodyARef.nativeElement.uuid, bodyBRef.nativeElement.uuid, untracked(opts)],
|
|
17
|
+
uuid,
|
|
18
|
+
});
|
|
19
|
+
onCleanup(() => worker.removeSpring({ uuid }));
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const api = computed(() => {
|
|
23
|
+
deps();
|
|
24
|
+
return {
|
|
25
|
+
setDamping: (value) => worker.setSpringDamping({ props: value, uuid }),
|
|
26
|
+
setRestLength: (value) => worker.setSpringRestLength({ props: value, uuid }),
|
|
27
|
+
setStiffness: (value) => worker.setSpringStiffness({ props: value, uuid }),
|
|
28
|
+
remove: () => worker.removeSpring({ uuid }),
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
return { bodyA: bodyARef, bodyB: bodyBRef, api };
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ByaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9jYW5ub24vc2VydmljZXMvc3JjL3NwcmluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQW9CLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLHFCQUFxQixFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU3RyxPQUFPLEVBQWdDLHNCQUFzQixFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9HLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBa0J4RCxNQUFNLFVBQVUsWUFBWSxDQUN4QixLQUE0QixFQUM1QixLQUE0QixFQUM1QixFQUNJLFFBQVEsRUFDUixJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFDakIsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQzZELEVBQUU7SUFFcEYsUUFBUSxHQUFHLHNCQUFzQixDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMxRCxPQUFPLHFCQUFxQixDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUU7UUFDeEMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDNUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLFVBQVUsRUFBRSxDQUFDO1FBRWhDLE1BQU0sSUFBSSxHQUFHLE1BQU0sRUFBRSxDQUFDO1FBRXRCLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdELE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRTdELE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1lBQ2pCLElBQUksRUFBRSxDQUFDO1lBQ1AsSUFBSSxRQUFRLENBQUMsYUFBYSxJQUFJLFFBQVEsQ0FBQyxhQUFhLEVBQUU7Z0JBQ2xELE1BQU0sQ0FBQyxTQUFTLENBQUM7b0JBQ2IsS0FBSyxFQUFFLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNsRixJQUFJO2lCQUNQLENBQUMsQ0FBQztnQkFDSCxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQzthQUNsRDtRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUN0QixJQUFJLEVBQUUsQ0FBQztZQUNQLE9BQU87Z0JBQ0gsVUFBVSxFQUFFLENBQUMsS0FBYSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDO2dCQUM5RSxhQUFhLEVBQUUsQ0FBQyxLQUFhLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUM7Z0JBQ3BGLFlBQVksRUFBRSxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQztnQkFDbEYsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQzthQUM5QyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ3JELENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdG9yLCBTaWduYWwsIGNvbXB1dGVkLCBlZmZlY3QsIGluamVjdCwgcnVuSW5JbmplY3Rpb25Db250ZXh0LCB1bnRyYWNrZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFNwcmluZ09wdG5zIH0gZnJvbSAnQHBtbmRycy9jYW5ub24td29ya2VyLWFwaSc7XG5pbXBvcnQgeyBOZ3RBbnlSZWNvcmQsIE5ndEluamVjdGVkUmVmLCBhc3NlcnRJbmplY3Rpb25Db250ZXh0LCBpbmplY3ROZ3RSZWYsIGlzLCBtYWtlSWQgfSBmcm9tICdhbmd1bGFyLXRocmVlJztcbmltcG9ydCB7IE5HVENfUEhZU0lDU19BUEkgfSBmcm9tICdhbmd1bGFyLXRocmVlLWNhbm5vbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmd0Y1NwcmluZ0FwaSB7XG4gICAgc2V0RGFtcGluZzogKHZhbHVlOiBudW1iZXIpID0+IHZvaWQ7XG4gICAgc2V0UmVzdExlbmd0aDogKHZhbHVlOiBudW1iZXIpID0+IHZvaWQ7XG4gICAgc2V0U3RpZmZuZXNzOiAodmFsdWU6IG51bWJlcikgPT4gdm9pZDtcbiAgICByZW1vdmU6ICgpID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmd0Y1NwcmluZ1JldHVybjxcbiAgICBUT2JqZWN0QSBleHRlbmRzIFRIUkVFLk9iamVjdDNEID0gVEhSRUUuT2JqZWN0M0QsXG4gICAgVE9iamVjdEIgZXh0ZW5kcyBUSFJFRS5PYmplY3QzRCA9IFRIUkVFLk9iamVjdDNEXG4+IHtcbiAgICBib2R5QTogTmd0SW5qZWN0ZWRSZWY8VE9iamVjdEE+O1xuICAgIGJvZHlCOiBOZ3RJbmplY3RlZFJlZjxUT2JqZWN0Qj47XG4gICAgYXBpOiBTaWduYWw8Tmd0Y1NwcmluZ0FwaT47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RTcHJpbmc8QSBleHRlbmRzIFRIUkVFLk9iamVjdDNELCBCIGV4dGVuZHMgVEhSRUUuT2JqZWN0M0Q+KFxuICAgIGJvZHlBOiBOZ3RJbmplY3RlZFJlZjxBPiB8IEEsXG4gICAgYm9keUI6IE5ndEluamVjdGVkUmVmPEI+IHwgQixcbiAgICB7XG4gICAgICAgIGluamVjdG9yLFxuICAgICAgICBvcHRzID0gKCkgPT4gKHt9KSxcbiAgICAgICAgZGVwcyA9ICgpID0+ICh7fSksXG4gICAgfTogeyBpbmplY3Rvcj86IEluamVjdG9yOyBkZXBzPzogKCkgPT4gTmd0QW55UmVjb3JkOyBvcHRzPzogKCkgPT4gU3ByaW5nT3B0bnMgfSA9IHt9XG4pOiBOZ3RjU3ByaW5nUmV0dXJuPEEsIEI+IHtcbiAgICBpbmplY3RvciA9IGFzc2VydEluamVjdGlvbkNvbnRleHQoaW5qZWN0U3ByaW5nLCBpbmplY3Rvcik7XG4gICAgcmV0dXJuIHJ1bkluSW5qZWN0aW9uQ29udGV4dChpbmplY3RvciwgKCkgPT4ge1xuICAgICAgICBjb25zdCBwaHlzaWNzQXBpID0gaW5qZWN0KE5HVENfUEhZU0lDU19BUEkpO1xuICAgICAgICBjb25zdCB7IHdvcmtlciB9ID0gcGh5c2ljc0FwaSgpO1xuXG4gICAgICAgIGNvbnN0IHV1aWQgPSBtYWtlSWQoKTtcblxuICAgICAgICBjb25zdCBib2R5QVJlZiA9IGlzLnJlZihib2R5QSkgPyBib2R5QSA6IGluamVjdE5ndFJlZihib2R5QSk7XG4gICAgICAgIGNvbnN0IGJvZHlCUmVmID0gaXMucmVmKGJvZHlCKSA/IGJvZHlCIDogaW5qZWN0Tmd0UmVmKGJvZHlCKTtcblxuICAgICAgICBlZmZlY3QoKG9uQ2xlYW51cCkgPT4ge1xuICAgICAgICAgICAgZGVwcygpO1xuICAgICAgICAgICAgaWYgKGJvZHlBUmVmLm5hdGl2ZUVsZW1lbnQgJiYgYm9keUJSZWYubmF0aXZlRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHdvcmtlci5hZGRTcHJpbmcoe1xuICAgICAgICAgICAgICAgICAgICBwcm9wczogW2JvZHlBUmVmLm5hdGl2ZUVsZW1lbnQudXVpZCwgYm9keUJSZWYubmF0aXZlRWxlbWVudC51dWlkLCB1bnRyYWNrZWQob3B0cyldLFxuICAgICAgICAgICAgICAgICAgICB1dWlkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG9uQ2xlYW51cCgoKSA9PiB3b3JrZXIucmVtb3ZlU3ByaW5nKHsgdXVpZCB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFwaSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgICAgIGRlcHMoKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc2V0RGFtcGluZzogKHZhbHVlOiBudW1iZXIpID0+IHdvcmtlci5zZXRTcHJpbmdEYW1waW5nKHsgcHJvcHM6IHZhbHVlLCB1dWlkIH0pLFxuICAgICAgICAgICAgICAgIHNldFJlc3RMZW5ndGg6ICh2YWx1ZTogbnVtYmVyKSA9PiB3b3JrZXIuc2V0U3ByaW5nUmVzdExlbmd0aCh7IHByb3BzOiB2YWx1ZSwgdXVpZCB9KSxcbiAgICAgICAgICAgICAgICBzZXRTdGlmZm5lc3M6ICh2YWx1ZTogbnVtYmVyKSA9PiB3b3JrZXIuc2V0U3ByaW5nU3RpZmZuZXNzKHsgcHJvcHM6IHZhbHVlLCB1dWlkIH0pLFxuICAgICAgICAgICAgICAgIHJlbW92ZTogKCkgPT4gd29ya2VyLnJlbW92ZVNwcmluZyh7IHV1aWQgfSksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyBib2R5QTogYm9keUFSZWYsIGJvZHlCOiBib2R5QlJlZiwgYXBpIH07XG4gICAgfSk7XG59XG4iXX0=
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, computed, Component, CUSTOM_ELEMENTS_SCHEMA, Input } from '@angular/core';
|
|
3
|
+
import { propsToBody } from '@pmndrs/cannon-worker-api';
|
|
4
|
+
import { injectBeforeRender, NgtArgs } from 'angular-three';
|
|
5
|
+
import { NGTC_PHYSICS_API } from 'angular-three-cannon';
|
|
6
|
+
import CannonDebugger from 'cannon-es-debugger';
|
|
7
|
+
import * as THREE from 'three';
|
|
8
|
+
|
|
9
|
+
const q = new THREE.Quaternion();
|
|
10
|
+
const s = new THREE.Vector3(1, 1, 1);
|
|
11
|
+
const v = new THREE.Vector3();
|
|
12
|
+
const m = new THREE.Matrix4();
|
|
13
|
+
function getMatrix(o) {
|
|
14
|
+
if (o instanceof THREE.InstancedMesh) {
|
|
15
|
+
o.getMatrixAt(parseInt(o.uuid.split('/')[1]), m);
|
|
16
|
+
return m;
|
|
17
|
+
}
|
|
18
|
+
return o.matrix;
|
|
19
|
+
}
|
|
20
|
+
const NGTC_DEBUG_API = new InjectionToken('NgtcDebug API');
|
|
21
|
+
class NgtcDebug {
|
|
22
|
+
#bodies;
|
|
23
|
+
#bodyMap;
|
|
24
|
+
#physicsApi;
|
|
25
|
+
#cannonDebugger;
|
|
26
|
+
constructor() {
|
|
27
|
+
this.color = 'black';
|
|
28
|
+
this.scale = 1;
|
|
29
|
+
this.impl = CannonDebugger;
|
|
30
|
+
this.disabled = false;
|
|
31
|
+
this.#bodies = [];
|
|
32
|
+
this.#bodyMap = {};
|
|
33
|
+
this.scene = new THREE.Scene();
|
|
34
|
+
this.#physicsApi = inject(NGTC_PHYSICS_API);
|
|
35
|
+
this.api = computed(() => ({
|
|
36
|
+
add: (uuid, props, type) => {
|
|
37
|
+
const body = propsToBody({ uuid, props, type });
|
|
38
|
+
this.#bodies.push(body);
|
|
39
|
+
this.#bodyMap[uuid] = body;
|
|
40
|
+
},
|
|
41
|
+
remove: (id) => {
|
|
42
|
+
const debugBodyIndex = this.#bodies.indexOf(this.#bodyMap[id]);
|
|
43
|
+
if (debugBodyIndex > -1)
|
|
44
|
+
this.#bodies.splice(debugBodyIndex, 1);
|
|
45
|
+
delete this.#bodyMap[id];
|
|
46
|
+
},
|
|
47
|
+
}));
|
|
48
|
+
injectBeforeRender(() => {
|
|
49
|
+
if (!this.#cannonDebugger)
|
|
50
|
+
return;
|
|
51
|
+
const refs = this.#physicsApi().refs;
|
|
52
|
+
for (const uuid in this.#bodyMap) {
|
|
53
|
+
getMatrix(refs[uuid]).decompose(v, q, s);
|
|
54
|
+
this.#bodyMap[uuid].position.copy(v);
|
|
55
|
+
this.#bodyMap[uuid].quaternion.copy(q);
|
|
56
|
+
}
|
|
57
|
+
for (const child of this.scene.children) {
|
|
58
|
+
child.visible = !this.disabled;
|
|
59
|
+
}
|
|
60
|
+
if (!this.disabled) {
|
|
61
|
+
this.#cannonDebugger.update();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
ngOnInit() {
|
|
66
|
+
this.#cannonDebugger = this.impl(this.scene, { bodies: this.#bodies }, {
|
|
67
|
+
color: this.color,
|
|
68
|
+
scale: this.scale,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtcDebug, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
72
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtcDebug, isStandalone: true, selector: "ngtc-debug", inputs: { color: "color", scale: "scale", impl: "impl", disabled: "disabled" }, providers: [{ provide: NGTC_DEBUG_API, useFactory: (debug) => debug.api, deps: [NgtcDebug] }], ngImport: i0, template: `
|
|
73
|
+
<ngt-primitive *args="[scene]" />
|
|
74
|
+
<ng-content />
|
|
75
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
|
|
76
|
+
}
|
|
77
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtcDebug, decorators: [{
|
|
78
|
+
type: Component,
|
|
79
|
+
args: [{
|
|
80
|
+
selector: 'ngtc-debug',
|
|
81
|
+
standalone: true,
|
|
82
|
+
template: `
|
|
83
|
+
<ngt-primitive *args="[scene]" />
|
|
84
|
+
<ng-content />
|
|
85
|
+
`,
|
|
86
|
+
providers: [{ provide: NGTC_DEBUG_API, useFactory: (debug) => debug.api, deps: [NgtcDebug] }],
|
|
87
|
+
imports: [NgtArgs],
|
|
88
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
89
|
+
}]
|
|
90
|
+
}], ctorParameters: function () { return []; }, propDecorators: { color: [{
|
|
91
|
+
type: Input
|
|
92
|
+
}], scale: [{
|
|
93
|
+
type: Input
|
|
94
|
+
}], impl: [{
|
|
95
|
+
type: Input
|
|
96
|
+
}], disabled: [{
|
|
97
|
+
type: Input
|
|
98
|
+
}] } });
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Generated bundle index. Do not edit.
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
export { NGTC_DEBUG_API, NgtcDebug };
|
|
105
|
+
//# sourceMappingURL=angular-three-cannon-debug.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angular-three-cannon-debug.mjs","sources":["../../../../libs/cannon/debug/src/debug.ts","../../../../libs/cannon/debug/src/angular-three-cannon-debug.ts"],"sourcesContent":["import {\n Component,\n computed,\n CUSTOM_ELEMENTS_SCHEMA,\n inject,\n InjectionToken,\n Input,\n OnInit,\n Signal,\n} from '@angular/core';\nimport { BodyProps, BodyShapeType, propsToBody } from '@pmndrs/cannon-worker-api';\nimport { injectBeforeRender, NgtArgs } from 'angular-three';\nimport { NGTC_PHYSICS_API } from 'angular-three-cannon';\nimport { Body, Quaternion as CQuarternion, Vec3, World } from 'cannon-es';\nimport CannonDebugger from 'cannon-es-debugger';\nimport * as THREE from 'three';\n\nconst q = new THREE.Quaternion();\nconst s = new THREE.Vector3(1, 1, 1);\nconst v = new THREE.Vector3();\nconst m = new THREE.Matrix4();\n\nfunction getMatrix(o: THREE.Object3D): THREE.Matrix4 {\n if (o instanceof THREE.InstancedMesh) {\n o.getMatrixAt(parseInt(o.uuid.split('/')[1]), m);\n return m;\n }\n return o.matrix;\n}\n\nexport interface NgtcDebugApi {\n add(id: string, props: BodyProps, type: BodyShapeType): void;\n remove(id: string): void;\n}\n\nexport const NGTC_DEBUG_API = new InjectionToken<Signal<NgtcDebugApi>>('NgtcDebug API');\n\n@Component({\n selector: 'ngtc-debug',\n standalone: true,\n template: `\n <ngt-primitive *args=\"[scene]\" />\n <ng-content />\n `,\n providers: [{ provide: NGTC_DEBUG_API, useFactory: (debug: NgtcDebug) => debug.api, deps: [NgtcDebug] }],\n imports: [NgtArgs],\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n})\nexport class NgtcDebug implements OnInit {\n @Input() color = 'black';\n @Input() scale = 1;\n @Input() impl = CannonDebugger;\n @Input() disabled = false;\n\n readonly #bodies: Body[] = [];\n readonly #bodyMap: Record<string, Body> = {};\n readonly scene = new THREE.Scene();\n\n readonly #physicsApi = inject(NGTC_PHYSICS_API);\n\n #cannonDebugger!: ReturnType<typeof CannonDebugger>;\n\n readonly api = computed(() => ({\n add: (uuid: string, props: BodyProps, type: BodyShapeType) => {\n const body = propsToBody({ uuid, props, type });\n this.#bodies.push(body);\n this.#bodyMap[uuid] = body;\n },\n remove: (id: string) => {\n const debugBodyIndex = this.#bodies.indexOf(this.#bodyMap[id]);\n if (debugBodyIndex > -1) this.#bodies.splice(debugBodyIndex, 1);\n delete this.#bodyMap[id];\n },\n }));\n\n constructor() {\n injectBeforeRender(() => {\n if (!this.#cannonDebugger) return;\n const refs = this.#physicsApi().refs;\n for (const uuid in this.#bodyMap) {\n getMatrix(refs[uuid]).decompose(v, q, s);\n this.#bodyMap[uuid].position.copy(v as unknown as Vec3);\n this.#bodyMap[uuid].quaternion.copy(q as unknown as CQuarternion);\n }\n\n for (const child of this.scene.children) {\n child.visible = !this.disabled;\n }\n\n if (!this.disabled) {\n this.#cannonDebugger.update();\n }\n });\n }\n\n ngOnInit() {\n this.#cannonDebugger = this.impl(this.scene, { bodies: this.#bodies } as World, {\n color: this.color,\n scale: this.scale,\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
import { runInInjectionContext, inject, effect, computed, untracked } from '@angular/core';
|
|
2
|
+
import { assertInjectionContext, injectNgtRef, makeId, is } from 'angular-three';
|
|
3
|
+
import { NGTC_PHYSICS_API } from 'angular-three-cannon';
|
|
4
|
+
import { NGTC_DEBUG_API } from 'angular-three-cannon/debug';
|
|
5
|
+
import * as THREE from 'three';
|
|
6
|
+
|
|
7
|
+
const temp = new THREE.Object3D();
|
|
8
|
+
function capitalize(str) {
|
|
9
|
+
return (str.charAt(0).toUpperCase() + str.slice(1));
|
|
10
|
+
}
|
|
11
|
+
function getUUID(ref, index) {
|
|
12
|
+
const suffix = index === undefined ? '' : `/${index}`;
|
|
13
|
+
if (typeof ref === 'function')
|
|
14
|
+
return null;
|
|
15
|
+
return ref && ref.nativeElement && `${ref.nativeElement.uuid}${suffix}`;
|
|
16
|
+
}
|
|
17
|
+
const e = new THREE.Euler();
|
|
18
|
+
const q = new THREE.Quaternion();
|
|
19
|
+
const quaternionToRotation = (callback) => {
|
|
20
|
+
return (v) => callback(e.setFromQuaternion(q.fromArray(v)).toArray());
|
|
21
|
+
};
|
|
22
|
+
let incrementingId = 0;
|
|
23
|
+
function subscribe(ref, worker, subscriptions, type, index, target = 'bodies') {
|
|
24
|
+
return (callback) => {
|
|
25
|
+
const id = incrementingId++;
|
|
26
|
+
subscriptions[id] = { [type]: callback };
|
|
27
|
+
const uuid = getUUID(ref, index);
|
|
28
|
+
uuid && worker.subscribe({ props: { id, target, type }, uuid });
|
|
29
|
+
return () => {
|
|
30
|
+
delete subscriptions[id];
|
|
31
|
+
worker.unsubscribe({ props: id });
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function prepare(object, { position = [0, 0, 0], rotation = [0, 0, 0], userData = {} }) {
|
|
36
|
+
object.userData = userData;
|
|
37
|
+
object.position.set(...position);
|
|
38
|
+
object.rotation.set(...rotation);
|
|
39
|
+
object.updateMatrix();
|
|
40
|
+
}
|
|
41
|
+
function setupCollision(events, { onCollide, onCollideBegin, onCollideEnd }, uuid) {
|
|
42
|
+
events[uuid] = {
|
|
43
|
+
collide: onCollide,
|
|
44
|
+
collideBegin: onCollideBegin,
|
|
45
|
+
collideEnd: onCollideEnd,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function makeTriplet(v) {
|
|
49
|
+
return v instanceof THREE.Vector3 ? [v.x, v.y, v.z] : v;
|
|
50
|
+
}
|
|
51
|
+
function injectPlane(fn, opts) {
|
|
52
|
+
return injectBody('Plane', fn, () => [], opts);
|
|
53
|
+
}
|
|
54
|
+
function injectBox(fn, opts) {
|
|
55
|
+
const defaultBoxArgs = [1, 1, 1];
|
|
56
|
+
return injectBody('Box', fn, (args = defaultBoxArgs) => args, opts);
|
|
57
|
+
}
|
|
58
|
+
function injectCylinder(fn, opts) {
|
|
59
|
+
return injectBody('Cylinder', fn, (args = []) => args, opts);
|
|
60
|
+
}
|
|
61
|
+
function injectHeightfield(fn, opts) {
|
|
62
|
+
return injectBody('Heightfield', fn, (args) => args, opts);
|
|
63
|
+
}
|
|
64
|
+
function injectParticle(fn, opts) {
|
|
65
|
+
return injectBody('Particle', fn, () => [], opts);
|
|
66
|
+
}
|
|
67
|
+
function injectSphere(fn, opts) {
|
|
68
|
+
return injectBody('Sphere', fn, (args = [1]) => {
|
|
69
|
+
if (!Array.isArray(args))
|
|
70
|
+
throw new Error('useSphere args must be an array');
|
|
71
|
+
return [args[0]];
|
|
72
|
+
}, opts);
|
|
73
|
+
}
|
|
74
|
+
function injectTrimesh(fn, opts) {
|
|
75
|
+
return injectBody('Trimesh', fn, (args) => args, opts);
|
|
76
|
+
}
|
|
77
|
+
function injectConvexPolyhedron(fn, opts) {
|
|
78
|
+
return injectBody('ConvexPolyhedron', fn, ([vertices, faces, normals, axes, boundingSphereRadius] = []) => [
|
|
79
|
+
vertices && vertices.map(makeTriplet),
|
|
80
|
+
faces,
|
|
81
|
+
normals && normals.map(makeTriplet),
|
|
82
|
+
axes && axes.map(makeTriplet),
|
|
83
|
+
boundingSphereRadius,
|
|
84
|
+
], opts);
|
|
85
|
+
}
|
|
86
|
+
function injectCompoundBody(fn, opts) {
|
|
87
|
+
return injectBody('Compound', fn, (args) => args, opts);
|
|
88
|
+
}
|
|
89
|
+
function injectBody(type, getPropsFn, argsFn, { ref, injector, deps = () => ({}) } = {}) {
|
|
90
|
+
injector = assertInjectionContext(injectBody, injector);
|
|
91
|
+
return runInInjectionContext(injector, () => {
|
|
92
|
+
let bodyRef = injectNgtRef();
|
|
93
|
+
if (ref)
|
|
94
|
+
bodyRef = ref;
|
|
95
|
+
const physicsApi = inject(NGTC_PHYSICS_API);
|
|
96
|
+
const debugApi = inject(NGTC_DEBUG_API, { optional: true });
|
|
97
|
+
const { refs, worker, subscriptions, scaleOverrides, events } = physicsApi();
|
|
98
|
+
const { add: debugAdd, remove: debugRemove } = debugApi?.() || {};
|
|
99
|
+
effect((onCleanup) => {
|
|
100
|
+
// register deps
|
|
101
|
+
deps();
|
|
102
|
+
if (!bodyRef.untracked) {
|
|
103
|
+
bodyRef.nativeElement = new THREE.Object3D();
|
|
104
|
+
}
|
|
105
|
+
const object = bodyRef.untracked;
|
|
106
|
+
const currentWorker = worker;
|
|
107
|
+
const objectCount = object instanceof THREE.InstancedMesh
|
|
108
|
+
? (object.instanceMatrix.setUsage(THREE.DynamicDrawUsage), object.count)
|
|
109
|
+
: 1;
|
|
110
|
+
const uuid = object instanceof THREE.InstancedMesh
|
|
111
|
+
? new Array(objectCount).fill(0).map((_, i) => `${object.uuid}/${i}`)
|
|
112
|
+
: [object.uuid];
|
|
113
|
+
const props = object instanceof THREE.InstancedMesh
|
|
114
|
+
? uuid.map((id, i) => {
|
|
115
|
+
const props = getPropsFn(i);
|
|
116
|
+
prepare(temp, props);
|
|
117
|
+
object.setMatrixAt(i, temp.matrix);
|
|
118
|
+
object.instanceMatrix.needsUpdate = true;
|
|
119
|
+
refs[id] = object;
|
|
120
|
+
debugAdd?.(id, props, type);
|
|
121
|
+
setupCollision(events, props, id);
|
|
122
|
+
return { ...props, args: argsFn(props.args) };
|
|
123
|
+
})
|
|
124
|
+
: uuid.map((id, i) => {
|
|
125
|
+
const props = getPropsFn(i);
|
|
126
|
+
prepare(object, props);
|
|
127
|
+
refs[id] = object;
|
|
128
|
+
debugAdd?.(id, props, type);
|
|
129
|
+
setupCollision(events, props, id);
|
|
130
|
+
return { ...props, args: argsFn(props.args) };
|
|
131
|
+
});
|
|
132
|
+
// Register on mount, unregister on unmount
|
|
133
|
+
currentWorker.addBodies({
|
|
134
|
+
props: props.map(({ onCollide, onCollideBegin, onCollideEnd, ...serializableProps }) => {
|
|
135
|
+
return { onCollide: Boolean(onCollide), ...serializableProps };
|
|
136
|
+
}),
|
|
137
|
+
type,
|
|
138
|
+
uuid,
|
|
139
|
+
});
|
|
140
|
+
onCleanup(() => {
|
|
141
|
+
uuid.forEach((id) => {
|
|
142
|
+
delete refs[id];
|
|
143
|
+
debugRemove?.(id);
|
|
144
|
+
delete events[id];
|
|
145
|
+
});
|
|
146
|
+
currentWorker.removeBodies({ uuid });
|
|
147
|
+
});
|
|
148
|
+
}, { allowSignalWrites: true });
|
|
149
|
+
const api = computed(() => {
|
|
150
|
+
const makeAtomic = (type, index) => {
|
|
151
|
+
const op = `set${capitalize(type)}`;
|
|
152
|
+
return {
|
|
153
|
+
set: (value) => {
|
|
154
|
+
const uuid = getUUID(bodyRef, index);
|
|
155
|
+
uuid &&
|
|
156
|
+
worker[op]({
|
|
157
|
+
props: value,
|
|
158
|
+
uuid,
|
|
159
|
+
});
|
|
160
|
+
},
|
|
161
|
+
subscribe: subscribe(bodyRef, worker, subscriptions, type, index),
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
const makeQuaternion = (index) => {
|
|
165
|
+
const type = 'quaternion';
|
|
166
|
+
return {
|
|
167
|
+
copy: ({ w, x, y, z }) => {
|
|
168
|
+
const uuid = getUUID(bodyRef, index);
|
|
169
|
+
uuid && worker.setQuaternion({ props: [x, y, z, w], uuid });
|
|
170
|
+
},
|
|
171
|
+
set: (x, y, z, w) => {
|
|
172
|
+
const uuid = getUUID(bodyRef, index);
|
|
173
|
+
uuid && worker.setQuaternion({ props: [x, y, z, w], uuid });
|
|
174
|
+
},
|
|
175
|
+
subscribe: subscribe(bodyRef, worker, subscriptions, type, index),
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
const makeRotation = (index) => {
|
|
179
|
+
return {
|
|
180
|
+
copy: ({ x, y, z }) => {
|
|
181
|
+
const uuid = getUUID(bodyRef, index);
|
|
182
|
+
uuid && worker.setRotation({ props: [x, y, z], uuid });
|
|
183
|
+
},
|
|
184
|
+
set: (x, y, z) => {
|
|
185
|
+
const uuid = getUUID(bodyRef, index);
|
|
186
|
+
uuid && worker.setRotation({ props: [x, y, z], uuid });
|
|
187
|
+
},
|
|
188
|
+
subscribe: (callback) => {
|
|
189
|
+
const id = incrementingId++;
|
|
190
|
+
const target = 'bodies';
|
|
191
|
+
const type = 'quaternion';
|
|
192
|
+
const uuid = getUUID(bodyRef, index);
|
|
193
|
+
subscriptions[id] = { [type]: quaternionToRotation(callback) };
|
|
194
|
+
uuid && worker.subscribe({ props: { id, target, type }, uuid });
|
|
195
|
+
return () => {
|
|
196
|
+
delete subscriptions[id];
|
|
197
|
+
worker.unsubscribe({ props: id });
|
|
198
|
+
};
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
const makeVec = (type, index) => {
|
|
203
|
+
const op = `set${capitalize(type)}`;
|
|
204
|
+
return {
|
|
205
|
+
copy: ({ x, y, z }) => {
|
|
206
|
+
const uuid = getUUID(bodyRef, index);
|
|
207
|
+
uuid && worker[op]({ props: [x, y, z], uuid });
|
|
208
|
+
},
|
|
209
|
+
set: (x, y, z) => {
|
|
210
|
+
const uuid = getUUID(bodyRef, index);
|
|
211
|
+
uuid && worker[op]({ props: [x, y, z], uuid });
|
|
212
|
+
},
|
|
213
|
+
subscribe: subscribe(bodyRef, worker, subscriptions, type, index),
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
const makeRemove = (index) => {
|
|
217
|
+
const uuid = getUUID(bodyRef, index);
|
|
218
|
+
return () => {
|
|
219
|
+
if (uuid)
|
|
220
|
+
worker.removeBodies({ uuid: [uuid] });
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
function makeApi(index) {
|
|
224
|
+
return {
|
|
225
|
+
allowSleep: makeAtomic('allowSleep', index),
|
|
226
|
+
angularDamping: makeAtomic('angularDamping', index),
|
|
227
|
+
angularFactor: makeVec('angularFactor', index),
|
|
228
|
+
angularVelocity: makeVec('angularVelocity', index),
|
|
229
|
+
applyForce(force, worldPoint) {
|
|
230
|
+
const uuid = getUUID(bodyRef, index);
|
|
231
|
+
uuid && worker.applyForce({ props: [force, worldPoint], uuid });
|
|
232
|
+
},
|
|
233
|
+
applyImpulse(impulse, worldPoint) {
|
|
234
|
+
const uuid = getUUID(bodyRef, index);
|
|
235
|
+
uuid && worker.applyImpulse({ props: [impulse, worldPoint], uuid });
|
|
236
|
+
},
|
|
237
|
+
applyLocalForce(force, localPoint) {
|
|
238
|
+
const uuid = getUUID(bodyRef, index);
|
|
239
|
+
uuid && worker.applyLocalForce({ props: [force, localPoint], uuid });
|
|
240
|
+
},
|
|
241
|
+
applyLocalImpulse(impulse, localPoint) {
|
|
242
|
+
const uuid = getUUID(bodyRef, index);
|
|
243
|
+
uuid && worker.applyLocalImpulse({ props: [impulse, localPoint], uuid });
|
|
244
|
+
},
|
|
245
|
+
applyTorque(torque) {
|
|
246
|
+
const uuid = getUUID(bodyRef, index);
|
|
247
|
+
uuid && worker.applyTorque({ props: [torque], uuid });
|
|
248
|
+
},
|
|
249
|
+
collisionFilterGroup: makeAtomic('collisionFilterGroup', index),
|
|
250
|
+
collisionFilterMask: makeAtomic('collisionFilterMask', index),
|
|
251
|
+
collisionResponse: makeAtomic('collisionResponse', index),
|
|
252
|
+
fixedRotation: makeAtomic('fixedRotation', index),
|
|
253
|
+
isTrigger: makeAtomic('isTrigger', index),
|
|
254
|
+
linearDamping: makeAtomic('linearDamping', index),
|
|
255
|
+
linearFactor: makeVec('linearFactor', index),
|
|
256
|
+
mass: makeAtomic('mass', index),
|
|
257
|
+
material: makeAtomic('material', index),
|
|
258
|
+
position: makeVec('position', index),
|
|
259
|
+
quaternion: makeQuaternion(index),
|
|
260
|
+
rotation: makeRotation(index),
|
|
261
|
+
scaleOverride(scale) {
|
|
262
|
+
const uuid = getUUID(bodyRef, index);
|
|
263
|
+
if (uuid)
|
|
264
|
+
scaleOverrides[uuid] = new THREE.Vector3(...scale);
|
|
265
|
+
},
|
|
266
|
+
sleep() {
|
|
267
|
+
const uuid = getUUID(bodyRef, index);
|
|
268
|
+
uuid && worker.sleep({ uuid });
|
|
269
|
+
},
|
|
270
|
+
sleepSpeedLimit: makeAtomic('sleepSpeedLimit', index),
|
|
271
|
+
sleepTimeLimit: makeAtomic('sleepTimeLimit', index),
|
|
272
|
+
userData: makeAtomic('userData', index),
|
|
273
|
+
velocity: makeVec('velocity', index),
|
|
274
|
+
remove: makeRemove(index),
|
|
275
|
+
wakeUp() {
|
|
276
|
+
const uuid = getUUID(bodyRef, index);
|
|
277
|
+
uuid && worker.wakeUp({ uuid });
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const cache = {};
|
|
282
|
+
return {
|
|
283
|
+
...makeApi(undefined),
|
|
284
|
+
at: (index) => cache[index] || (cache[index] = makeApi(index)),
|
|
285
|
+
};
|
|
286
|
+
});
|
|
287
|
+
return { ref: bodyRef, api };
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function usePointToPointConstraint(bodyA, bodyB, opts) {
|
|
292
|
+
return injectConstraint('PointToPoint', bodyA, bodyB, opts);
|
|
293
|
+
}
|
|
294
|
+
function useConeTwistConstraint(bodyA, bodyB, opts) {
|
|
295
|
+
return injectConstraint('ConeTwist', bodyA, bodyB, opts);
|
|
296
|
+
}
|
|
297
|
+
function useDistanceConstraint(bodyA, bodyB, opts) {
|
|
298
|
+
return injectConstraint('Distance', bodyA, bodyB, opts);
|
|
299
|
+
}
|
|
300
|
+
function useHingeConstraint(bodyA, bodyB, opts) {
|
|
301
|
+
return injectConstraint('Hinge', bodyA, bodyB, opts);
|
|
302
|
+
}
|
|
303
|
+
function useLockConstraint(bodyA, bodyB, opts) {
|
|
304
|
+
return injectConstraint('Lock', bodyA, bodyB, opts);
|
|
305
|
+
}
|
|
306
|
+
function injectConstraint(type, bodyA, bodyB, { injector, deps = () => ({}), opts = () => ({}), } = {}) {
|
|
307
|
+
injector = assertInjectionContext(injectConstraint, injector);
|
|
308
|
+
return runInInjectionContext(injector, () => {
|
|
309
|
+
const physicsApi = inject(NGTC_PHYSICS_API);
|
|
310
|
+
const { worker } = physicsApi();
|
|
311
|
+
const uuid = makeId();
|
|
312
|
+
const bodyARef = is.ref(bodyA) ? bodyA : injectNgtRef(bodyA);
|
|
313
|
+
const bodyBRef = is.ref(bodyB) ? bodyB : injectNgtRef(bodyB);
|
|
314
|
+
effect((onCleanup) => {
|
|
315
|
+
deps();
|
|
316
|
+
if (bodyARef.nativeElement && bodyBRef.nativeElement) {
|
|
317
|
+
worker.addConstraint({
|
|
318
|
+
props: [bodyARef.untracked.uuid, bodyBRef.untracked.uuid, untracked(opts)],
|
|
319
|
+
type,
|
|
320
|
+
uuid,
|
|
321
|
+
});
|
|
322
|
+
onCleanup(() => worker.removeConstraint({ uuid }));
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
const api = computed(() => {
|
|
326
|
+
deps();
|
|
327
|
+
const enableDisable = {
|
|
328
|
+
disable: () => worker.disableConstraint({ uuid }),
|
|
329
|
+
enable: () => worker.enableConstraint({ uuid }),
|
|
330
|
+
remove: () => worker.removeConstraint({ uuid }),
|
|
331
|
+
};
|
|
332
|
+
if (type === 'Hinge') {
|
|
333
|
+
return {
|
|
334
|
+
...enableDisable,
|
|
335
|
+
disableMotor: () => worker.disableConstraintMotor({ uuid }),
|
|
336
|
+
enableMotor: () => worker.enableConstraintMotor({ uuid }),
|
|
337
|
+
setMotorMaxForce: (value) => worker.setConstraintMotorMaxForce({ props: value, uuid }),
|
|
338
|
+
setMotorSpeed: (value) => worker.setConstraintMotorSpeed({ props: value, uuid }),
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return enableDisable;
|
|
342
|
+
});
|
|
343
|
+
return { bodyA: bodyARef, bodyB: bodyBRef, api };
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function injectContactMaterial(materialB, materialA, { opts, deps = () => ({}), injector, }) {
|
|
348
|
+
injector = assertInjectionContext(injectContactMaterial, injector);
|
|
349
|
+
return runInInjectionContext(injector, () => {
|
|
350
|
+
const physicsApi = inject(NGTC_PHYSICS_API);
|
|
351
|
+
const { worker } = physicsApi();
|
|
352
|
+
const uuid = makeId();
|
|
353
|
+
effect((onCleanup) => {
|
|
354
|
+
deps();
|
|
355
|
+
worker.addContactMaterial({
|
|
356
|
+
props: [materialA, materialB, untracked(opts)],
|
|
357
|
+
uuid,
|
|
358
|
+
});
|
|
359
|
+
onCleanup(() => worker.removeContactMaterial({ uuid }));
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function injectRaycastClosest(opts) {
|
|
365
|
+
return injectRay('Closest', opts);
|
|
366
|
+
}
|
|
367
|
+
function injectRaycastAny(opts) {
|
|
368
|
+
return injectRay('Any', opts);
|
|
369
|
+
}
|
|
370
|
+
function useRaycastAll(opts) {
|
|
371
|
+
return injectRay('All', opts);
|
|
372
|
+
}
|
|
373
|
+
function injectRay(mode, { options, callback, deps = () => ({}), injector }) {
|
|
374
|
+
injector = assertInjectionContext(injectRay, injector);
|
|
375
|
+
return runInInjectionContext(injector, () => {
|
|
376
|
+
const physicsApi = inject(NGTC_PHYSICS_API);
|
|
377
|
+
const { worker, events } = physicsApi();
|
|
378
|
+
const uuid = makeId();
|
|
379
|
+
effect((onCleanup) => {
|
|
380
|
+
deps();
|
|
381
|
+
events[uuid] = { rayhit: callback };
|
|
382
|
+
worker.addRay({ props: { ...untracked(options), mode }, uuid });
|
|
383
|
+
onCleanup(() => {
|
|
384
|
+
worker.removeRay({ uuid });
|
|
385
|
+
delete events[uuid];
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function isString(v) {
|
|
392
|
+
return typeof v === 'string';
|
|
393
|
+
}
|
|
394
|
+
function injectRaycastVehicle(fn, { ref, injector, deps = () => ({}), } = {}) {
|
|
395
|
+
injector = assertInjectionContext(injectRaycastVehicle, injector);
|
|
396
|
+
return runInInjectionContext(injector, () => {
|
|
397
|
+
const physicsApi = inject(NGTC_PHYSICS_API);
|
|
398
|
+
const { worker, subscriptions } = physicsApi();
|
|
399
|
+
let instanceRef = injectNgtRef();
|
|
400
|
+
if (ref)
|
|
401
|
+
instanceRef = ref;
|
|
402
|
+
effect((onCleanup) => {
|
|
403
|
+
deps();
|
|
404
|
+
if (!instanceRef.untracked) {
|
|
405
|
+
instanceRef.nativeElement = new THREE.Object3D();
|
|
406
|
+
}
|
|
407
|
+
const currentWorker = worker;
|
|
408
|
+
const uuid = instanceRef.nativeElement.uuid;
|
|
409
|
+
const { chassisBody, indexForwardAxis = 2, indexRightAxis = 0, indexUpAxis = 1, wheelInfos, wheels, } = untracked(fn);
|
|
410
|
+
const chassisBodyUUID = getUUID(chassisBody);
|
|
411
|
+
const wheelUUIDs = wheels.map((ref) => getUUID(ref));
|
|
412
|
+
if (!chassisBodyUUID || !wheelUUIDs.every(isString))
|
|
413
|
+
return;
|
|
414
|
+
currentWorker.addRaycastVehicle({
|
|
415
|
+
props: [chassisBodyUUID, wheelUUIDs, wheelInfos, indexForwardAxis, indexRightAxis, indexUpAxis],
|
|
416
|
+
uuid,
|
|
417
|
+
});
|
|
418
|
+
onCleanup(() => {
|
|
419
|
+
currentWorker.removeRaycastVehicle({ uuid });
|
|
420
|
+
});
|
|
421
|
+
}, { allowSignalWrites: true });
|
|
422
|
+
const api = computed(() => {
|
|
423
|
+
deps();
|
|
424
|
+
return {
|
|
425
|
+
applyEngineForce(value, wheelIndex) {
|
|
426
|
+
const uuid = getUUID(instanceRef);
|
|
427
|
+
uuid &&
|
|
428
|
+
worker.applyRaycastVehicleEngineForce({
|
|
429
|
+
props: [value, wheelIndex],
|
|
430
|
+
uuid,
|
|
431
|
+
});
|
|
432
|
+
},
|
|
433
|
+
setBrake(brake, wheelIndex) {
|
|
434
|
+
const uuid = getUUID(instanceRef);
|
|
435
|
+
uuid && worker.setRaycastVehicleBrake({ props: [brake, wheelIndex], uuid });
|
|
436
|
+
},
|
|
437
|
+
setSteeringValue(value, wheelIndex) {
|
|
438
|
+
const uuid = getUUID(instanceRef);
|
|
439
|
+
uuid &&
|
|
440
|
+
worker.setRaycastVehicleSteeringValue({
|
|
441
|
+
props: [value, wheelIndex],
|
|
442
|
+
uuid,
|
|
443
|
+
});
|
|
444
|
+
},
|
|
445
|
+
sliding: {
|
|
446
|
+
subscribe: subscribe(instanceRef, worker, subscriptions, 'sliding', undefined, 'vehicles'),
|
|
447
|
+
},
|
|
448
|
+
remove: () => {
|
|
449
|
+
const uuid = getUUID(instanceRef);
|
|
450
|
+
uuid && worker.removeRaycastVehicle({ uuid });
|
|
451
|
+
},
|
|
452
|
+
};
|
|
453
|
+
});
|
|
454
|
+
return { ref: instanceRef, api };
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function injectSpring(bodyA, bodyB, { injector, opts = () => ({}), deps = () => ({}), } = {}) {
|
|
459
|
+
injector = assertInjectionContext(injectSpring, injector);
|
|
460
|
+
return runInInjectionContext(injector, () => {
|
|
461
|
+
const physicsApi = inject(NGTC_PHYSICS_API);
|
|
462
|
+
const { worker } = physicsApi();
|
|
463
|
+
const uuid = makeId();
|
|
464
|
+
const bodyARef = is.ref(bodyA) ? bodyA : injectNgtRef(bodyA);
|
|
465
|
+
const bodyBRef = is.ref(bodyB) ? bodyB : injectNgtRef(bodyB);
|
|
466
|
+
effect((onCleanup) => {
|
|
467
|
+
deps();
|
|
468
|
+
if (bodyARef.nativeElement && bodyBRef.nativeElement) {
|
|
469
|
+
worker.addSpring({
|
|
470
|
+
props: [bodyARef.nativeElement.uuid, bodyBRef.nativeElement.uuid, untracked(opts)],
|
|
471
|
+
uuid,
|
|
472
|
+
});
|
|
473
|
+
onCleanup(() => worker.removeSpring({ uuid }));
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
const api = computed(() => {
|
|
477
|
+
deps();
|
|
478
|
+
return {
|
|
479
|
+
setDamping: (value) => worker.setSpringDamping({ props: value, uuid }),
|
|
480
|
+
setRestLength: (value) => worker.setSpringRestLength({ props: value, uuid }),
|
|
481
|
+
setStiffness: (value) => worker.setSpringStiffness({ props: value, uuid }),
|
|
482
|
+
remove: () => worker.removeSpring({ uuid }),
|
|
483
|
+
};
|
|
484
|
+
});
|
|
485
|
+
return { bodyA: bodyARef, bodyB: bodyBRef, api };
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Generated bundle index. Do not edit.
|
|
491
|
+
*/
|
|
492
|
+
|
|
493
|
+
export { getUUID, injectBox, injectCompoundBody, injectContactMaterial, injectConvexPolyhedron, injectCylinder, injectHeightfield, injectParticle, injectPlane, injectRaycastAny, injectRaycastClosest, injectRaycastVehicle, injectSphere, injectSpring, injectTrimesh, subscribe, useConeTwistConstraint, useDistanceConstraint, useHingeConstraint, useLockConstraint, usePointToPointConstraint, useRaycastAll };
|
|
494
|
+
//# sourceMappingURL=angular-three-cannon-services.mjs.map
|