@needle-tools/engine 2.37.0-pre → 2.38.0-pre
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/CHANGELOG.md +21 -0
- package/dist/needle-engine.d.ts +80 -13
- package/dist/needle-engine.js +349 -349
- package/dist/needle-engine.js.map +4 -4
- package/dist/needle-engine.min.js +25 -25
- package/dist/needle-engine.min.js.map +4 -4
- package/lib/engine/engine_addressables.d.ts +3 -1
- package/lib/engine/engine_addressables.js +12 -5
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_element.js +3 -2
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_element_overlay.js +4 -3
- package/lib/engine/engine_element_overlay.js.map +1 -1
- package/lib/engine/engine_input.d.ts +2 -0
- package/lib/engine/engine_input.js +14 -3
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_physics.d.ts +2 -4
- package/lib/engine/engine_physics.js +75 -30
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_physics.types.d.ts +7 -0
- package/lib/engine/engine_physics.types.js +8 -0
- package/lib/engine/engine_physics.types.js.map +1 -1
- package/lib/engine/engine_setup.d.ts +7 -1
- package/lib/engine/engine_setup.js +10 -2
- package/lib/engine/engine_setup.js.map +1 -1
- package/lib/engine/engine_types.d.ts +1 -1
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine-components/Animation.d.ts +1 -0
- package/lib/engine-components/Animation.js +7 -0
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/AnimatorController.js +14 -7
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/Camera.d.ts +1 -0
- package/lib/engine-components/Camera.js +20 -5
- package/lib/engine-components/Camera.js.map +1 -1
- package/lib/engine-components/CharacterController.d.ts +31 -0
- package/lib/engine-components/CharacterController.js +167 -0
- package/lib/engine-components/CharacterController.js.map +1 -0
- package/lib/engine-components/Collider.d.ts +10 -4
- package/lib/engine-components/Collider.js +18 -8
- package/lib/engine-components/Collider.js.map +1 -1
- package/lib/engine-components/Light.d.ts +2 -0
- package/lib/engine-components/Light.js +13 -2
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/Renderer.js +4 -0
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/RigidBody.d.ts +6 -1
- package/lib/engine-components/RigidBody.js +62 -25
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SmoothFollow.d.ts +2 -1
- package/lib/engine-components/SmoothFollow.js +25 -17
- package/lib/engine-components/SmoothFollow.js.map +1 -1
- package/lib/engine-components/WebXR.js +3 -4
- package/lib/engine-components/WebXR.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +3 -0
- package/lib/engine-components/codegen/components.js +3 -0
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/codegen/register_types.js +12 -0
- package/src/engine/dist/engine_physics.js +739 -0
- package/src/engine/dist/engine_setup.js +777 -0
- package/src/engine/engine_addressables.ts +18 -8
- package/src/engine/engine_element.ts +3 -2
- package/src/engine/engine_element_overlay.ts +4 -3
- package/src/engine/engine_input.ts +12 -3
- package/src/engine/engine_physics.ts +82 -47
- package/src/engine/engine_physics.types.ts +9 -0
- package/src/engine/engine_setup.ts +26 -17
- package/src/engine/engine_types.ts +2 -1
- package/src/engine-components/Animation.ts +8 -0
- package/src/engine-components/AnimatorController.ts +16 -11
- package/src/engine-components/Camera.ts +21 -4
- package/src/engine-components/CharacterController.ts +171 -0
- package/src/engine-components/Collider.ts +22 -12
- package/src/engine-components/Light.ts +17 -3
- package/src/engine-components/Renderer.ts +5 -1
- package/src/engine-components/RigidBody.ts +63 -29
- package/src/engine-components/SmoothFollow.ts +21 -18
- package/src/engine-components/WebXR.ts +3 -4
- package/src/engine-components/codegen/components.ts +3 -0
- package/src/engine-components/dist/CharacterController.js +123 -0
- package/src/engine-components/dist/RigidBody.js +458 -0
|
@@ -5,7 +5,7 @@ import { Context } from "./engine_setup";
|
|
|
5
5
|
import { Group, Object3D, Scene } from "three";
|
|
6
6
|
import { processNewScripts } from "./engine_mainloop_utils";
|
|
7
7
|
import { InstantiateEvent, registerPrefabProvider, syncInstantiate } from "./engine_networking_instantiate";
|
|
8
|
-
import { download } from "./engine_web_api";
|
|
8
|
+
import { download, hash } from "./engine_web_api";
|
|
9
9
|
import { getLoader } from "./engine_gltf";
|
|
10
10
|
import { SourceIdentifier } from "./engine_types";
|
|
11
11
|
import { destroy, instantiate, InstantiateOptions } from "./engine_gameobject";
|
|
@@ -51,11 +51,11 @@ export class AssetReference {
|
|
|
51
51
|
|
|
52
52
|
static getOrCreate(sourceId: SourceIdentifier, uri: string, context: Context): AssetReference {
|
|
53
53
|
const fullPath = getPath(sourceId, uri);
|
|
54
|
-
if(debug) console.log("GetOrCreate Addressable from", sourceId, uri, "FinalPath=", fullPath);
|
|
54
|
+
if (debug) console.log("GetOrCreate Addressable from", sourceId, uri, "FinalPath=", fullPath);
|
|
55
55
|
const addressables = context.addressables;
|
|
56
56
|
const existing = addressables.findAssetReference(fullPath);
|
|
57
57
|
if (existing) return existing;
|
|
58
|
-
const ref = new AssetReference(fullPath);
|
|
58
|
+
const ref = new AssetReference(fullPath, context.hash);
|
|
59
59
|
addressables.registerAssetReference(ref);
|
|
60
60
|
return ref;
|
|
61
61
|
}
|
|
@@ -63,6 +63,7 @@ export class AssetReference {
|
|
|
63
63
|
get asset(): any {
|
|
64
64
|
return this._glbRoot ?? this._asset;
|
|
65
65
|
}
|
|
66
|
+
|
|
66
67
|
protected set asset(val: any) {
|
|
67
68
|
this._asset = val;
|
|
68
69
|
}
|
|
@@ -70,7 +71,7 @@ export class AssetReference {
|
|
|
70
71
|
private _loading?: PromiseLike<any>;
|
|
71
72
|
|
|
72
73
|
get uri(): string {
|
|
73
|
-
return this._uri
|
|
74
|
+
return this._uri;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
get rawAsset(): any { return this._asset; }
|
|
@@ -80,11 +81,20 @@ export class AssetReference {
|
|
|
80
81
|
private _uri: string;
|
|
81
82
|
private _progressListeners: ProgressCallback[] = [];
|
|
82
83
|
|
|
84
|
+
private _hash?: string;
|
|
85
|
+
private _hashedUri: string;
|
|
86
|
+
|
|
83
87
|
private _isLoadingRawBinary: boolean = false;
|
|
84
88
|
private _rawBinary?: ArrayBuffer | null;
|
|
85
89
|
|
|
86
|
-
constructor(uri: string) {
|
|
90
|
+
constructor(uri: string, hash?: string) {
|
|
87
91
|
this._uri = uri;
|
|
92
|
+
this._hash = hash;
|
|
93
|
+
if (uri.includes("?v="))
|
|
94
|
+
this._hashedUri = uri;
|
|
95
|
+
else
|
|
96
|
+
this._hashedUri = hash ? uri + "?v=" + hash : uri;
|
|
97
|
+
|
|
88
98
|
registerPrefabProvider(this._uri, this.onResolvePrefab.bind(this));
|
|
89
99
|
}
|
|
90
100
|
|
|
@@ -120,8 +130,8 @@ export class AssetReference {
|
|
|
120
130
|
if (this._isLoadingRawBinary) return null;
|
|
121
131
|
if (this._rawBinary !== undefined) return this._rawBinary;
|
|
122
132
|
this._isLoadingRawBinary = true;
|
|
123
|
-
if (debug) console.log("Preload", this.
|
|
124
|
-
const res = await download(this.
|
|
133
|
+
if (debug) console.log("Preload", this._hashedUri);
|
|
134
|
+
const res = await download(this._hashedUri, p => {
|
|
125
135
|
this.raiseProgressEvent(p);
|
|
126
136
|
});
|
|
127
137
|
this._rawBinary = res?.buffer ?? null;
|
|
@@ -148,7 +158,7 @@ export class AssetReference {
|
|
|
148
158
|
}
|
|
149
159
|
else {
|
|
150
160
|
if (debug) console.log("Load async", this.uri);
|
|
151
|
-
this._loading = getLoader().loadSync(context, this.
|
|
161
|
+
this._loading = getLoader().loadSync(context, this._hashedUri, null, true, prog => {
|
|
152
162
|
this.raiseProgressEvent(prog);
|
|
153
163
|
});
|
|
154
164
|
}
|
|
@@ -133,7 +133,8 @@ export class EngineElement extends HTMLElement implements INeedleEngineComponent
|
|
|
133
133
|
if (srcAttributeValue) src = srcAttributeValue;
|
|
134
134
|
|
|
135
135
|
const alias = this.getAttribute("alias");
|
|
136
|
-
|
|
136
|
+
const hash = this.getAttribute("hash");
|
|
137
|
+
this._context = new Context({ name: src, domElement: this, alias: alias, hash: hash ?? undefined });
|
|
137
138
|
this._watcher = new EngineElementSourceFileWatcher(this.getAttribute("id") ?? alias ?? "", this._context);
|
|
138
139
|
|
|
139
140
|
if (src && src.length > 0) {
|
|
@@ -234,7 +235,7 @@ export class EngineElement extends HTMLElement implements INeedleEngineComponent
|
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
static get observedAttributes() {
|
|
237
|
-
return ["src", "loadstart", "progress", "loadfinished", "dracoDecoderPath", "dracoDecoderType", "ktx2DecoderPath"];
|
|
238
|
+
return ["hash", "src", "loadstart", "progress", "loadfinished", "dracoDecoderPath", "dracoDecoderType", "ktx2DecoderPath"];
|
|
238
239
|
}
|
|
239
240
|
|
|
240
241
|
attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
|
|
@@ -73,11 +73,12 @@ export class AROverlayHandler {
|
|
|
73
73
|
return element;
|
|
74
74
|
}
|
|
75
75
|
if (element.children) {
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
for (let i = 0; i < element.children.length; i++) {
|
|
77
|
+
const ch = element.children[i] as HTMLElement;
|
|
78
78
|
if (!ch || !ch.classList) continue;
|
|
79
|
-
if (ch.classList.contains(arContainerClassName))
|
|
79
|
+
if (ch.classList.contains(arContainerClassName)) {
|
|
80
80
|
return ch;
|
|
81
|
+
}
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
|
|
@@ -147,6 +147,10 @@ export class Input extends EventTarget {
|
|
|
147
147
|
if (i >= this._mouseWheelChanged.length) return false;
|
|
148
148
|
return this._mouseWheelChanged[i];
|
|
149
149
|
}
|
|
150
|
+
getMouseWheelDeltaY(i: number = 0): number {
|
|
151
|
+
if (i >= this._mouseWheelDeltaY.length) return 0;
|
|
152
|
+
return this._mouseWheelDeltaY[i];
|
|
153
|
+
}
|
|
150
154
|
getPointerEvent(i: number): Event | undefined {
|
|
151
155
|
if (i >= this._pointerEvent.length) return undefined;
|
|
152
156
|
return this._pointerEvent[i] ?? undefined;
|
|
@@ -169,6 +173,7 @@ export class Input extends EventTarget {
|
|
|
169
173
|
private _pointerIds: number[] = [];
|
|
170
174
|
private _pointerTypes: string[] = [""];
|
|
171
175
|
private _mouseWheelChanged: boolean[] = [false];
|
|
176
|
+
private _mouseWheelDeltaY: number[] = [0];
|
|
172
177
|
private _pointerEvent: Event[] = [];
|
|
173
178
|
|
|
174
179
|
getKeyDown(): string | null {
|
|
@@ -269,11 +274,12 @@ export class Input extends EventTarget {
|
|
|
269
274
|
this._pointerClick[i] = false;
|
|
270
275
|
for (let i = 0; i < this._pointerDoubleClick.length; i++)
|
|
271
276
|
this._pointerDoubleClick[i] = false;
|
|
272
|
-
for (const pt of this._pointerPositionsDelta)
|
|
277
|
+
for (const pt of this._pointerPositionsDelta)
|
|
273
278
|
pt.set(0, 0);
|
|
274
|
-
}
|
|
275
279
|
for (let i = 0; i < this._mouseWheelChanged.length; i++)
|
|
276
280
|
this._mouseWheelChanged[i] = false;
|
|
281
|
+
for (let i = 0; i < this._mouseWheelDeltaY.length; i++)
|
|
282
|
+
this._mouseWheelDeltaY[i] = 0;
|
|
277
283
|
}
|
|
278
284
|
|
|
279
285
|
|
|
@@ -307,9 +313,12 @@ export class Input extends EventTarget {
|
|
|
307
313
|
this.onDispatchEvent(InputEvents.KeyUp, new KeyEventArgs(evt));
|
|
308
314
|
}
|
|
309
315
|
|
|
310
|
-
private onMouseWheel(
|
|
316
|
+
private onMouseWheel(evt: WheelEvent) {
|
|
317
|
+
if (this._mouseWheelDeltaY.length <= 0) this._mouseWheelDeltaY.push(0);
|
|
311
318
|
if (this._mouseWheelChanged.length <= 0) this._mouseWheelChanged.push(false);
|
|
312
319
|
this._mouseWheelChanged[0] = true;
|
|
320
|
+
const current = this._mouseWheelDeltaY[0];
|
|
321
|
+
this._mouseWheelDeltaY[0] = current + evt.deltaY;
|
|
313
322
|
}
|
|
314
323
|
|
|
315
324
|
private onTouchMove(_evt) {
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
import { BasicDepthPacking, Box3, BufferAttribute, BufferGeometry, Camera, Intersection, Layers, LineBasicMaterial, LineSegments, Matrix4, Mesh, NormalAnimationBlendMode, Object3D, Quaternion, Ray, Raycaster, Sphere, Vector2, Vector3 } from 'three'
|
|
2
2
|
import { Context } from './engine_setup';
|
|
3
3
|
import { getParam } from "./engine_utils"
|
|
4
|
-
import { getWorldPosition, getWorldQuaternion, getWorldScale,
|
|
4
|
+
import { getWorldPosition, getWorldQuaternion, getWorldScale, setWorldPositionXYZ, setWorldQuaternionXYZW } from "./engine_three_utils"
|
|
5
5
|
import {
|
|
6
6
|
IComponent,
|
|
7
|
-
IGameObject,
|
|
8
7
|
ICollider,
|
|
9
8
|
IRigidbody,
|
|
10
9
|
Collision,
|
|
11
|
-
|
|
12
|
-
ContactPoint,
|
|
13
|
-
Vec3
|
|
10
|
+
ContactPoint
|
|
14
11
|
} from './engine_types';
|
|
15
12
|
import { InstancingUtil } from './engine_instancing';
|
|
16
13
|
import { foreachComponent } from './engine_gameobject';
|
|
17
14
|
|
|
18
|
-
import RAPIER, { ActiveEvents, Collider, ColliderDesc, EventQueue, RigidBody,
|
|
19
|
-
import { CollisionDetectionMode
|
|
20
|
-
import { showBalloonWarning } from './debug/debug';
|
|
15
|
+
import RAPIER, { ActiveEvents, Collider, ColliderDesc, EventQueue, RigidBody, RigidBodyType, World } from '@dimforge/rapier3d-compat';
|
|
16
|
+
import { CollisionDetectionMode } from '../engine/engine_physics.types';
|
|
21
17
|
export type Rapier = typeof RAPIER;
|
|
22
18
|
|
|
23
19
|
|
|
@@ -33,6 +29,8 @@ declare type PhysicsBody = {
|
|
|
33
29
|
|
|
34
30
|
const $componentKey = Symbol("needle component");
|
|
35
31
|
const $bodyKey = Symbol("physics body");
|
|
32
|
+
const $colliderRigidbody = Symbol("rigidbody");
|
|
33
|
+
// const $removed = Symbol("removed");
|
|
36
34
|
|
|
37
35
|
export class RaycastOptions {
|
|
38
36
|
ray: Ray | undefined = undefined;
|
|
@@ -209,6 +207,7 @@ export class Physics {
|
|
|
209
207
|
|
|
210
208
|
private _tempPosition: Vector3 = new Vector3();
|
|
211
209
|
private _tempQuaternion: Quaternion = new Quaternion();
|
|
210
|
+
private _tempScale: Vector3 = new Vector3();
|
|
212
211
|
private _tempMatrix: Matrix4 = new Matrix4();
|
|
213
212
|
|
|
214
213
|
private static _didLoadPhysicsEngine: boolean = false;
|
|
@@ -266,6 +265,14 @@ export class Physics {
|
|
|
266
265
|
this.createCollider(collider, desc, center);
|
|
267
266
|
}
|
|
268
267
|
|
|
268
|
+
addCapsuleCollider(collider: ICollider, center: Vector3, height: number, radius: number) {
|
|
269
|
+
const obj = collider.gameObject;
|
|
270
|
+
const scale = getWorldScale(obj, this._tempPosition);
|
|
271
|
+
if(debugPhysics) console.log("capsule scale", scale, height, radius);
|
|
272
|
+
const desc = ColliderDesc.capsule(height * .5 * scale.y - radius, radius * scale.x);
|
|
273
|
+
this.createCollider(collider, desc, center);
|
|
274
|
+
}
|
|
275
|
+
|
|
269
276
|
addMeshCollider(collider: ICollider, mesh: Mesh, convex: boolean) {
|
|
270
277
|
const geo = mesh.geometry;
|
|
271
278
|
if (!geo) {
|
|
@@ -308,9 +315,10 @@ export class Physics {
|
|
|
308
315
|
useExplicitMassProperties
|
|
309
316
|
} = this.getRigidbody(collider, this._tempMatrix);
|
|
310
317
|
|
|
311
|
-
matrix.decompose(this._tempPosition, this._tempQuaternion,
|
|
318
|
+
matrix.decompose(this._tempPosition, this._tempQuaternion, this._tempScale);
|
|
319
|
+
getWorldScale(collider.gameObject, this._tempScale);
|
|
312
320
|
if (center)
|
|
313
|
-
this._tempPosition.add(center);
|
|
321
|
+
this._tempPosition.add(center).multiply(this._tempScale);
|
|
314
322
|
desc.setTranslation(this._tempPosition.x, this._tempPosition.y, this._tempPosition.z);
|
|
315
323
|
desc.setRotation(this._tempQuaternion);
|
|
316
324
|
|
|
@@ -373,13 +381,15 @@ export class Physics {
|
|
|
373
381
|
|
|
374
382
|
}
|
|
375
383
|
|
|
384
|
+
collider[$colliderRigidbody] = rigidBody;
|
|
385
|
+
|
|
376
386
|
return { rigidBody: rigidBody, useExplicitMassProperties: useExplicitMassProperties };
|
|
377
387
|
}
|
|
378
388
|
|
|
379
389
|
removeBody(obj: IComponent) {
|
|
380
390
|
const body = obj[$bodyKey];
|
|
381
391
|
obj[$bodyKey] = null;
|
|
382
|
-
if (body) {
|
|
392
|
+
if (body && this.world) {
|
|
383
393
|
const index = this.objects.findIndex(o => o === obj);
|
|
384
394
|
if (index >= 0) {
|
|
385
395
|
const body = this.bodies[index];
|
|
@@ -387,20 +397,37 @@ export class Physics {
|
|
|
387
397
|
this.objects.splice(index, 1);
|
|
388
398
|
|
|
389
399
|
if (body instanceof Collider) {
|
|
390
|
-
|
|
400
|
+
const collider = body as Collider;
|
|
401
|
+
this.world?.removeCollider(collider, true);
|
|
402
|
+
|
|
403
|
+
// remove the rigidbody if it doesnt have colliders anymore
|
|
404
|
+
const rb = collider.parent();
|
|
405
|
+
if (rb && rb.numColliders() <= 0) {
|
|
406
|
+
this.world?.removeRigidBody(rb);
|
|
407
|
+
}
|
|
391
408
|
}
|
|
392
409
|
else if (body instanceof RigidBody) {
|
|
393
|
-
this
|
|
410
|
+
// TODO: running this code below causes a crash in rapier
|
|
411
|
+
// const rb = body as RigidBody;
|
|
412
|
+
// console.log("colliders", rb.numColliders())
|
|
413
|
+
// for (let i = 0; i < rb.numColliders(); i++) {
|
|
414
|
+
// const col = rb.collider(i);
|
|
415
|
+
// this.world?.removeCollider(col, true);
|
|
416
|
+
// }
|
|
417
|
+
// console.log("colliders", rb.numColliders(), rb)
|
|
418
|
+
// console.log(rb.handle, rb.userData);
|
|
419
|
+
// if (rb.userData === undefined)
|
|
420
|
+
// this.world?.removeRigidBody(rb);
|
|
394
421
|
}
|
|
395
422
|
|
|
396
423
|
// check if we need to remove the rigidbody too
|
|
397
|
-
const col = obj as ICollider;
|
|
398
|
-
if (col.isCollider && col.attachedRigidbody) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
424
|
+
// const col = obj as ICollider;
|
|
425
|
+
// if (col.isCollider && col.attachedRigidbody) {
|
|
426
|
+
// const rb = col.attachedRigidbody[$bodyKey] as RigidBody;
|
|
427
|
+
// if (rb && rb.numColliders() <= 0) {
|
|
428
|
+
// // this.world?.removeRigidBody(rb);
|
|
429
|
+
// }
|
|
430
|
+
// }
|
|
404
431
|
}
|
|
405
432
|
}
|
|
406
433
|
}
|
|
@@ -526,10 +553,22 @@ export class Physics {
|
|
|
526
553
|
continue;
|
|
527
554
|
}
|
|
528
555
|
|
|
556
|
+
|
|
529
557
|
// sync
|
|
530
558
|
const pos = body.translation();
|
|
531
|
-
setWorldPositionXYZ(obj.gameObject, pos.x, pos.y, pos.z);
|
|
532
559
|
const rot = body.rotation();
|
|
560
|
+
// make sure to keep the collider offset
|
|
561
|
+
const center = obj["center"] as Vector3;
|
|
562
|
+
if (center && center.isVector3) {
|
|
563
|
+
this._tempQuaternion.set(rot.x, rot.y, rot.z, rot.w);
|
|
564
|
+
const offset = this._tempPosition.copy(center).applyQuaternion(this._tempQuaternion);
|
|
565
|
+
const scale = getWorldScale(obj.gameObject);
|
|
566
|
+
offset.multiply(scale);
|
|
567
|
+
pos.x -= offset.x;
|
|
568
|
+
pos.y -= offset.y;
|
|
569
|
+
pos.z -= offset.z;
|
|
570
|
+
}
|
|
571
|
+
setWorldPositionXYZ(obj.gameObject, pos.x, pos.y, pos.z);
|
|
533
572
|
setWorldQuaternionXYZW(obj.gameObject, rot.x, rot.y, rot.z, rot.w);
|
|
534
573
|
}
|
|
535
574
|
}
|
|
@@ -542,13 +581,27 @@ export class Physics {
|
|
|
542
581
|
|
|
543
582
|
const worldPosition = getWorldPosition(obj, this._tempPosition);
|
|
544
583
|
const worldQuaternion = getWorldQuaternion(obj, this._tempQuaternion);
|
|
584
|
+
const type = body.bodyType();
|
|
585
|
+
switch (type) {
|
|
586
|
+
case RigidBodyType.Fixed:
|
|
587
|
+
case RigidBodyType.KinematicPositionBased:
|
|
588
|
+
case RigidBodyType.KinematicVelocityBased:
|
|
589
|
+
if (translation)
|
|
590
|
+
body.setNextKinematicTranslation(worldPosition);
|
|
591
|
+
if (rotation)
|
|
592
|
+
body.setNextKinematicRotation(worldQuaternion);
|
|
593
|
+
break;
|
|
594
|
+
default:
|
|
595
|
+
if (translation)
|
|
596
|
+
body.setTranslation(worldPosition, false);
|
|
597
|
+
if (rotation)
|
|
598
|
+
body.setRotation(worldQuaternion, false);
|
|
599
|
+
break;
|
|
600
|
+
|
|
601
|
+
}
|
|
602
|
+
body.wakeUp();
|
|
545
603
|
// physicsBody.setBodyType(RAPIER.RigidBodyType.Fixed);
|
|
546
|
-
if (translation)
|
|
547
|
-
body.setTranslation(worldPosition, false);
|
|
548
|
-
if (rotation)
|
|
549
|
-
body.setRotation(worldQuaternion, false);
|
|
550
604
|
// physicsBody.setLinvel(vel, false);
|
|
551
|
-
body.wakeUp();
|
|
552
605
|
|
|
553
606
|
// update velocity
|
|
554
607
|
// const pos = physicsBody.translation();
|
|
@@ -600,25 +653,6 @@ export class Physics {
|
|
|
600
653
|
}
|
|
601
654
|
|
|
602
655
|
|
|
603
|
-
export interface IColliderProvider {
|
|
604
|
-
getCollider(obj: Object3D): ICollider;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
let colliderProvider: IColliderProvider | null = null;
|
|
608
|
-
export function registerColliderProvider(prov: IColliderProvider) {
|
|
609
|
-
colliderProvider = prov;
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
class CollisionContext implements ICollisionContext {
|
|
613
|
-
|
|
614
|
-
getCollider(obj: Object3D<Event>): ICollider {
|
|
615
|
-
return colliderProvider!.getCollider(obj);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
656
|
|
|
623
657
|
/** responsible of processing collision events for the component system */
|
|
624
658
|
class PhysicsCollisionHandler {
|
|
@@ -642,7 +676,8 @@ class PhysicsCollisionHandler {
|
|
|
642
676
|
const col2 = this.world!.getCollider(handle2);
|
|
643
677
|
const colliderComponent1 = col1[$componentKey];
|
|
644
678
|
const colliderComponent2 = col2[$componentKey];
|
|
645
|
-
|
|
679
|
+
if (debugCollisions)
|
|
680
|
+
console.log("EVT", colliderComponent1.name, colliderComponent2.name, started, col1, col2);
|
|
646
681
|
if (colliderComponent1 && colliderComponent2) {
|
|
647
682
|
if (started) {
|
|
648
683
|
this.onCollisionStarted(colliderComponent1, col1, colliderComponent2, col2);
|
|
@@ -710,7 +745,7 @@ class PhysicsCollisionHandler {
|
|
|
710
745
|
for (const active of this.activeTriggers) {
|
|
711
746
|
const c = active.component;
|
|
712
747
|
if (c.activeAndEnabled && c.onTriggerStay) {
|
|
713
|
-
const arg = active.
|
|
748
|
+
const arg = active.otherCollider;
|
|
714
749
|
c.onTriggerStay(arg);
|
|
715
750
|
}
|
|
716
751
|
}
|
|
@@ -58,6 +58,7 @@ export class ContextArgs {
|
|
|
58
58
|
alias: string | undefined | null = undefined;
|
|
59
59
|
domElement: HTMLElement | null;
|
|
60
60
|
renderer?: THREE.WebGLRenderer = undefined;
|
|
61
|
+
hash?: string;
|
|
61
62
|
|
|
62
63
|
constructor(domElement: HTMLElement | null) {
|
|
63
64
|
this.domElement = domElement ?? document.body;
|
|
@@ -70,7 +71,8 @@ export enum FrameEvent {
|
|
|
70
71
|
LateUpdate = 2,
|
|
71
72
|
OnBeforeRender = 3,
|
|
72
73
|
OnAfterRender = 4,
|
|
73
|
-
|
|
74
|
+
PrePhysicsStep = 9,
|
|
75
|
+
PostPhysicsStep = 10,
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
export enum XRSessionMode {
|
|
@@ -81,12 +83,12 @@ export enum XRSessionMode {
|
|
|
81
83
|
export declare type OnBeforeRenderCallback = (renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, geometry: THREE.BufferGeometry, material: THREE.Material, group: THREE.Group) => void
|
|
82
84
|
|
|
83
85
|
|
|
84
|
-
export function registerComponent(script
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
export function registerComponent(script: IComponent, context?: Context) {
|
|
87
|
+
if (!script) return;
|
|
88
|
+
const new_scripts = context?.new_scripts ?? Context.Current.new_scripts;
|
|
89
|
+
if (!new_scripts.includes(script)) {
|
|
90
|
+
new_scripts.push(script);
|
|
91
|
+
}
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
export class Context {
|
|
@@ -105,13 +107,16 @@ export class Context {
|
|
|
105
107
|
alias: string | undefined | null;
|
|
106
108
|
isManagedExternally: boolean = false;
|
|
107
109
|
|
|
110
|
+
/** used to append to loaded assets */
|
|
111
|
+
hash?: string;
|
|
112
|
+
|
|
108
113
|
domElement: HTMLElement;
|
|
109
114
|
get resolutionScaleFactor() { return this._resolutionScaleFactor; }
|
|
110
115
|
/** use to scale the resolution up or down of the renderer. default is 1 */
|
|
111
|
-
set resolutionScaleFactor(val: number) {
|
|
112
|
-
if(val === this._resolutionScaleFactor) return;
|
|
113
|
-
if(typeof val !== "number") return;
|
|
114
|
-
if(val <= 0) {
|
|
116
|
+
set resolutionScaleFactor(val: number) {
|
|
117
|
+
if (val === this._resolutionScaleFactor) return;
|
|
118
|
+
if (typeof val !== "number") return;
|
|
119
|
+
if (val <= 0) {
|
|
115
120
|
console.error("Invalid resolution scale factor", val);
|
|
116
121
|
return;
|
|
117
122
|
}
|
|
@@ -124,7 +129,9 @@ export class Context {
|
|
|
124
129
|
get domX(): number { return this.domElement.offsetLeft; }
|
|
125
130
|
get domY(): number { return this.domElement.offsetTop; }
|
|
126
131
|
get isInXR() { return this.renderer.xr?.isPresenting || false; }
|
|
127
|
-
xrSessionMode
|
|
132
|
+
xrSessionMode: XRSessionMode | undefined = undefined;
|
|
133
|
+
get isInVR() { return this.xrSessionMode === XRSessionMode.ImmersiveVR; }
|
|
134
|
+
get isInAR() { return this.xrSessionMode === XRSessionMode.ImmersiveAR; }
|
|
128
135
|
get xrSession() { return this.renderer.xr?.getSession(); }
|
|
129
136
|
get arOverlayElement(): HTMLElement {
|
|
130
137
|
const el = this.domElement as any;
|
|
@@ -182,7 +189,7 @@ export class Context {
|
|
|
182
189
|
rendererData: RendererData;
|
|
183
190
|
addressables: Addressables;
|
|
184
191
|
lightmaps: ILightDataRegistry;
|
|
185
|
-
players
|
|
192
|
+
players: PlayerViewManager;
|
|
186
193
|
|
|
187
194
|
private _sizeChanged: boolean = false;
|
|
188
195
|
private _isCreated: boolean = false;
|
|
@@ -193,6 +200,7 @@ export class Context {
|
|
|
193
200
|
this.name = args?.name || "";
|
|
194
201
|
this.alias = args?.alias;
|
|
195
202
|
this.domElement = args?.domElement || document.body;
|
|
203
|
+
this.hash = args?.hash;
|
|
196
204
|
if (args?.renderer) {
|
|
197
205
|
this.renderer = args.renderer;
|
|
198
206
|
this.isManagedExternally = true;
|
|
@@ -232,7 +240,7 @@ export class Context {
|
|
|
232
240
|
this.lightmaps = new LightDataRegistry(this);
|
|
233
241
|
this.players = new PlayerViewManager(this);
|
|
234
242
|
|
|
235
|
-
window.addEventListener('resize', () => this._sizeChanged = true
|
|
243
|
+
window.addEventListener('resize', () => this._sizeChanged = true);
|
|
236
244
|
const ro = new ResizeObserver(_ => this._sizeChanged = true);
|
|
237
245
|
ro.observe(this.domElement);
|
|
238
246
|
}
|
|
@@ -335,13 +343,13 @@ export class Context {
|
|
|
335
343
|
}
|
|
336
344
|
|
|
337
345
|
removeCamera(cam?: Camera | null) {
|
|
338
|
-
if(!cam) return;
|
|
346
|
+
if (!cam) return;
|
|
339
347
|
const index = this._cameraStack.indexOf(cam);
|
|
340
348
|
if (index >= 0) this._cameraStack.splice(index, 1);
|
|
341
349
|
|
|
342
350
|
if (this.mainCameraComponent === cam) {
|
|
343
351
|
this.mainCameraComponent = undefined;
|
|
344
|
-
|
|
352
|
+
|
|
345
353
|
if (this._cameraStack.length > 0) {
|
|
346
354
|
const last = this._cameraStack[this._cameraStack.length - 1];
|
|
347
355
|
this.setCurrentCamera(last);
|
|
@@ -569,8 +577,9 @@ export class Context {
|
|
|
569
577
|
const physicsSteps = 1;
|
|
570
578
|
const dt = this.time.deltaTime / physicsSteps;
|
|
571
579
|
for (let i = 0; i < physicsSteps; i++) {
|
|
580
|
+
this.executeCoroutines(FrameEvent.PrePhysicsStep);
|
|
572
581
|
this.physics.step(dt);
|
|
573
|
-
this.executeCoroutines(FrameEvent.
|
|
582
|
+
this.executeCoroutines(FrameEvent.PostPhysicsStep);
|
|
574
583
|
}
|
|
575
584
|
}
|
|
576
585
|
catch (err) {
|
|
@@ -173,7 +173,7 @@ export class ContactPoint {
|
|
|
173
173
|
/// all info in here must be readonly because the object is only created once per started collision
|
|
174
174
|
export class Collision {
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
readonly contacts: ContactPoint[];
|
|
177
177
|
|
|
178
178
|
constructor(obj: Object3D, otherCollider: ICollider, contacts: ContactPoint[]) {
|
|
179
179
|
this.me = obj;
|
|
@@ -201,6 +201,7 @@ export class Collision {
|
|
|
201
201
|
return this.collider?.attachedRigidbody;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
+
|
|
204
205
|
|
|
205
206
|
// private _normal?: Vector3;
|
|
206
207
|
// get normal(): Vector3 {
|
|
@@ -112,6 +112,14 @@ export class Animation extends Behaviour {
|
|
|
112
112
|
return this.actions?.find(a => a.getClip().name === name);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
get isPlaying() {
|
|
116
|
+
for (let i = 0; i < this._currentActions.length; i++) {
|
|
117
|
+
if (this._currentActions[i].isRunning())
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
|
|
115
123
|
play(clipOrNumber: AnimationClip | number | string, options?: PlayOptions): Promise<AnimationAction> | void {
|
|
116
124
|
this.init();
|
|
117
125
|
if (!this.mixer) return;
|
|
@@ -218,7 +218,7 @@ export class AnimatorController {
|
|
|
218
218
|
if (!allConditionsAreMet) continue;
|
|
219
219
|
|
|
220
220
|
if (debug && allConditionsAreMet) {
|
|
221
|
-
console.log("All conditions are met", transition);
|
|
221
|
+
// console.log("All conditions are met", transition);
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
// disable triggers
|
|
@@ -232,16 +232,16 @@ export class AnimatorController {
|
|
|
232
232
|
if (action) {
|
|
233
233
|
const dur = state.motion.clip!.duration;
|
|
234
234
|
const normalizedTime = dur <= 0 ? 1 : action.time / dur;
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
) {
|
|
235
|
+
const makeTransition = transition.hasExitTime ? normalizedTime >= transition.exitTime : true;
|
|
236
|
+
// console.log(state.name, makeTransition, transition.hasExitTime, normalizedTime, transition.exitTime)
|
|
237
|
+
if (makeTransition) {
|
|
239
238
|
// if (transition.hasExitTime && transition.exitTime >= .9999)
|
|
240
239
|
action.clampWhenFinished = true;
|
|
241
240
|
// else action.clampWhenFinished = false;
|
|
242
|
-
if (debug)
|
|
243
|
-
|
|
244
|
-
console.log(
|
|
241
|
+
if (debug)
|
|
242
|
+
{
|
|
243
|
+
console.log("transition to " + transition.destinationState, transition, normalizedTime, transition.exitTime, transition.hasExitTime);
|
|
244
|
+
// console.log(action.time, transition.exitTime);
|
|
245
245
|
}
|
|
246
246
|
this.transitionTo(transition.destinationState as State, transition.duration, transition.offset);
|
|
247
247
|
// use the first transition that matches all conditions and make the transition as soon as in range
|
|
@@ -252,7 +252,7 @@ export class AnimatorController {
|
|
|
252
252
|
this.transitionTo(transition.destinationState as State, transition.duration, transition.offset);
|
|
253
253
|
return;
|
|
254
254
|
}
|
|
255
|
-
|
|
255
|
+
// if none of the transitions can be made continue searching for another transition meeting the conditions
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
let didTriggerLooping = false;
|
|
@@ -376,7 +376,13 @@ export class AnimatorController {
|
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
private createAction(clip: AnimationClip) {
|
|
379
|
-
|
|
379
|
+
|
|
380
|
+
// uncache clip causes issues when multiple states use the same clip
|
|
381
|
+
// this._mixer.uncacheClip(clip);
|
|
382
|
+
// instead only uncache the action when one already exists to make sure
|
|
383
|
+
// we get unique actions per state
|
|
384
|
+
const existing = this._mixer.existingAction(clip);
|
|
385
|
+
if (existing) this._mixer.uncacheAction(clip, this.animator?.gameObject);
|
|
380
386
|
|
|
381
387
|
if (this.animator?.applyRootMotion) {
|
|
382
388
|
if (!this.rootMotionHandler) {
|
|
@@ -387,7 +393,6 @@ export class AnimatorController {
|
|
|
387
393
|
return this.rootMotionHandler.createClip(this._mixer, root, clip);
|
|
388
394
|
}
|
|
389
395
|
else {
|
|
390
|
-
|
|
391
396
|
const action = this._mixer.clipAction(clip);
|
|
392
397
|
return action;
|
|
393
398
|
}
|