@@ -57,14 +57,34 @@
|
|
57
57
|
*/
|
58
58
|
@serializable()
|
59
59
|
autoFit: boolean = false;
|
60
|
+
/**
|
61
|
+
* Darkness of the shadows.
|
62
|
+
* @default 0.5
|
63
|
+
*/
|
60
64
|
@serializable()
|
61
65
|
darkness: number = 0.5;
|
66
|
+
/**
|
67
|
+
* Opacity of the shadows.
|
68
|
+
* @default 0.5
|
69
|
+
*/
|
62
70
|
@serializable()
|
63
71
|
opacity: number = 0.5;
|
72
|
+
/**
|
73
|
+
* Blur of the shadows.
|
74
|
+
* @default 4.0
|
75
|
+
*/
|
64
76
|
@serializable()
|
65
77
|
blur: number = 4.0;
|
78
|
+
/**
|
79
|
+
* When enabled objects will not be visible below the shadow plane
|
80
|
+
* @default false
|
81
|
+
*/
|
66
82
|
@serializable()
|
67
83
|
occludeBelowGround: boolean = false;
|
84
|
+
/**
|
85
|
+
* When enabled the backfaces of objects will cast shadows as well.
|
86
|
+
* @default true
|
87
|
+
*/
|
68
88
|
@serializable()
|
69
89
|
backfaceShadows: boolean = true;
|
70
90
|
|
@@ -11,6 +11,8 @@
|
|
11
11
|
ContextCreated = "ContextCreated",
|
12
12
|
/** Called after the first frame has been rendered after creation */
|
13
13
|
ContextFirstFrameRendered = "ContextFirstFrameRendered",
|
14
|
+
/** Called before the context gets destroyed */
|
15
|
+
ContextDestroying = "ContextDestroying",
|
14
16
|
/** Called when the context has been destroyed */
|
15
17
|
ContextDestroyed = "ContextDestroyed",
|
16
18
|
/** Called when the context could not find a camera during creation */
|
@@ -571,6 +571,7 @@
|
|
571
571
|
*/
|
572
572
|
clear() {
|
573
573
|
ContextRegistry.dispatchCallback(ContextEvent.ContextClearing, this);
|
574
|
+
invokeLifecycleFunctions(this, ContextEvent.ContextClearing);
|
574
575
|
// NOTE: this does dispose the environment/background image too
|
575
576
|
// which is probably not desired if it is set via the skybox-image attribute
|
576
577
|
destroy(this.scene, true, true);
|
@@ -598,6 +599,9 @@
|
|
598
599
|
/**@deprecated use dispose() */
|
599
600
|
onDestroy() { this.internalOnDestroy(); }
|
600
601
|
private internalOnDestroy() {
|
602
|
+
Context.Current = this;
|
603
|
+
ContextRegistry.dispatchCallback(ContextEvent.ContextDestroying, this);
|
604
|
+
invokeLifecycleFunctions(this, ContextEvent.ContextDestroying);
|
601
605
|
this.clear();
|
602
606
|
this.renderer?.setAnimationLoop(null);
|
603
607
|
if (this.renderer) {
|
@@ -625,6 +629,7 @@
|
|
625
629
|
}
|
626
630
|
this._isCreated = false;
|
627
631
|
ContextRegistry.dispatchCallback(ContextEvent.ContextDestroyed, this);
|
632
|
+
invokeLifecycleFunctions(this, ContextEvent.ContextDestroyed);
|
628
633
|
ContextRegistry.unregister(this);
|
629
634
|
if (Context.Current === this) {
|
630
635
|
//@ts-ignore
|
@@ -19,7 +19,24 @@
|
|
19
19
|
registerFrameEventCallback(cb, ContextEvent.ContextCreated);
|
20
20
|
return () => unregisterFrameEventCallback(cb, ContextEvent.ContextCreated);
|
21
21
|
}
|
22
|
+
/**
|
23
|
+
* Register a callback before the engine context is cleared.
|
24
|
+
* This happens if e.g. `<needle-engine src>` changes
|
25
|
+
*/
|
26
|
+
export function onClear(cb: LifecycleMethod): () => void {
|
27
|
+
registerFrameEventCallback(cb, ContextEvent.ContextClearing);
|
28
|
+
return () => unregisterFrameEventCallback(cb, ContextEvent.ContextClearing);
|
29
|
+
}
|
22
30
|
|
31
|
+
/**
|
32
|
+
* Register a callback in the engine before the context is destroyed
|
33
|
+
* This happens once per context (before the context is destroyed)
|
34
|
+
*/
|
35
|
+
export function onDestroy(cb: LifecycleMethod): () => void {
|
36
|
+
registerFrameEventCallback(cb, ContextEvent.ContextDestroying);
|
37
|
+
return () => unregisterFrameEventCallback(cb, ContextEvent.ContextDestroying);
|
38
|
+
}
|
39
|
+
|
23
40
|
/** Register a callback in the engine start event.
|
24
41
|
* This happens at the beginning of each frame
|
25
42
|
* @param cb The callback to be called
|
@@ -1,4 +1,5 @@
|
|
1
1
|
|
2
|
+
import { setDracoDecoderLocation, setKTX2TranscoderLocation } from '@needle-tools/gltf-progressive';
|
2
3
|
import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';
|
3
4
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
4
5
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
|
@@ -10,9 +11,9 @@
|
|
10
11
|
|
11
12
|
const debug = getParam("debugdecoders");
|
12
13
|
|
14
|
+
// NOTE: keep in sync with gltf-progressive
|
13
15
|
let DEFAULT_DRACO_DECODER_LOCATION = 'https://www.gstatic.com/draco/versioned/decoders/1.4.1/';
|
14
16
|
let DEFAULT_KTX2_TRANSCODER_LOCATION = 'https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/';
|
15
|
-
|
16
17
|
fetch(DEFAULT_DRACO_DECODER_LOCATION + "draco_decoder.js", { method: "head" })
|
17
18
|
.catch(_ => {
|
18
19
|
if (isDevEnvironment()) console.warn("Failed to load draco decoder from \"" + DEFAULT_DRACO_DECODER_LOCATION + "\".\nFalling back to local version at \"./include/draco\"");
|
@@ -20,6 +21,7 @@
|
|
20
21
|
DEFAULT_KTX2_TRANSCODER_LOCATION = "./include/ktx2/";
|
21
22
|
});
|
22
23
|
|
24
|
+
|
23
25
|
let dracoLoader: DRACOLoader;
|
24
26
|
let meshoptDecoder: typeof MeshoptDecoder;
|
25
27
|
let ktx2Loader: KTX2Loader;
|
@@ -30,6 +32,7 @@
|
|
30
32
|
dracoLoader = new DRACOLoader();
|
31
33
|
if (debug) console.log("Setting draco decoder path to", path);
|
32
34
|
dracoLoader.setDecoderPath(path);
|
35
|
+
setDracoDecoderLocation(path);
|
33
36
|
}
|
34
37
|
}
|
35
38
|
|
@@ -48,6 +51,7 @@
|
|
48
51
|
ktx2Loader = new KTX2Loader();
|
49
52
|
if (debug) console.log("Setting ktx2 transcoder path to", path);
|
50
53
|
ktx2Loader.setTranscoderPath(path);
|
54
|
+
setKTX2TranscoderLocation(path);
|
51
55
|
}
|
52
56
|
}
|
53
57
|
|
@@ -75,20 +75,30 @@
|
|
75
75
|
this.controls?.addEventListener("start", callback as any);
|
76
76
|
}
|
77
77
|
|
78
|
-
/** When enabled OrbitControls will automatically raycast find a look at target in start
|
78
|
+
/** When enabled OrbitControls will automatically raycast find a look at target in start
|
79
|
+
* @default true
|
80
|
+
*/
|
79
81
|
@serializable()
|
80
82
|
autoTarget: boolean = true;
|
81
|
-
/** When enabled the scene will be automatically fitted into the camera view in onEnable
|
83
|
+
/** When enabled the scene will be automatically fitted into the camera view in onEnable
|
84
|
+
* @default false
|
85
|
+
*/
|
82
86
|
@serializable()
|
83
87
|
autoFit: boolean = false;
|
84
88
|
|
85
|
-
/** When enabled the camera can be rotated
|
89
|
+
/** When enabled the camera can be rotated
|
90
|
+
* @default true
|
91
|
+
*/
|
86
92
|
@serializable()
|
87
93
|
enableRotate: boolean = true;
|
88
|
-
/** When enabled the camera will rotate automatically
|
94
|
+
/** When enabled the camera will rotate automatically
|
95
|
+
* @default false
|
96
|
+
*/
|
89
97
|
@serializable()
|
90
98
|
autoRotate: boolean = false;
|
91
|
-
/** The speed at which the camera will rotate automatically. Will only be used when `autoRotate` is enabled
|
99
|
+
/** The speed at which the camera will rotate automatically. Will only be used when `autoRotate` is enabled
|
100
|
+
* @default 1.0
|
101
|
+
*/
|
92
102
|
@serializable()
|
93
103
|
autoRotateSpeed: number = 1.0;
|
94
104
|
/** The minimum azimuth angle in radians */
|
@@ -97,30 +107,46 @@
|
|
97
107
|
/** The maximum azimuth angle in radians */
|
98
108
|
@serializable()
|
99
109
|
maxAzimuthAngle: number = Infinity;
|
100
|
-
/** The minimum polar angle in radians
|
110
|
+
/** The minimum polar angle in radians
|
111
|
+
* @default 0
|
112
|
+
*/
|
101
113
|
@serializable()
|
102
114
|
minPolarAngle: number = 0;
|
103
|
-
/** The maximum polar angle in radians
|
115
|
+
/** The maximum polar angle in radians
|
116
|
+
* @default Math.PI
|
117
|
+
*/
|
104
118
|
@serializable()
|
105
119
|
maxPolarAngle: number = Math.PI;
|
106
120
|
|
107
|
-
/** When enabled the camera can be moved using keyboard keys. The keys are defined in the `controls.keys` property
|
121
|
+
/** When enabled the camera can be moved using keyboard keys. The keys are defined in the `controls.keys` property
|
122
|
+
* @default true
|
123
|
+
*/
|
108
124
|
@serializable()
|
109
125
|
enableKeys: boolean = true;
|
110
|
-
/** When enabled the camera movement will be damped
|
126
|
+
/** When enabled the camera movement will be damped
|
127
|
+
* @default true
|
128
|
+
*/
|
111
129
|
@serializable()
|
112
130
|
enableDamping: boolean = true;
|
113
|
-
/** The damping factor for the camera movement. For more information see the [three.js documentation](https://threejs.org/docs/#examples/en/controls/OrbitControls.dampingFactor)
|
131
|
+
/** The damping factor for the camera movement. For more information see the [three.js documentation](https://threejs.org/docs/#examples/en/controls/OrbitControls.dampingFactor)
|
132
|
+
* @default 0.1
|
133
|
+
*/
|
114
134
|
@serializable()
|
115
135
|
dampingFactor: number = 0.1;
|
116
136
|
|
117
|
-
/** When enabled the camera can be zoomed
|
137
|
+
/** When enabled the camera can be zoomed
|
138
|
+
* @default true
|
139
|
+
*/
|
118
140
|
@serializable()
|
119
141
|
enableZoom: boolean = true;
|
120
|
-
/** The minimum zoom level
|
142
|
+
/** The minimum zoom level
|
143
|
+
* @default 0
|
144
|
+
*/
|
121
145
|
@serializable()
|
122
146
|
minZoom: number = 0;
|
123
|
-
/** The maximum zoom level
|
147
|
+
/** The maximum zoom level
|
148
|
+
* @default Infinity
|
149
|
+
*/
|
124
150
|
@serializable()
|
125
151
|
maxZoom: number = Infinity;
|
126
152
|
|
@@ -128,28 +154,21 @@
|
|
128
154
|
* Sets the zoom speed of the OrbitControls
|
129
155
|
* @default 1
|
130
156
|
*/
|
131
|
-
|
132
|
-
|
133
|
-
}
|
134
|
-
get zoomSpeed() {
|
135
|
-
return this._controls?.zoomSpeed ?? 0;
|
136
|
-
}
|
157
|
+
@serializable()
|
158
|
+
zoomSpeed: number = 1;
|
137
159
|
|
138
160
|
/**
|
139
161
|
* Set to true to enable zooming to the cursor position.
|
140
162
|
* @default false
|
141
163
|
*/
|
142
|
-
|
143
|
-
if (this._controls) this._controls.zoomToCursor = value;
|
144
|
-
}
|
145
|
-
get zoomToCursor() {
|
146
|
-
return this._controls?.zoomToCursor ?? false;
|
147
|
-
}
|
164
|
+
zoomToCursor: boolean = false;
|
148
165
|
|
149
|
-
/** When enabled the camera can be panned
|
166
|
+
/** When enabled the camera can be panned
|
167
|
+
* @default true
|
168
|
+
*/
|
150
169
|
@serializable()
|
151
170
|
enablePan: boolean = true;
|
152
|
-
/** Assigning a LookAtConstraint will make the camera look at the constraint source */
|
171
|
+
/** Assigning a {@link LookAtConstraint} will make the camera look at the constraint source */
|
153
172
|
@serializable(LookAtConstraint)
|
154
173
|
lookAtConstraint: LookAtConstraint | null = null;
|
155
174
|
/** The weight of the first lookAtConstraint source */
|
@@ -402,6 +421,8 @@
|
|
402
421
|
this._controls.autoRotate = this.autoRotate;
|
403
422
|
this._controls.autoRotateSpeed = this.autoRotateSpeed;
|
404
423
|
this._controls.enableZoom = this.enableZoom;
|
424
|
+
this._controls.zoomSpeed = this.zoomSpeed;
|
425
|
+
this._controls.zoomToCursor = this.zoomToCursor;
|
405
426
|
this._controls.enableDamping = this.enableDamping;
|
406
427
|
this._controls.dampingFactor = this.dampingFactor;
|
407
428
|
this._controls.enablePan = this.enablePan;
|