@@ -29,7 +29,8 @@
|
|
29
29
|
|
30
30
|
// to make this work properly we need to resolve the paths all to absolute paths
|
31
31
|
// assuming that id is relative to importer
|
32
|
-
|
32
|
+
if (importer)
|
33
|
+
id = path.resolve(path.dirname(importer), id);
|
33
34
|
|
34
35
|
if (!graph.allNodes.has(id)) {
|
35
36
|
graph.allNodes.set(id, {
|
@@ -87,7 +87,8 @@
|
|
87
87
|
/**@deprecated use setBool */
|
88
88
|
SetBool(name: string | number, val: boolean) { this.setBool(name, val); }
|
89
89
|
setBool(name: string | number, value: boolean) {
|
90
|
-
if(
|
90
|
+
if (debug) console.log("setBool", name, value);
|
91
|
+
if (this.runtimeAnimatorController?.getBool(name) !== value)
|
91
92
|
this._parametersAreDirty = true;
|
92
93
|
this.runtimeAnimatorController?.setBool(name, value);
|
93
94
|
}
|
@@ -95,55 +96,71 @@
|
|
95
96
|
/**@deprecated use getBool */
|
96
97
|
GetBool(name: string | number) { return this.getBool(name); }
|
97
98
|
getBool(name: string | number): boolean {
|
98
|
-
|
99
|
+
const res = this.runtimeAnimatorController?.getBool(name) ?? false;
|
100
|
+
if (debug) console.log("getBool", name, res);
|
101
|
+
return res;
|
99
102
|
}
|
100
103
|
|
104
|
+
toggleBool(name: string | number) {
|
105
|
+
this.setBool(name, !this.getBool(name));
|
106
|
+
}
|
107
|
+
|
101
108
|
/**@deprecated use setFloat */
|
102
109
|
SetFloat(name: string | number, val: number) { this.setFloat(name, val); }
|
103
110
|
setFloat(name: string | number, val: number) {
|
104
|
-
if(this.runtimeAnimatorController?.getFloat(name) !== val)
|
111
|
+
if (this.runtimeAnimatorController?.getFloat(name) !== val)
|
105
112
|
this._parametersAreDirty = true;
|
113
|
+
if (debug) console.log("setFloat", name, val);
|
106
114
|
this.runtimeAnimatorController?.setFloat(name, val);
|
107
115
|
}
|
108
116
|
|
109
117
|
/**@deprecated use getFloat */
|
110
118
|
GetFloat(name: string | number) { return this.getFloat(name); }
|
111
119
|
getFloat(name: string | number): number {
|
112
|
-
|
120
|
+
const res = this.runtimeAnimatorController?.getFloat(name) ?? -1;
|
121
|
+
if (debug) console.log("getFloat", name, res);
|
122
|
+
return res;
|
113
123
|
}
|
114
124
|
|
115
125
|
/**@deprecated use setInteger */
|
116
126
|
SetInteger(name: string | number, val: number) { this.setInteger(name, val); }
|
117
127
|
setInteger(name: string | number, val: number) {
|
118
|
-
if(this.runtimeAnimatorController?.getInteger(name) !== val)
|
128
|
+
if (this.runtimeAnimatorController?.getInteger(name) !== val)
|
119
129
|
this._parametersAreDirty = true;
|
130
|
+
if (debug) console.log("setInteger", name, val);
|
120
131
|
this.runtimeAnimatorController?.setInteger(name, val);
|
121
132
|
}
|
122
133
|
|
123
134
|
/**@deprecated use getInteger */
|
124
135
|
GetInteger(name: string | number) { return this.getInteger(name); }
|
125
136
|
getInteger(name: string | number): number {
|
126
|
-
|
137
|
+
const res = this.runtimeAnimatorController?.getInteger(name) ?? -1;
|
138
|
+
if (debug) console.log("getInteger", name, res);
|
139
|
+
return res;
|
127
140
|
}
|
128
141
|
|
129
142
|
/**@deprecated use setTrigger */
|
130
143
|
SetTrigger(name: string | number) { this.setTrigger(name); }
|
131
144
|
setTrigger(name: string | number) {
|
145
|
+
this._parametersAreDirty = true;
|
146
|
+
if (debug) console.log("setTrigger", name);
|
132
147
|
this.runtimeAnimatorController?.setTrigger(name);
|
133
|
-
this._parametersAreDirty = true;
|
134
148
|
}
|
135
149
|
|
136
150
|
/**@deprecated use resetTrigger */
|
137
151
|
ResetTrigger(name: string | number) { this.resetTrigger(name); }
|
138
152
|
resetTrigger(name: string | number) {
|
153
|
+
this._parametersAreDirty = true;
|
154
|
+
if (debug) console.log("resetTrigger", name);
|
139
155
|
this.runtimeAnimatorController?.resetTrigger(name);
|
140
|
-
this._parametersAreDirty = true;
|
141
156
|
}
|
142
157
|
|
143
158
|
/**@deprecated use getTrigger */
|
144
159
|
GetTrigger(name: string | number) { this.getTrigger(name); }
|
145
160
|
getTrigger(name: string | number) {
|
146
|
-
this.runtimeAnimatorController?.getTrigger(name);
|
161
|
+
const res = this.runtimeAnimatorController?.getTrigger(name);
|
162
|
+
if (debug) console.log("getTrigger", name, res);
|
163
|
+
return res;
|
147
164
|
}
|
148
165
|
|
149
166
|
/**@deprecated use isInTransition */
|
@@ -156,6 +173,7 @@
|
|
156
173
|
SetSpeed(speed: number) { return this.setSpeed(speed); }
|
157
174
|
setSpeed(speed: number) {
|
158
175
|
if (speed === this.speed) return;
|
176
|
+
if (debug) console.log("setSpeed", speed);
|
159
177
|
this.speed = speed;
|
160
178
|
this._animatorController?.setSpeed(speed);
|
161
179
|
}
|
@@ -113,6 +113,7 @@
|
|
113
113
|
internalDestroy(instance, recursive, dispose, true, allComponents);
|
114
114
|
for (const comp of allComponents) {
|
115
115
|
comp.gameObject = null!;
|
116
|
+
//@ts-ignore
|
116
117
|
comp.context = null;
|
117
118
|
}
|
118
119
|
}
|
@@ -273,6 +273,7 @@
|
|
273
273
|
this.contextBeforeRenderCallbacks.set(context, cb);
|
274
274
|
context.pre_render_callbacks.push(cb);
|
275
275
|
}
|
276
|
+
object.renderOrder = 999999;
|
276
277
|
object.layers.disableAll();
|
277
278
|
object.layers.enable(2);
|
278
279
|
object[$cacheSymbol] = cache;
|
@@ -133,7 +133,7 @@
|
|
133
133
|
const active = isComponent ? componentInstance.activeAndEnabled : true;
|
134
134
|
const context = isComponent ? componentInstance.context : undefined;
|
135
135
|
try {
|
136
|
-
if (isComponent) {
|
136
|
+
if (isComponent && context) {
|
137
137
|
removeScriptFromContext(componentInstance, context);
|
138
138
|
}
|
139
139
|
if (isComponent && active) {
|
@@ -170,7 +170,7 @@
|
|
170
170
|
if (inst["onAfterHotReloadFields"]) inst["onAfterHotReloadFields"]();
|
171
171
|
}
|
172
172
|
finally {
|
173
|
-
if (isComponent) {
|
173
|
+
if (isComponent && context) {
|
174
174
|
addScriptToArrays(componentInstance, context);
|
175
175
|
}
|
176
176
|
if (isComponent && active) {
|
@@ -1309,6 +1309,7 @@
|
|
1309
1309
|
const c = active.component;
|
1310
1310
|
if (c.destroyed) continue;
|
1311
1311
|
if (c.activeAndEnabled && c.onCollisionStay) {
|
1312
|
+
if(active.collision.collider.destroyed) continue;
|
1312
1313
|
const arg = active.collision;
|
1313
1314
|
c.onCollisionStay(arg);
|
1314
1315
|
}
|
@@ -1318,6 +1319,7 @@
|
|
1318
1319
|
if (c.destroyed) continue;
|
1319
1320
|
if (c.activeAndEnabled && c.onTriggerStay) {
|
1320
1321
|
const arg = active.otherCollider;
|
1322
|
+
if(arg.destroyed) continue;
|
1321
1323
|
c.onTriggerStay(arg);
|
1322
1324
|
}
|
1323
1325
|
}
|
@@ -1328,7 +1330,7 @@
|
|
1328
1330
|
for (let i = 0; i < this.activeCollisions.length; i++) {
|
1329
1331
|
const active = this.activeCollisions[i];
|
1330
1332
|
const collider = active.collider;
|
1331
|
-
if (collider.destroyed) {
|
1333
|
+
if (collider.destroyed || active.collision.collider.destroyed) {
|
1332
1334
|
this.activeCollisions.splice(i, 1);
|
1333
1335
|
i--;
|
1334
1336
|
continue;
|
@@ -1346,7 +1348,7 @@
|
|
1346
1348
|
for (let i = 0; i < this.activeCollisionsStay.length; i++) {
|
1347
1349
|
const active = this.activeCollisionsStay[i];
|
1348
1350
|
const collider = active.collider;
|
1349
|
-
if (collider.destroyed) {
|
1351
|
+
if (collider.destroyed || active.collision.collider.destroyed) {
|
1350
1352
|
this.activeCollisionsStay.splice(i, 1);
|
1351
1353
|
i--;
|
1352
1354
|
continue;
|
@@ -1364,7 +1366,7 @@
|
|
1364
1366
|
for (let i = 0; i < this.activeTriggers.length; i++) {
|
1365
1367
|
const active = this.activeTriggers[i];
|
1366
1368
|
const collider = active.collider;
|
1367
|
-
if (collider.destroyed) {
|
1369
|
+
if (collider.destroyed || active.otherCollider.destroyed) {
|
1368
1370
|
this.activeTriggers.splice(i, 1);
|
1369
1371
|
i--;
|
1370
1372
|
continue;
|
@@ -215,6 +215,7 @@
|
|
215
215
|
method: string,
|
216
216
|
target: string,
|
217
217
|
argument?: any,
|
218
|
+
arguments?: Array<any>,
|
218
219
|
enabled?: boolean,
|
219
220
|
}
|
220
221
|
|
@@ -280,16 +281,24 @@
|
|
280
281
|
}
|
281
282
|
}
|
282
283
|
|
283
|
-
|
284
|
-
|
285
|
-
if (typeof args === "object") {
|
284
|
+
function deserializeArgument(arg: any) {
|
285
|
+
if (typeof arg === "object") {
|
286
286
|
// Try to deserialize the call argument to either a object or a component reference
|
287
|
-
let argRes = objectSerializer.onDeserialize(
|
288
|
-
if (!argRes) argRes = componentSerializer.onDeserialize(
|
289
|
-
if (argRes)
|
287
|
+
let argRes = objectSerializer.onDeserialize(arg, context);
|
288
|
+
if (!argRes) argRes = componentSerializer.onDeserialize(arg, context);
|
289
|
+
if (argRes) return argRes;
|
290
290
|
}
|
291
|
+
return arg;
|
291
292
|
}
|
292
293
|
|
294
|
+
let args = call.argument;
|
295
|
+
if (args !== undefined) {
|
296
|
+
args = deserializeArgument(args);
|
297
|
+
}
|
298
|
+
else if (call.arguments !== undefined) {
|
299
|
+
args = call.arguments.map(deserializeArgument);
|
300
|
+
}
|
301
|
+
|
293
302
|
// This is the final method we pass to the call info (or undefined if the method couldnt be resolved)
|
294
303
|
const eventMethod = hasMethod ? this.createEventMethod(target, call.method, args) : undefined;
|
295
304
|
const fn = new CallInfo(eventMethod, call.enabled);
|
@@ -326,8 +335,17 @@
|
|
326
335
|
return (...forwardedArgs) => {
|
327
336
|
const method = target[methodName];
|
328
337
|
if (typeof method === "function") {
|
329
|
-
if (args !== undefined)
|
330
|
-
|
338
|
+
if (args !== undefined) {
|
339
|
+
// we now have support for creating event methods with multiple arguments
|
340
|
+
// an argument can not be an array right now - so if we receive an array we assume it's the array of arguments that we want to call the method with
|
341
|
+
// this means ["test", true] will invoke the method like this: myFunction("test", true)
|
342
|
+
if (Array.isArray(args))
|
343
|
+
method?.call(target, ...args);
|
344
|
+
// in any other case (when we just have one argument) we just call the method with the argument
|
345
|
+
// we an not use ...args by default becaue that would break string arguments (it would then just use the first character)
|
346
|
+
else
|
347
|
+
method?.call(target, args);
|
348
|
+
}
|
331
349
|
else // support invoking EventList with any number of arguments (if none were declared in unity)
|
332
350
|
method?.call(target, ...forwardedArgs);
|
333
351
|
}
|
@@ -357,7 +375,7 @@
|
|
357
375
|
colorSpace: THREE.LinearSRGBColorSpace,
|
358
376
|
});
|
359
377
|
rt.texture = tex;
|
360
|
-
|
378
|
+
|
361
379
|
tex.isRenderTargetTexture = true;
|
362
380
|
tex.flipY = true;
|
363
381
|
tex.offset.y = 1;
|
@@ -236,7 +236,18 @@
|
|
236
236
|
};
|
237
237
|
}
|
238
238
|
|
239
|
+
export function getParentHierarchyPath(obj: Object3D): string {
|
240
|
+
let path = obj?.name || "";
|
241
|
+
if(!obj) return path;
|
242
|
+
let parent = obj.parent;
|
243
|
+
while (parent) {
|
244
|
+
path = parent.name + "/" + path;
|
245
|
+
parent = parent.parent;
|
246
|
+
}
|
247
|
+
return path;
|
248
|
+
}
|
239
249
|
|
250
|
+
|
240
251
|
export function isAnimationAction(obj: object) {
|
241
252
|
if (obj) {
|
242
253
|
// this doesnt work :(
|
@@ -101,10 +101,14 @@
|
|
101
101
|
}
|
102
102
|
|
103
103
|
export declare interface IGameObject extends Object3D {
|
104
|
+
|
105
|
+
/** the object's unique identifier */
|
104
106
|
guid: string | undefined;
|
105
107
|
|
108
|
+
/** if the object is enabled in the hierarchy (usually equivalent to `visible`) */
|
106
109
|
activeSelf: boolean;
|
107
110
|
|
111
|
+
/** call to destroy this object including all components that are attached to it. Will destroy all children recursively */
|
108
112
|
destroy(): void;
|
109
113
|
|
110
114
|
/** NOTE: this is just a wrapper for devs coming from Unity. Please use this.gameObject instead. In Needle Engine this.gameObject is the same as this.gameObject.transform. See the tutorial link below for more information
|
@@ -113,14 +117,26 @@
|
|
113
117
|
* */
|
114
118
|
get transform(): IGameObject;
|
115
119
|
|
120
|
+
/** Add a new component to this object. Expects a component type (e.g. `addNewComponent(Animator)`) */
|
116
121
|
addNewComponent<T>(type: Constructor<T>): T | null;
|
122
|
+
/** Remove a component from this object. Expected a component instance
|
123
|
+
* @returns the removed component (equal to the passed in component)
|
124
|
+
*/
|
117
125
|
removeComponent(comp: IComponent): IComponent;
|
126
|
+
/** Searches for a component type on this object. If no component of the searched type exists yet a new instance will be created and returned */
|
118
127
|
getOrAddComponent<T>(typeName: Constructor<T> | null): T;
|
128
|
+
/** Tries to find a component of a type on this object.
|
129
|
+
* @returns the first instance of a component on this object that matches the passed in type or null if no component of this type (or a subtype) exists */
|
119
130
|
getComponent<T>(type: Constructor<T>): T | null;
|
131
|
+
/** @returns all components of a certain type on this object */
|
120
132
|
getComponents<T>(type: Constructor<T>, arr?: T[]): Array<T>;
|
133
|
+
/** Finds a component of a certain type on this object OR a child object if any exists */
|
121
134
|
getComponentInChildren<T>(type: Constructor<T>): T | null;
|
135
|
+
/** Finds all components of a certain type on this object AND all children (recursively) */
|
122
136
|
getComponentsInChildren<T>(type: Constructor<T>, arr?: T[]): Array<T>;
|
137
|
+
/** Finds a component of a certain type on this object OR a parent object if any exists */
|
123
138
|
getComponentInParent<T>(type: Constructor<T>): T | null;
|
139
|
+
/** Finds all components of a certain type on this object AND all parents (recursively) */
|
124
140
|
getComponentsInParent<T>(type: Constructor<T>, arr?: T[]): Array<T>;
|
125
141
|
|
126
142
|
get worldPosition(): Vector3;
|
@@ -144,6 +160,7 @@
|
|
144
160
|
export interface IComponent extends IHasGuid {
|
145
161
|
get isComponent(): boolean;
|
146
162
|
|
163
|
+
/** the object this component is attached to */
|
147
164
|
gameObject: IGameObject;
|
148
165
|
// guid: string;
|
149
166
|
enabled: boolean;
|
@@ -327,7 +344,9 @@
|
|
327
344
|
private readonly _normal: Vec3;
|
328
345
|
private readonly _tangentVelocity: Vec3;
|
329
346
|
|
347
|
+
/** the distance of the collision point */
|
330
348
|
readonly distance: number;
|
349
|
+
/** the impulse velocity */
|
331
350
|
readonly impulse: number;
|
332
351
|
readonly friction: number;
|
333
352
|
|
@@ -343,7 +362,7 @@
|
|
343
362
|
return target.set(this._normal.x, this._normal.y, this._normal.z);
|
344
363
|
}
|
345
364
|
|
346
|
-
/** */
|
365
|
+
/** worldspace tangent */
|
347
366
|
get tangentVelocity() {
|
348
367
|
const target = contactsVectorBuffer.get();
|
349
368
|
return target.set(this._tangentVelocity.x, this._tangentVelocity.y, this._tangentVelocity.z);
|
@@ -361,55 +380,36 @@
|
|
361
380
|
|
362
381
|
/// all info in here must be readonly because the object is only created once per started collision
|
363
382
|
export class Collision {
|
383
|
+
|
384
|
+
/** The contact points of this collision. Contains information about positions, normals, distance, friction, impulse... */
|
364
385
|
readonly contacts: ContactPoint[];
|
365
386
|
|
366
|
-
constructor(obj:
|
387
|
+
constructor(obj: IGameObject, otherCollider: ICollider, contacts: ContactPoint[]) {
|
367
388
|
this.me = obj;
|
368
389
|
this._collider = otherCollider;
|
369
390
|
this._gameObject = otherCollider.gameObject;
|
370
391
|
this.contacts = contacts;
|
371
392
|
}
|
372
393
|
|
373
|
-
|
394
|
+
/** the gameobject this collision event belongs to (e.g. if onCollisionEnter is called then `me` is the same as `this.gameObject`) */
|
395
|
+
readonly me: IGameObject;
|
396
|
+
|
374
397
|
private _collider: ICollider;
|
375
|
-
|
376
|
-
/** the collider the collision happened with */
|
398
|
+
/** the other collider the collision happened with */
|
377
399
|
get collider(): ICollider {
|
378
400
|
return this._collider;
|
379
401
|
}
|
380
402
|
|
381
|
-
|
382
|
-
|
383
|
-
get gameObject():
|
403
|
+
private _gameObject: IGameObject;
|
404
|
+
/** the other object the collision happened with */
|
405
|
+
get gameObject(): IGameObject {
|
384
406
|
return this._gameObject;
|
385
407
|
}
|
386
408
|
|
387
|
-
/** the rigidbody we hit, null if none attached */
|
409
|
+
/** the other rigidbody we hit, null if none attached */
|
388
410
|
get rigidBody(): IRigidbody | null {
|
389
411
|
return this.collider?.attachedRigidbody;
|
390
412
|
}
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
// private _normal?: Vector3;
|
395
|
-
// get normal(): Vector3 {
|
396
|
-
// if (!this._normal) {
|
397
|
-
// const vec = this.collision.contact.ni;
|
398
|
-
// this._normal = new Vector3(vec.x, vec.y, vec.z);
|
399
|
-
// }
|
400
|
-
// return this._normal;
|
401
|
-
// }
|
402
|
-
|
403
|
-
|
404
|
-
// private _point?: Vector3;
|
405
|
-
// get point(): Vector3 {
|
406
|
-
// if (!this._point) {
|
407
|
-
// const c = this.collision.contact;
|
408
|
-
// const point = c.bi.position.clone().vadd(c.ri);
|
409
|
-
// this._point = new Vector3(point.x, point.y, point.z);
|
410
|
-
// }
|
411
|
-
// return this._point;
|
412
|
-
// }
|
413
413
|
}
|
414
414
|
|
415
415
|
export type RaycastResult = null | { point: Vector3, collider: ICollider, normal?: Vector3 };
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { TypeStore } from "./../engine_typestore.js"
|
2
|
-
|
2
|
+
|
3
3
|
// Import types
|
4
4
|
import { __Ignore } from "../../engine-components/codegen/components.js";
|
5
5
|
import { ActionBuilder } from "../../engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js";
|
@@ -219,7 +219,7 @@
|
|
219
219
|
import { XRGrabRendering } from "../../engine-components/webxr/WebXRGrabRendering.js";
|
220
220
|
import { XRRig } from "../../engine-components/webxr/WebXRRig.js";
|
221
221
|
import { XRState } from "../../engine-components/XRFlag.js";
|
222
|
-
|
222
|
+
|
223
223
|
// Register types
|
224
224
|
TypeStore.add("__Ignore", __Ignore);
|
225
225
|
TypeStore.add("ActionBuilder", ActionBuilder);
|
@@ -115,6 +115,7 @@
|
|
115
115
|
const original = this.obj.matrixWorld.multiplyMatrices.bind(this.obj.matrixWorld);
|
116
116
|
const lastParentMatrix = new Matrix4();
|
117
117
|
this.obj.matrixWorld["multiplyMatrices"] = (parent: Matrix4, matrix: Matrix4) => {
|
118
|
+
if (this.context.physics.engine?.isUpdating || this.mute) return original(parent, matrix);
|
118
119
|
if (!lastParentMatrix.equals(parent)) {
|
119
120
|
this.positionChanged = true;
|
120
121
|
this.rotationChanged = true;
|