@needle-tools/engine 2.63.3-pre → 2.64.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 +13 -0
- package/dist/needle-engine.js +9760 -9635
- package/dist/needle-engine.umd.cjs +237 -236
- package/lib/engine/engine_application.d.ts +7 -1
- package/lib/engine/engine_application.js +11 -0
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_constants.d.ts +1 -1
- package/lib/engine/engine_constants.js +1 -1
- package/lib/engine/engine_constants.js.map +1 -1
- package/lib/engine/engine_gameobject.js +2 -2
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_instancing.d.ts +1 -0
- package/lib/engine/engine_instancing.js +3 -2
- package/lib/engine/engine_instancing.js.map +1 -1
- package/lib/engine/engine_license.js +14 -13
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_mainloop_utils.js +27 -52
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_physics.d.ts +1 -0
- package/lib/engine/engine_physics.js +30 -0
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.d.ts +1 -0
- package/lib/engine/engine_serialization_builtin_serializer.js +30 -25
- package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
- package/lib/engine/engine_serialization_core.js +8 -0
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_setup.d.ts +1 -1
- package/lib/engine/engine_setup.js.map +1 -1
- package/lib/engine/engine_time.d.ts +1 -0
- package/lib/engine/engine_time.js +5 -1
- package/lib/engine/engine_time.js.map +1 -1
- package/lib/engine/engine_types.d.ts +12 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine-components/Animation.js +6 -6
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/AnimatorController.js +2 -0
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/AudioListener.js +2 -0
- package/lib/engine-components/AudioListener.js.map +1 -1
- package/lib/engine-components/AudioSource.d.ts +2 -1
- package/lib/engine-components/AudioSource.js +19 -4
- package/lib/engine-components/AudioSource.js.map +1 -1
- package/lib/engine-components/Component.d.ts +1 -0
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/GridHelper.d.ts +1 -0
- package/lib/engine-components/GridHelper.js +7 -0
- package/lib/engine-components/GridHelper.js.map +1 -1
- package/lib/engine-components/ParticleSystem.js +13 -1
- package/lib/engine-components/ParticleSystem.js.map +1 -1
- package/lib/engine-components/Renderer.d.ts +5 -1
- package/lib/engine-components/Renderer.js +78 -29
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/WebARSessionRoot.d.ts +1 -0
- package/lib/engine-components/WebARSessionRoot.js +10 -0
- package/lib/engine-components/WebARSessionRoot.js.map +1 -1
- package/lib/engine-components/js-extensions/Object3D.js +11 -1
- package/lib/engine-components/js-extensions/Object3D.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +5 -0
- package/lib/engine-components/timeline/PlayableDirector.js +36 -23
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +9 -0
- package/lib/engine-components/timeline/TimelineTracks.js +121 -21
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/engine/engine_application.ts +14 -3
- package/src/engine/engine_constants.ts +1 -1
- package/src/engine/engine_gameobject.ts +2 -2
- package/src/engine/engine_instancing.ts +3 -3
- package/src/engine/engine_license.ts +14 -13
- package/src/engine/engine_mainloop_utils.ts +32 -58
- package/src/engine/engine_physics.ts +23 -0
- package/src/engine/engine_serialization_builtin_serializer.ts +36 -27
- package/src/engine/engine_serialization_core.ts +8 -1
- package/src/engine/engine_setup.ts +1 -1
- package/src/engine/engine_time.ts +9 -4
- package/src/engine/engine_types.ts +36 -22
- package/src/engine-components/Animation.ts +6 -5
- package/src/engine-components/AnimatorController.ts +1 -0
- package/src/engine-components/AudioListener.ts +1 -0
- package/src/engine-components/AudioSource.ts +20 -6
- package/src/engine-components/Component.ts +3 -0
- package/src/engine-components/GridHelper.ts +10 -2
- package/src/engine-components/ParticleSystem.ts +15 -2
- package/src/engine-components/Renderer.ts +92 -33
- package/src/engine-components/WebARSessionRoot.ts +14 -0
- package/src/engine-components/js-extensions/Object3D.ts +11 -3
- package/src/engine-components/timeline/PlayableDirector.ts +35 -24
- package/src/engine-components/timeline/TimelineTracks.ts +132 -22
- package/src/tsconfig.json +33 -0
- package/src/engine/codegen/license.js +0 -1
- /package/{src/plugins → plugins}/vite/build.js +0 -0
- /package/{src/plugins → plugins}/vite/config.js +0 -0
- /package/{src/plugins → plugins}/vite/gzip.js +0 -0
- /package/{src/plugins → plugins}/vite/index.js +0 -0
- /package/{src/plugins → plugins}/vite/meta.js +0 -0
- /package/{src/plugins → plugins}/vite/poster-client.js +0 -0
- /package/{src/plugins → plugins}/vite/poster.js +0 -0
- /package/{src/plugins → plugins}/vite/reload-client.js +0 -0
- /package/{src/plugins → plugins}/vite/reload.js +0 -0
|
@@ -21,9 +21,9 @@ export interface UIDProvider {
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
export declare type CoroutineData = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
comp: IComponent,
|
|
25
|
+
main: Generator,
|
|
26
|
+
chained?: Array<Generator>
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
|
|
@@ -37,25 +37,25 @@ export interface IContext {
|
|
|
37
37
|
domElement: HTMLElement;
|
|
38
38
|
|
|
39
39
|
scripts: IComponent[];
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
40
|
+
scripts_pausedChanged: IComponent[];
|
|
41
|
+
// scripts with update event
|
|
42
|
+
scripts_earlyUpdate: IComponent[];
|
|
43
|
+
scripts_update: IComponent[];
|
|
44
|
+
scripts_lateUpdate: IComponent[];
|
|
45
|
+
scripts_onBeforeRender: IComponent[];
|
|
46
|
+
scripts_onAfterRender: IComponent[];
|
|
47
|
+
scripts_WithCorroutines: IComponent[];
|
|
48
|
+
coroutines: { [FrameEvent: number]: Array<CoroutineData> };
|
|
49
|
+
|
|
50
|
+
post_setup_callbacks: Function[];
|
|
51
|
+
pre_update_callbacks: Function[];
|
|
52
|
+
pre_render_callbacks: Function[];
|
|
53
|
+
post_render_callbacks: Function[];
|
|
54
|
+
|
|
55
|
+
new_scripts: IComponent[];
|
|
56
|
+
new_script_start: IComponent[];
|
|
57
|
+
new_scripts_pre_setup_callbacks: Function[];
|
|
58
|
+
new_scripts_post_setup_callbacks: Function[];
|
|
59
59
|
|
|
60
60
|
stopAllCoroutinesFrom(script: IComponent);
|
|
61
61
|
}
|
|
@@ -71,6 +71,13 @@ export declare interface IGameObject extends Object3D {
|
|
|
71
71
|
guid: string | undefined;
|
|
72
72
|
|
|
73
73
|
activeSelf: boolean;
|
|
74
|
+
|
|
75
|
+
/** 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
|
|
76
|
+
* @augments Object3D
|
|
77
|
+
* @tutorial https://fwd.needle.tools/needle-engine/docs/transform
|
|
78
|
+
* */
|
|
79
|
+
get transform(): Object3D;
|
|
80
|
+
|
|
74
81
|
addNewComponent<T>(type: Constructor<T>): T | null;
|
|
75
82
|
removeComponent(comp: IComponent): IComponent;
|
|
76
83
|
getOrAddComponent<T>(typeName: Constructor<T> | null): T;
|
|
@@ -100,12 +107,19 @@ export interface IComponent {
|
|
|
100
107
|
|
|
101
108
|
get activeAndEnabled(): boolean;
|
|
102
109
|
|
|
110
|
+
/** @internal */
|
|
103
111
|
__internalNewInstanceCreated();
|
|
112
|
+
/** @internal */
|
|
104
113
|
__internalAwake();
|
|
114
|
+
/** @internal */
|
|
105
115
|
__internalStart();
|
|
116
|
+
/** @internal */
|
|
106
117
|
__internalEnable();
|
|
118
|
+
/** @internal */
|
|
107
119
|
__internalDisable();
|
|
120
|
+
/** @internal */
|
|
108
121
|
__internalDestroy();
|
|
122
|
+
/** @internal */
|
|
109
123
|
resolveGuids?(guidsMap: GuidsMap): void;
|
|
110
124
|
|
|
111
125
|
/** experimental, called when the script is registered for the first time, this is called even if the component is not enabled. */
|
|
@@ -125,11 +125,12 @@ export class Animation extends Behaviour {
|
|
|
125
125
|
update() {
|
|
126
126
|
if (!this.mixer) return;
|
|
127
127
|
this.mixer.update(this.context.time.deltaTime);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
128
|
+
// this is now handled via matrix auto update
|
|
129
|
+
// for (const handle of this._handles) {
|
|
130
|
+
// handle._update();
|
|
131
|
+
// }
|
|
132
|
+
// if (this._handles?.length > 0)
|
|
133
|
+
// InstancingUtil.markDirty(this.gameObject);
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
getAction(name: string): THREE.AnimationAction | undefined | null {
|
|
@@ -146,6 +146,7 @@ export class AnimatorController {
|
|
|
146
146
|
if (!this.animator) return;
|
|
147
147
|
this.evaluateTransitions();
|
|
148
148
|
this.updateActiveStates();
|
|
149
|
+
if(!this._activeState) return;
|
|
149
150
|
const dt = this.animator.context.time.deltaTime;
|
|
150
151
|
if (this.animator.applyRootMotion) {
|
|
151
152
|
this.rootMotionHandler?.onBeforeUpdate();
|
|
@@ -16,6 +16,7 @@ export class AudioListener extends Behaviour {
|
|
|
16
16
|
|
|
17
17
|
awake() {
|
|
18
18
|
AudioSource.registerWaitForAllowAudio(() => {
|
|
19
|
+
if (this.destroyed) return;
|
|
19
20
|
const listener = this.listener;
|
|
20
21
|
if (listener == null) return;
|
|
21
22
|
// if the listener is already parented to some object d0nt change it
|
|
@@ -75,7 +75,7 @@ export class AudioSource extends Behaviour {
|
|
|
75
75
|
}
|
|
76
76
|
this.callbacks.length = 0;
|
|
77
77
|
};
|
|
78
|
-
|
|
78
|
+
const fn = callback.bind(this);
|
|
79
79
|
document.addEventListener('pointerdown', fn);
|
|
80
80
|
document.addEventListener('click', fn);
|
|
81
81
|
document.addEventListener('dragstart', fn);
|
|
@@ -133,7 +133,7 @@ export class AudioSource extends Behaviour {
|
|
|
133
133
|
get volume(): number { return this._volume; }
|
|
134
134
|
set volume(val: number) {
|
|
135
135
|
this._volume = val;
|
|
136
|
-
if (this.sound) {
|
|
136
|
+
if (this.sound && !this.context.application.muted) {
|
|
137
137
|
if (debug) console.log(this.name, "audio set volume", val);
|
|
138
138
|
this.sound.setVolume(val);
|
|
139
139
|
}
|
|
@@ -167,7 +167,9 @@ export class AudioSource extends Behaviour {
|
|
|
167
167
|
|
|
168
168
|
public get ShouldPlay(): boolean { return this.shouldPlay; }
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
|
|
171
|
+
private _focusCallback: any;
|
|
172
|
+
private _muteChangedCallback: any;
|
|
171
173
|
|
|
172
174
|
awake() {
|
|
173
175
|
this.audioLoader = new THREE.AudioLoader();
|
|
@@ -189,13 +191,22 @@ export class AudioSource extends Behaviour {
|
|
|
189
191
|
if (this.enabled && this.playOnAwake && !this.isPlaying && AudioSource._userInteractionRegistered) {
|
|
190
192
|
this.play();
|
|
191
193
|
}
|
|
192
|
-
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
this._muteChangedCallback = () => {
|
|
197
|
+
if (this.context.application.muted)
|
|
198
|
+
this.sound?.setVolume(0);
|
|
199
|
+
else
|
|
200
|
+
this.sound?.setVolume(this.volume);
|
|
201
|
+
}
|
|
193
202
|
|
|
194
203
|
this.context.application.addEventListener(ApplicationEvents.Visible, this._focusCallback);
|
|
204
|
+
this.context.application.addEventListener(ApplicationEvents.MuteChanged, this._muteChangedCallback);
|
|
195
205
|
}
|
|
196
206
|
|
|
197
207
|
onDestroy() {
|
|
198
208
|
this.context.application.removeEventListener(ApplicationEvents.Visible, this._focusCallback);
|
|
209
|
+
this.context.application.removeEventListener(ApplicationEvents.MuteChanged, this._muteChangedCallback);
|
|
199
210
|
}
|
|
200
211
|
|
|
201
212
|
|
|
@@ -233,7 +244,8 @@ export class AudioSource extends Behaviour {
|
|
|
233
244
|
|
|
234
245
|
sound.setBuffer(buffer);
|
|
235
246
|
sound.loop = this._loop;
|
|
236
|
-
sound.setVolume(
|
|
247
|
+
if(this.context.application.muted) sound.setVolume(0);
|
|
248
|
+
else sound.setVolume(this.volume);
|
|
237
249
|
sound.autoplay = this.shouldPlay;
|
|
238
250
|
// sound.setDistanceModel('linear');
|
|
239
251
|
// sound.setRolloffFactor(1);
|
|
@@ -313,7 +325,9 @@ export class AudioSource extends Behaviour {
|
|
|
313
325
|
if (debug)
|
|
314
326
|
console.log("play", this.sound?.getVolume(), this.sound);
|
|
315
327
|
if (this.sound && !this.sound.isPlaying) {
|
|
316
|
-
this.
|
|
328
|
+
const muted = this.context.application.muted;
|
|
329
|
+
if(muted) this.sound.setVolume(0);
|
|
330
|
+
this.sound.play(muted ? .1 : 0);
|
|
317
331
|
}
|
|
318
332
|
}
|
|
319
333
|
|
|
@@ -23,6 +23,9 @@ abstract class GameObject extends THREE.Object3D implements THREE.Object3D, IGam
|
|
|
23
23
|
|
|
24
24
|
guid: string | undefined;
|
|
25
25
|
|
|
26
|
+
// The actual implementation / prototype of threejs is modified in js-extensions/Object3D
|
|
27
|
+
abstract get transform(): THREE.Object3D;
|
|
28
|
+
|
|
26
29
|
public static isDestroyed(go: THREE.Object3D): boolean {
|
|
27
30
|
return isDestroyed(go);
|
|
28
31
|
}
|
|
@@ -6,7 +6,7 @@ import { Color, GridHelper as _GridHelper } from "three";
|
|
|
6
6
|
export class GridHelper extends Behaviour {
|
|
7
7
|
|
|
8
8
|
@serializable()
|
|
9
|
-
public isGizmo:boolean = false;
|
|
9
|
+
public isGizmo: boolean = false;
|
|
10
10
|
@serializable(Color)
|
|
11
11
|
private color0!: THREE.Color;
|
|
12
12
|
@serializable(Color)
|
|
@@ -23,10 +23,18 @@ export class GridHelper extends Behaviour {
|
|
|
23
23
|
const size = this.size;
|
|
24
24
|
const divisions = this.divisions;
|
|
25
25
|
if (!this.gridHelper) {
|
|
26
|
-
this.gridHelper = new _GridHelper(size, divisions, this.color0 ?? new Color(.4, .4, .4), this.color1 ?? new Color(.6
|
|
26
|
+
this.gridHelper = new _GridHelper(size, divisions, this.color0 ?? new Color(.4, .4, .4), this.color1 ?? new Color(.6, .6, .6));
|
|
27
27
|
if (this.offset !== undefined)
|
|
28
28
|
this.gridHelper.position.y += this.offset;
|
|
29
|
+
}
|
|
30
|
+
if (this.gridHelper)
|
|
29
31
|
this.gameObject.add(this.gridHelper);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
onDisable(): void {
|
|
35
|
+
if (this.gridHelper) {
|
|
36
|
+
this.gameObject.remove(this.gridHelper);
|
|
37
|
+
this.gridHelper = null;
|
|
30
38
|
}
|
|
31
39
|
}
|
|
32
40
|
}
|
|
@@ -70,7 +70,7 @@ export class ParticleSystemRenderer extends Behaviour {
|
|
|
70
70
|
|
|
71
71
|
getMaterial(trailEnabled: boolean = false) {
|
|
72
72
|
const material = (trailEnabled === true && this.trailMaterial) ? this.trailMaterial : this.particleMaterial;
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
// progressive load on start
|
|
75
75
|
// TODO: figure out how to do this before particle system rendering so we only load textures for visible materials
|
|
76
76
|
if (material && !suppressProgressiveLoading && material["_didRequestTextureLOD"] === undefined) {
|
|
@@ -836,7 +836,20 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
836
836
|
onBeforeRender() {
|
|
837
837
|
this.onUpdate();
|
|
838
838
|
const dt = this.deltaTime;
|
|
839
|
-
|
|
839
|
+
|
|
840
|
+
if (this._batchSystem) {
|
|
841
|
+
// Updating layers on batches
|
|
842
|
+
// TODO: figure out a better way to do this
|
|
843
|
+
// Issue: https://github.com/Alchemist0823/three.quarks/issues/49
|
|
844
|
+
if (this.context.time.frameCount % 60 === 0) {
|
|
845
|
+
for (let i = 0; i < this._batchSystem.batches.length; i++) {
|
|
846
|
+
const batch = this._batchSystem.batches[i];
|
|
847
|
+
batch.layers.disableAll();
|
|
848
|
+
batch.layers.set(2);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
this._batchSystem.update(dt);
|
|
852
|
+
}
|
|
840
853
|
this._time += dt;
|
|
841
854
|
if (this._time > this.duration) this._time = 0;
|
|
842
855
|
}
|
|
@@ -5,7 +5,7 @@ import { RendererLightmap } from "./RendererLightmap";
|
|
|
5
5
|
import { Context, FrameEvent } from "../engine/engine_setup";
|
|
6
6
|
import { getParam } from "../engine/engine_utils";
|
|
7
7
|
import { serializable } from "../engine/engine_serialization_decorator";
|
|
8
|
-
import { AxesHelper, Material, Mesh, Object3D, SkinnedMesh, Texture, Vector4 } from "three";
|
|
8
|
+
import { AxesHelper, Material, Matrix4, Mesh, Object3D, SkinnedMesh, Texture, Vector4 } from "three";
|
|
9
9
|
import { NEEDLE_render_objects } from "../engine/extensions/NEEDLE_render_objects";
|
|
10
10
|
import { NEEDLE_progressive } from "../engine/extensions/NEEDLE_progressive";
|
|
11
11
|
import { NEED_UPDATE_INSTANCE_KEY } from "../engine/engine_instancing";
|
|
@@ -18,6 +18,7 @@ import { showBalloonWarning } from "../engine/debug/debug";
|
|
|
18
18
|
// for staying compatible with old code
|
|
19
19
|
export { InstancingUtil } from "../engine/engine_instancing";
|
|
20
20
|
|
|
21
|
+
const debugRenderer = getParam("debugrenderer");
|
|
21
22
|
const suppressInstancing = getParam("noInstancing");
|
|
22
23
|
const debugLightmap = getParam("debuglightmaps") ? true : false;
|
|
23
24
|
const debugInstancing = getParam("debuginstancing");
|
|
@@ -294,6 +295,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
294
295
|
}
|
|
295
296
|
|
|
296
297
|
awake() {
|
|
298
|
+
if (debugRenderer) console.log("Renderer ", this.name, this);
|
|
297
299
|
this.clearInstancingState();
|
|
298
300
|
|
|
299
301
|
if (this.probeAnchor && debug) this.probeAnchor.add(new AxesHelper(.2));
|
|
@@ -332,6 +334,9 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
332
334
|
if (this.renderOrder !== undefined && this.renderOrder.length > 0)
|
|
333
335
|
this.gameObject.renderOrder = this.renderOrder[0];
|
|
334
336
|
}
|
|
337
|
+
else {
|
|
338
|
+
this.context.addBeforeRenderListener(this.gameObject, this.onBeforeRenderThree.bind(this));
|
|
339
|
+
}
|
|
335
340
|
|
|
336
341
|
if (this.lightmapIndex >= 0) {
|
|
337
342
|
// use the override lightmap if its not undefined
|
|
@@ -394,20 +399,14 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
394
399
|
this.handles = undefined;
|
|
395
400
|
this.prevLayers = undefined;
|
|
396
401
|
}
|
|
402
|
+
|
|
397
403
|
setInstancingEnabled(enabled: boolean): boolean {
|
|
398
404
|
if (this._isInstancingEnabled === enabled) return enabled && (this.handles === undefined || this.handles != null && this.handles.length > 0);
|
|
399
405
|
this._isInstancingEnabled = enabled;
|
|
400
406
|
if (enabled) {
|
|
401
|
-
// if handles is undefined we
|
|
402
407
|
if (this.handles === undefined) {
|
|
403
|
-
this.handles = instancing.setup(this.gameObject, this.context, null, { rend: this, foundMeshes: 0 });
|
|
408
|
+
this.handles = instancing.setup(this, this.gameObject, this.context, null, { rend: this, foundMeshes: 0, useMatrixWorldAutoUpdate: this.useInstanceMatrixWorldAutoUpdate() });
|
|
404
409
|
if (this.handles) {
|
|
405
|
-
// const disableSelf = this.gameObject.type === "Mesh" || this.gameObject.children?.length === this.handles.length;
|
|
406
|
-
// this.gameObject.visible = !disableSelf;
|
|
407
|
-
// this.gameObject.type = "Object3D";
|
|
408
|
-
// this.gameObject.material = null;
|
|
409
|
-
// console.log("Using instancing", this.gameObject.visible);
|
|
410
|
-
// this.gameObject.onBeforeRender = () => console.log("SHOULD NOT BE CALLED");
|
|
411
410
|
GameObject.markAsInstancedRendered(this.gameObject, true);
|
|
412
411
|
return true;
|
|
413
412
|
}
|
|
@@ -417,8 +416,6 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
417
416
|
handler.updateInstanceMatrix(true);
|
|
418
417
|
handler.add();
|
|
419
418
|
}
|
|
420
|
-
// this.gameObject.type = "Object3D";
|
|
421
|
-
// this.gameObject.visible = false;
|
|
422
419
|
GameObject.markAsInstancedRendered(this.gameObject, true);
|
|
423
420
|
return true;
|
|
424
421
|
}
|
|
@@ -429,13 +426,19 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
429
426
|
handler.remove();
|
|
430
427
|
}
|
|
431
428
|
}
|
|
432
|
-
// this.gameObject.visible = true;
|
|
433
429
|
return true;
|
|
434
430
|
}
|
|
435
431
|
|
|
436
432
|
return false;
|
|
437
433
|
}
|
|
438
434
|
|
|
435
|
+
/** Return true to wrap matrix update events for instanced rendering to update instance matrices automatically when matrixWorld changes
|
|
436
|
+
* This is a separate method to be overrideable from user code
|
|
437
|
+
*/
|
|
438
|
+
useInstanceMatrixWorldAutoUpdate() {
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
|
|
439
442
|
start() {
|
|
440
443
|
if (this.enableInstancing && !suppressInstancing) {
|
|
441
444
|
this.setInstancingEnabled(true);
|
|
@@ -461,6 +464,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
461
464
|
}
|
|
462
465
|
|
|
463
466
|
this.updateReflectionProbe();
|
|
467
|
+
|
|
464
468
|
}
|
|
465
469
|
|
|
466
470
|
onDisable() {
|
|
@@ -479,17 +483,12 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
479
483
|
NEEDLE_render_objects.applyStencil(this);
|
|
480
484
|
}
|
|
481
485
|
|
|
482
|
-
static envmap: THREE.Texture | null = null;
|
|
483
486
|
|
|
484
487
|
onBeforeRender() {
|
|
485
488
|
if (!this.gameObject) {
|
|
486
489
|
return;
|
|
487
490
|
}
|
|
488
491
|
|
|
489
|
-
Renderer.envmap = this.scene.environment;
|
|
490
|
-
|
|
491
|
-
const needsUpdate: boolean = this.gameObject[NEED_UPDATE_INSTANCE_KEY] === true || this.gameObject.matrixWorldNeedsUpdate;
|
|
492
|
-
|
|
493
492
|
if (this.isMultiMaterialObject(this.gameObject) && this.gameObject.children?.length > 0) {
|
|
494
493
|
for (const ch of this.gameObject.children) {
|
|
495
494
|
this.applySettings(ch);
|
|
@@ -499,9 +498,14 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
499
498
|
this.applySettings(this.gameObject);
|
|
500
499
|
}
|
|
501
500
|
|
|
502
|
-
if (
|
|
503
|
-
|
|
504
|
-
|
|
501
|
+
if (this.handles?.length) {
|
|
502
|
+
// if (this.name === "Darbouka")
|
|
503
|
+
// console.log(this.name, this.gameObject.matrixWorldNeedsUpdate);
|
|
504
|
+
const needsUpdate: boolean = this.gameObject[NEED_UPDATE_INSTANCE_KEY] === true;// || this.gameObject.matrixWorldNeedsUpdate;
|
|
505
|
+
if (needsUpdate) {
|
|
506
|
+
if(debugInstancing)
|
|
507
|
+
console.log("UPDATE INSTANCED MATRICES", this.context.time.frame);
|
|
508
|
+
this.gameObject[NEED_UPDATE_INSTANCE_KEY] = false;
|
|
505
509
|
const remove = false;// Math.random() < .01;
|
|
506
510
|
for (let i = this.handles.length - 1; i >= 0; i--) {
|
|
507
511
|
const h = this.handles[i];
|
|
@@ -539,14 +543,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
539
543
|
|
|
540
544
|
onBeforeRenderThree(_renderer, _scene, _camera, _geometry, material, _group) {
|
|
541
545
|
|
|
542
|
-
|
|
543
|
-
if (!suppressProgressiveLoading && material._didRequestTextureLOD === undefined && this.allowProgressiveLoading) {
|
|
544
|
-
material._didRequestTextureLOD = 0;
|
|
545
|
-
if (debugProgressiveLoading) {
|
|
546
|
-
console.log("Load material LOD", material.name);
|
|
547
|
-
}
|
|
548
|
-
NEEDLE_progressive.assignTextureLOD(this.context, this.sourceId, material);
|
|
549
|
-
}
|
|
546
|
+
this.loadProgressiveTextures(material);
|
|
550
547
|
|
|
551
548
|
if (material.envMapIntensity !== undefined) {
|
|
552
549
|
const factor = this.hasLightmap ? Math.PI : 1;
|
|
@@ -607,6 +604,22 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
607
604
|
}
|
|
608
605
|
}
|
|
609
606
|
|
|
607
|
+
loadProgressiveTextures(material: THREE.Material) {
|
|
608
|
+
// progressive load before rendering so we only load textures for visible materials
|
|
609
|
+
if (!suppressProgressiveLoading && material) {
|
|
610
|
+
if (debugProgressiveLoading && material["_didRequestTextureLOD"] === undefined)
|
|
611
|
+
console.warn("Progressive?", this)
|
|
612
|
+
|
|
613
|
+
if (material["_didRequestTextureLOD"] === undefined && this.allowProgressiveLoading) {
|
|
614
|
+
material["_didRequestTextureLOD"] = 0;
|
|
615
|
+
if (debugProgressiveLoading) {
|
|
616
|
+
console.log("Load material LOD", material.name);
|
|
617
|
+
}
|
|
618
|
+
NEEDLE_progressive.assignTextureLOD(this.context, this.sourceId, material);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
610
623
|
private applySettings(go: THREE.Object3D) {
|
|
611
624
|
go.receiveShadow = this.receiveShadows;
|
|
612
625
|
if (this.shadowCastingMode == ShadowCastingMode.On) {
|
|
@@ -689,17 +702,22 @@ export enum ShadowCastingMode {
|
|
|
689
702
|
|
|
690
703
|
|
|
691
704
|
|
|
692
|
-
declare class InstancingSetupArgs {
|
|
705
|
+
declare class InstancingSetupArgs {
|
|
706
|
+
rend: Renderer;
|
|
707
|
+
foundMeshes: number;
|
|
708
|
+
useMatrixWorldAutoUpdate: boolean;
|
|
709
|
+
};
|
|
693
710
|
|
|
694
711
|
class InstancingHandler {
|
|
695
712
|
|
|
696
713
|
public objs: InstancedMeshRenderer[] = [];
|
|
697
714
|
|
|
698
|
-
public setup(obj: THREE.Object3D, context: Context, handlesArray: InstanceHandle[] | null, args: InstancingSetupArgs, level: number = 0)
|
|
715
|
+
public setup(renderer:Renderer, obj: THREE.Object3D, context: Context, handlesArray: InstanceHandle[] | null, args: InstancingSetupArgs, level: number = 0)
|
|
699
716
|
: InstanceHandle[] | null {
|
|
700
717
|
|
|
701
718
|
const res = this.tryCreateOrAddInstance(obj, context, args);
|
|
702
719
|
if (res) {
|
|
720
|
+
renderer.loadProgressiveTextures(res.instancer.material);
|
|
703
721
|
if (handlesArray === null) handlesArray = [];
|
|
704
722
|
handlesArray.push(res);
|
|
705
723
|
return handlesArray;
|
|
@@ -708,7 +726,7 @@ class InstancingHandler {
|
|
|
708
726
|
if (level <= 0 && obj.type !== "Mesh") {
|
|
709
727
|
const nextLevel = level + 1;
|
|
710
728
|
for (const ch of obj.children) {
|
|
711
|
-
handlesArray = this.setup(ch, context, handlesArray, args, nextLevel);
|
|
729
|
+
handlesArray = this.setup(renderer, ch, context, handlesArray, args, nextLevel);
|
|
712
730
|
}
|
|
713
731
|
}
|
|
714
732
|
return handlesArray;
|
|
@@ -736,16 +754,52 @@ class InstancingHandler {
|
|
|
736
754
|
for (const i of this.objs) {
|
|
737
755
|
if (i.isFull()) continue;
|
|
738
756
|
if (i.geo === geo && i.material === mat) {
|
|
739
|
-
|
|
757
|
+
const handle = i.addInstance(mesh);
|
|
758
|
+
if (args.useMatrixWorldAutoUpdate && handle)
|
|
759
|
+
this.autoUpdateInstanceMatrix(mesh, i, handle);
|
|
760
|
+
return handle;
|
|
740
761
|
}
|
|
741
762
|
}
|
|
742
763
|
// console.log("Add new instance mesh renderer", obj);
|
|
743
764
|
const i = new InstancedMeshRenderer(obj.name, geo, mat, 200, context);
|
|
744
765
|
this.objs.push(i);
|
|
745
|
-
|
|
766
|
+
const handle = i.addInstance(mesh);
|
|
767
|
+
if (args.useMatrixWorldAutoUpdate && handle)
|
|
768
|
+
this.autoUpdateInstanceMatrix(mesh, i, handle);
|
|
769
|
+
return handle;
|
|
746
770
|
}
|
|
747
771
|
return null;
|
|
748
772
|
}
|
|
773
|
+
|
|
774
|
+
private autoUpdateInstanceMatrix(obj: Object3D, _renderer: InstancedMeshRenderer, _handle: InstanceHandle) {
|
|
775
|
+
const original = obj.matrixWorld["multiplyMatrices"].bind(obj.matrixWorld);
|
|
776
|
+
let previousMatrix: THREE.Matrix4 = obj.matrixWorld.clone();
|
|
777
|
+
|
|
778
|
+
const matrixChangeWrapper = (a: Matrix4, b: Matrix4) => {
|
|
779
|
+
const newMatrixWorld = original(a, b);
|
|
780
|
+
// console.warn("MULT", obj.matrixWorldNeedsUpdate);
|
|
781
|
+
if (obj[NEED_UPDATE_INSTANCE_KEY] || previousMatrix.equals(newMatrixWorld) === false) {
|
|
782
|
+
previousMatrix.copy(newMatrixWorld)
|
|
783
|
+
// handle.setMatrix(newMatrixWorld);
|
|
784
|
+
obj[NEED_UPDATE_INSTANCE_KEY] = true;
|
|
785
|
+
}
|
|
786
|
+
return newMatrixWorld;
|
|
787
|
+
};
|
|
788
|
+
obj.matrixWorld["multiplyMatrices"] = matrixChangeWrapper;
|
|
789
|
+
|
|
790
|
+
// wrap matrixWorldNeedsUpdate
|
|
791
|
+
// let originalMatrixWorldNeedsUpdate = obj.matrixWorldNeedsUpdate;
|
|
792
|
+
// Object.defineProperty(obj, "matrixWorldNeedsUpdate", {
|
|
793
|
+
// get: () => {
|
|
794
|
+
// return originalMatrixWorldNeedsUpdate;
|
|
795
|
+
// },
|
|
796
|
+
// set: (value: boolean) => {
|
|
797
|
+
// if(value) console.warn("SET MATRIX WORLD NEEDS UPDATE");
|
|
798
|
+
// originalMatrixWorldNeedsUpdate = value;
|
|
799
|
+
// }
|
|
800
|
+
// });
|
|
801
|
+
|
|
802
|
+
}
|
|
749
803
|
}
|
|
750
804
|
const instancing: InstancingHandler = new InstancingHandler();
|
|
751
805
|
|
|
@@ -773,6 +827,11 @@ class InstanceHandle {
|
|
|
773
827
|
this.instancer.updateInstance(this.object.matrixWorld, this.instanceIndex);
|
|
774
828
|
}
|
|
775
829
|
|
|
830
|
+
setMatrix(matrix: THREE.Matrix4) {
|
|
831
|
+
if (this.instanceIndex < 0) return;
|
|
832
|
+
this.instancer.updateInstance(matrix, this.instanceIndex);
|
|
833
|
+
}
|
|
834
|
+
|
|
776
835
|
add() {
|
|
777
836
|
if (this.instanceIndex >= 0) return;
|
|
778
837
|
this.instancer.add(this);
|
|
@@ -45,6 +45,7 @@ export class WebARSessionRoot extends Behaviour {
|
|
|
45
45
|
private _placementPose: Matrix4 | null = null;
|
|
46
46
|
private _isTouching: boolean = false;
|
|
47
47
|
private _rigStartPose: Matrix4 | undefined | null = null;
|
|
48
|
+
private _gotFirstHitTestResult: boolean = false;
|
|
48
49
|
|
|
49
50
|
onBegin(session: XRSession) {
|
|
50
51
|
this._placementPose = null;
|
|
@@ -52,6 +53,7 @@ export class WebARSessionRoot extends Behaviour {
|
|
|
52
53
|
this.gameObject.matrixAutoUpdate = false;
|
|
53
54
|
this._startPose = this.gameObject.matrix.clone();
|
|
54
55
|
this._rigStartPose = this.rig?.matrix.clone();
|
|
56
|
+
this._gotFirstHitTestResult = false;
|
|
55
57
|
session.addEventListener('selectstart', this._selectStartFn);
|
|
56
58
|
session.addEventListener('selectend', this._selectEndFn);
|
|
57
59
|
// setTimeout(() => this.gameObject.visible = false, 1000); // TODO test on phone AR and Hololens if this was still needed
|
|
@@ -66,12 +68,24 @@ export class WebARSessionRoot extends Behaviour {
|
|
|
66
68
|
this.rig.matrixAutoUpdate = true;
|
|
67
69
|
this._initalMatrix.decompose(this.rig.position, this.rig.quaternion, this.rig.scale);
|
|
68
70
|
}
|
|
71
|
+
|
|
72
|
+
// TODO this is duplicate to WebXR events AND engine events, would be better in one place
|
|
73
|
+
this.dispatchEvent(new CustomEvent('onBeginSession'));
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
onUpdate(rig: Object3D | null, _session: XRSession, pose: XRPose | null | undefined): boolean {
|
|
72
77
|
|
|
73
78
|
if (pose && !this._placementPose) {
|
|
79
|
+
|
|
80
|
+
if (!this._gotFirstHitTestResult) {
|
|
81
|
+
this._gotFirstHitTestResult = true;
|
|
82
|
+
this.dispatchEvent(new CustomEvent('canPlaceSession', { detail: { pose: pose } }));
|
|
83
|
+
}
|
|
84
|
+
|
|
74
85
|
if (this._isTouching) {
|
|
86
|
+
// callbacks
|
|
87
|
+
this.dispatchEvent(new CustomEvent('placedSession', { detail: { pose: pose } }));
|
|
88
|
+
|
|
75
89
|
if (this.webAR) this.webAR.setReticleActive(false);
|
|
76
90
|
this.placeAt(rig, new Matrix4().fromArray(pose.transform.matrix).invert());
|
|
77
91
|
return true;
|
|
@@ -12,12 +12,13 @@ export function apply(object: Object3D) {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// do we still need this?
|
|
18
15
|
Object3D.prototype["SetActive"] = function (active: boolean) {
|
|
19
16
|
this.visible = active;
|
|
20
17
|
}
|
|
18
|
+
// e.g. when called via a UnityEvent
|
|
19
|
+
Object3D.prototype["setActive"] = function (active: boolean) {
|
|
20
|
+
this.visible = active;
|
|
21
|
+
}
|
|
21
22
|
|
|
22
23
|
Object3D.prototype["addNewComponent"] = function <T extends Component>(type: ConstructorConcrete<T>) {
|
|
23
24
|
return addNewComponent(this, new type());
|
|
@@ -67,6 +68,13 @@ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "activeSelf")) {
|
|
|
67
68
|
});
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "transform")) {
|
|
72
|
+
Object.defineProperty(Object3D.prototype, "transform", {
|
|
73
|
+
get: function () {
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
70
78
|
|
|
71
79
|
|
|
72
80
|
|