@needle-tools/engine 4.5.0-alpha.1 → 4.5.0-alpha.3
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 +15 -1
- package/dist/{needle-engine.bundle-3d05185b.js → needle-engine.bundle-1b8f44f4.js} +4945 -4907
- package/dist/{needle-engine.bundle-b2e17f0e.light.min.js → needle-engine.bundle-56f095f1.light.min.js} +125 -119
- package/dist/{needle-engine.bundle-d7d53476.light.umd.cjs → needle-engine.bundle-9fe9a394.light.umd.cjs} +137 -131
- package/dist/{needle-engine.bundle-e4ae93a2.min.js → needle-engine.bundle-baacde19.min.js} +125 -119
- package/dist/{needle-engine.bundle-c44e02c7.light.js → needle-engine.bundle-d710d96f.light.js} +4947 -4909
- package/dist/{needle-engine.bundle-f496c70e.umd.cjs → needle-engine.bundle-ef2b8438.umd.cjs} +135 -129
- package/dist/needle-engine.js +467 -471
- package/dist/needle-engine.light.js +467 -471
- package/dist/needle-engine.light.min.js +1 -1
- package/dist/needle-engine.light.umd.cjs +1 -1
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/api.d.ts +2 -1
- package/lib/engine/api.js +2 -1
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_context_registry.d.ts +2 -2
- package/lib/engine/engine_context_registry.js +2 -2
- package/lib/engine/engine_context_registry.js.map +1 -1
- package/lib/engine/engine_gltf.d.ts +2 -2
- package/lib/engine/engine_gltf_builtin_components.d.ts +5 -1
- package/lib/engine/engine_gltf_builtin_components.js +2 -2
- package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
- package/lib/engine/engine_loaders.callbacks.d.ts +62 -0
- package/lib/engine/engine_loaders.callbacks.js +56 -0
- package/lib/engine/engine_loaders.callbacks.js.map +1 -0
- package/lib/engine/engine_loaders.d.ts +44 -9
- package/lib/engine/engine_loaders.gltf.d.ts +13 -0
- package/lib/engine/engine_loaders.gltf.js +63 -0
- package/lib/engine/engine_loaders.gltf.js.map +1 -0
- package/lib/engine/engine_loaders.js +305 -48
- package/lib/engine/engine_loaders.js.map +1 -1
- package/lib/engine/engine_types.d.ts +7 -1
- package/lib/engine/engine_types.js +7 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_utils_format.d.ts +5 -3
- package/lib/engine/engine_utils_format.js +26 -10
- package/lib/engine/engine_utils_format.js.map +1 -1
- package/lib/engine/extensions/extensions.d.ts +3 -2
- package/lib/engine/extensions/extensions.js +10 -6
- package/lib/engine/extensions/extensions.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.attributes.d.ts +3 -6
- package/lib/engine/webcomponents/needle-engine.js +2 -2
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.loading.js +26 -34
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
- package/lib/engine-components/AvatarLoader.js +1 -1
- package/lib/engine-components/AvatarLoader.js.map +1 -1
- package/lib/engine-components/ContactShadows.d.ts +12 -0
- package/lib/engine-components/ContactShadows.js +23 -0
- package/lib/engine-components/ContactShadows.js.map +1 -1
- package/lib/engine-components/webxr/controllers/XRControllerModel.js +4 -3
- package/lib/engine-components/webxr/controllers/XRControllerModel.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/api.ts +2 -1
- package/src/engine/engine_context_registry.ts +2 -2
- package/src/engine/engine_gltf.ts +2 -2
- package/src/engine/engine_gltf_builtin_components.ts +7 -7
- package/src/engine/engine_loaders.callbacks.ts +88 -0
- package/src/engine/engine_loaders.gltf.ts +82 -0
- package/src/engine/engine_loaders.ts +332 -54
- package/src/engine/engine_types.ts +34 -18
- package/src/engine/engine_utils_format.ts +32 -14
- package/src/engine/extensions/extensions.ts +12 -7
- package/src/engine/webcomponents/needle-engine.attributes.ts +3 -6
- package/src/engine/webcomponents/needle-engine.loading.ts +28 -36
- package/src/engine/webcomponents/needle-engine.ts +2 -2
- package/src/engine-components/AvatarLoader.ts +1 -1
- package/src/engine-components/ContactShadows.ts +24 -0
- package/src/engine-components/webxr/controllers/XRControllerModel.ts +4 -5
- package/src/engine/engine_scenetools.ts +0 -379
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isDevEnvironment } from "./debug/index.js";
|
|
2
|
+
import { NeedleEngineModelLoader, registeredFileTypeCallbacks } from "./engine_loaders.callbacks.js";
|
|
2
3
|
import { getParam } from "./engine_utils.js";
|
|
3
4
|
|
|
4
5
|
const debug = getParam("debugfileformat");
|
|
@@ -6,7 +7,7 @@ const debug = getParam("debugfileformat");
|
|
|
6
7
|
/**
|
|
7
8
|
* The supported file types that can be determined by the engine. Used in {@link tryDetermineFileTypeFromURL} and {@link tryDetermineFileTypeFromBinary}
|
|
8
9
|
*/
|
|
9
|
-
export declare type FileType = "gltf" | "glb" | "vrm" | "fbx" | "obj" | "usdz" | "usd" | "usda" | "unknown";
|
|
10
|
+
export declare type FileType = "gltf" | "glb" | "vrm" | "fbx" | "obj" | "usdz" | "usd" | "usda" | "unknown" | ({} & string);
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Tries to determine the file type of a file from its URL
|
|
@@ -20,7 +21,9 @@ export declare type FileType = "gltf" | "glb" | "vrm" | "fbx" | "obj" | "usdz" |
|
|
|
20
21
|
* const fileType = await tryDetermineFileTypeFromURL(url);
|
|
21
22
|
* console.log(fileType); // "glb"
|
|
22
23
|
*/
|
|
23
|
-
export async function tryDetermineFileTypeFromURL(url: string, useExtension: boolean
|
|
24
|
+
export async function tryDetermineFileTypeFromURL(url: string, opts: { useExtension: boolean }): Promise<FileType> {
|
|
25
|
+
|
|
26
|
+
const { useExtension = true } = opts;
|
|
24
27
|
|
|
25
28
|
if (useExtension) {
|
|
26
29
|
// We want to save on requests so we first check the file extension if there's any
|
|
@@ -59,11 +62,12 @@ export async function tryDetermineFileTypeFromURL(url: string, useExtension: boo
|
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
|
|
65
|
+
|
|
63
66
|
// If the URL doesnt contain a filetype we need to check the header
|
|
64
67
|
// This is the case for example if we load a file from a data url
|
|
68
|
+
const originalUrl = url;
|
|
65
69
|
|
|
66
|
-
if(url.startsWith("blob:")) {
|
|
70
|
+
if (url.startsWith("blob:")) {
|
|
67
71
|
// We can't modify the blob URL
|
|
68
72
|
}
|
|
69
73
|
else {
|
|
@@ -84,7 +88,7 @@ export async function tryDetermineFileTypeFromURL(url: string, useExtension: boo
|
|
|
84
88
|
|
|
85
89
|
if (header?.ok) {
|
|
86
90
|
const data = await header.arrayBuffer();
|
|
87
|
-
const res = tryDetermineFileTypeFromBinary(data, header);
|
|
91
|
+
const res = tryDetermineFileTypeFromBinary(originalUrl, data, header);
|
|
88
92
|
if (debug) console.log("Determined file type from header: " + res);
|
|
89
93
|
return res;
|
|
90
94
|
}
|
|
@@ -96,7 +100,7 @@ export async function tryDetermineFileTypeFromURL(url: string, useExtension: boo
|
|
|
96
100
|
/** Attempts to determine the file type of a binary file by looking at the first few bytes of the file.
|
|
97
101
|
* @hidden
|
|
98
102
|
*/
|
|
99
|
-
export function tryDetermineFileTypeFromBinary(data: ArrayBuffer, response: Response): FileType {
|
|
103
|
+
export function tryDetermineFileTypeFromBinary(url: string, data: ArrayBuffer, response: Response): FileType {
|
|
100
104
|
|
|
101
105
|
if (data.byteLength < 4) {
|
|
102
106
|
return "unknown";
|
|
@@ -193,14 +197,6 @@ export function tryDetermineFileTypeFromBinary(data: ArrayBuffer, response: Resp
|
|
|
193
197
|
console.debug("OBJ detected (mtllib)");
|
|
194
198
|
return "obj";
|
|
195
199
|
}
|
|
196
|
-
|
|
197
|
-
if (isDevEnvironment() || debug) {
|
|
198
|
-
const text = new TextDecoder().decode(data.slice(0, 16));
|
|
199
|
-
console.debug("Could not determine file type from binary data: \"" + text + "...\"", bytes);
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
console.debug("Could not determine file type from binary data", bytes);
|
|
203
|
-
}
|
|
204
200
|
// const text = new TextDecoder().decode(data);
|
|
205
201
|
// if (text.startsWith("Kaydara FBX")) {
|
|
206
202
|
// return "fbx";
|
|
@@ -209,5 +205,27 @@ export function tryDetermineFileTypeFromBinary(data: ArrayBuffer, response: Resp
|
|
|
209
205
|
// return "gltf";
|
|
210
206
|
// }
|
|
211
207
|
|
|
208
|
+
for (const callback of registeredFileTypeCallbacks) {
|
|
209
|
+
const mimetype = callback({
|
|
210
|
+
url: url,
|
|
211
|
+
response: response,
|
|
212
|
+
contentType: response.headers.get("content-type"),
|
|
213
|
+
bytes: bytes
|
|
214
|
+
})
|
|
215
|
+
if (mimetype) {
|
|
216
|
+
if (debug) console.debug(`Mimetype callback returned: ${mimetype}`);
|
|
217
|
+
return mimetype;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
if (isDevEnvironment() || debug) {
|
|
223
|
+
const text = new TextDecoder().decode(data.slice(0, Math.min(data.byteLength, 32)));
|
|
224
|
+
console.warn(`Could not determine file type.\n\nConsider registering a custom loader via the 'onCreateCustomModelLoader' callback: 'NeedleEngineModelLoader.onCreateCustomModelLoader(args => { })'\n\nContent-Type: \"${response.headers.get("content-type")}\n\"Text: \"${text}\"\nBinary:`, bytes);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
console.debug(`Could not determine file type from binary data`);
|
|
228
|
+
}
|
|
229
|
+
|
|
212
230
|
return "unknown";
|
|
213
231
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Loader } from "three";
|
|
1
2
|
import { GLTFExporter } from "three/examples/jsm/exporters/GLTFExporter.js";
|
|
2
3
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
3
4
|
|
|
@@ -66,13 +67,17 @@ export function removeCustomImportExtensionType(ext: INeedleGLTFExtensionPlugin)
|
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
/** Registers the Needle Engine components extension */
|
|
69
|
-
export function registerComponentExtension(loader: GLTFLoader): NEEDLE_components {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
export function registerComponentExtension(loader: GLTFLoader | Loader | object): NEEDLE_components | null {
|
|
71
|
+
if (loader instanceof GLTFLoader) {
|
|
72
|
+
const ext = new NEEDLE_components();
|
|
73
|
+
loader.register(p => {
|
|
74
|
+
ext.parser = p;
|
|
75
|
+
return ext;
|
|
76
|
+
});
|
|
73
77
|
return ext;
|
|
74
|
-
}
|
|
75
|
-
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return null;
|
|
76
81
|
}
|
|
77
82
|
|
|
78
83
|
|
|
@@ -130,7 +135,7 @@ export function registerExportExtensions(exp: GLTFExporter, context: Context) {
|
|
|
130
135
|
}
|
|
131
136
|
|
|
132
137
|
/** @internal */
|
|
133
|
-
export function
|
|
138
|
+
export function invokeLoadedImportPluginHooks(url: string, gltf: GLTF, context: Context) {
|
|
134
139
|
for (const ext of _plugins)
|
|
135
140
|
if (ext.onLoaded) ext.onLoaded(url, gltf, context);
|
|
136
141
|
}
|
|
@@ -31,19 +31,16 @@ type MainAttributes = {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
type LoadingAttributes = {
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
/** Set a custom loading background color (e.g. "red" or "#dd00ff" or "rgba(18, 224, 224, 0.5)") */
|
|
35
|
+
"loading-background"?: string,
|
|
36
|
+
/** Pro features */
|
|
36
37
|
"hide-loading-overlay"?: boolean,
|
|
37
38
|
/** Pro feature */
|
|
38
|
-
"loading-background-color"?: string,
|
|
39
|
-
/** Pro feature */
|
|
40
39
|
"loading-logo-src"?: string,
|
|
41
40
|
/** Pro feature */
|
|
42
41
|
"primary-color"?: string,
|
|
43
42
|
/** Pro feature */
|
|
44
43
|
"secondary-color"?: string,
|
|
45
|
-
/** Pro feature */
|
|
46
|
-
"loading-text-color"?: string,
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
type SkyboxAttributes = {
|
|
@@ -197,10 +197,12 @@ export class EngineLoadingView implements ILoadingViewHandler {
|
|
|
197
197
|
this._loadingElement.style.height = "100%";
|
|
198
198
|
this._loadingElement.style.left = "0";
|
|
199
199
|
this._loadingElement.style.top = "0";
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
const loadingBackgroundColor = this._element.getAttribute("loading-background");
|
|
201
|
+
if (loadingBackgroundColor) {
|
|
202
|
+
this._loadingElement.style.background = loadingBackgroundColor;
|
|
203
|
+
}
|
|
202
204
|
else
|
|
203
|
-
this._loadingElement.style.backgroundColor = "
|
|
205
|
+
this._loadingElement.style.backgroundColor = "transparent";
|
|
204
206
|
this._loadingElement.style.display = "flex";
|
|
205
207
|
this._loadingElement.style.alignItems = "center";
|
|
206
208
|
this._loadingElement.style.justifyContent = "center";
|
|
@@ -214,16 +216,6 @@ export class EngineLoadingView implements ILoadingViewHandler {
|
|
|
214
216
|
this._loadingElement.style.color = "rgba(0,0,0,.6)";
|
|
215
217
|
else
|
|
216
218
|
this._loadingElement.style.color = "rgba(255,255,255,.3)";
|
|
217
|
-
if (hasLicense && this._element) {
|
|
218
|
-
const loadingBackgroundColor = this._element.getAttribute("loading-background-color");
|
|
219
|
-
if (loadingBackgroundColor) {
|
|
220
|
-
this._loadingElement.style.backgroundColor = loadingBackgroundColor;
|
|
221
|
-
}
|
|
222
|
-
const textColor = this._element.getAttribute("loading-text-color");
|
|
223
|
-
if (textColor) {
|
|
224
|
-
this._loadingElement.style.color = textColor;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
219
|
}
|
|
228
220
|
|
|
229
221
|
const className = this._loadingElementOptions?.className ?? EngineLoadingView.LoadingContainerClassName;
|
|
@@ -302,8 +294,8 @@ export class EngineLoadingView implements ILoadingViewHandler {
|
|
|
302
294
|
const getGradientPos = function (t: number): string {
|
|
303
295
|
return Mathf.lerp(0, maxWidth, t) + "%";
|
|
304
296
|
}
|
|
305
|
-
this._loadingBar.style.background =
|
|
306
|
-
`linear-gradient(90deg, #204f49 ${getGradientPos(0)}, #0BA398 ${getGradientPos(.3)}, #66A22F ${getGradientPos(.6)}, #D7DB0A ${getGradientPos(1)})`;
|
|
297
|
+
this._loadingBar.style.background = "#66A22F";
|
|
298
|
+
// `linear-gradient(90deg, #204f49 ${getGradientPos(0)}, #0BA398 ${getGradientPos(.3)}, #66A22F ${getGradientPos(.6)}, #D7DB0A ${getGradientPos(1)})`;
|
|
307
299
|
this._loadingBar.style.backgroundAttachment = "fixed";
|
|
308
300
|
this._loadingBar.style.width = "0%";
|
|
309
301
|
this._loadingBar.style.height = "100%";
|
|
@@ -321,27 +313,27 @@ export class EngineLoadingView implements ILoadingViewHandler {
|
|
|
321
313
|
}
|
|
322
314
|
}
|
|
323
315
|
|
|
324
|
-
this._loadingTextContainer = document.createElement("div");
|
|
325
|
-
this._loadingTextContainer.style.display = "flex";
|
|
326
|
-
this._loadingTextContainer.style.justifyContent = "center";
|
|
327
|
-
this._loadingTextContainer.style.marginTop = ".2rem";
|
|
328
|
-
details.appendChild(this._loadingTextContainer);
|
|
329
|
-
|
|
330
|
-
const messageContainer = document.createElement("div");
|
|
331
|
-
this._messageContainer = messageContainer;
|
|
332
|
-
messageContainer.style.display = "flex";
|
|
333
|
-
messageContainer.style.fontSize = ".8rem";
|
|
334
|
-
messageContainer.style.paddingTop = ".1rem";
|
|
335
|
-
// messageContainer.style.border = "1px solid rgba(255,255,255,.1)";
|
|
336
|
-
messageContainer.style.justifyContent = "center";
|
|
337
|
-
details.appendChild(messageContainer);
|
|
338
|
-
|
|
339
|
-
if (hasLicense && this._element) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
316
|
+
// this._loadingTextContainer = document.createElement("div");
|
|
317
|
+
// this._loadingTextContainer.style.display = "flex";
|
|
318
|
+
// this._loadingTextContainer.style.justifyContent = "center";
|
|
319
|
+
// this._loadingTextContainer.style.marginTop = ".2rem";
|
|
320
|
+
// details.appendChild(this._loadingTextContainer);
|
|
321
|
+
|
|
322
|
+
// const messageContainer = document.createElement("div");
|
|
323
|
+
// this._messageContainer = messageContainer;
|
|
324
|
+
// messageContainer.style.display = "flex";
|
|
325
|
+
// messageContainer.style.fontSize = ".8rem";
|
|
326
|
+
// messageContainer.style.paddingTop = ".1rem";
|
|
327
|
+
// // messageContainer.style.border = "1px solid rgba(255,255,255,.1)";
|
|
328
|
+
// messageContainer.style.justifyContent = "center";
|
|
329
|
+
// details.appendChild(messageContainer);
|
|
330
|
+
|
|
331
|
+
// if (hasLicense && this._element) {
|
|
332
|
+
// const loadingTextColor = this._element.getAttribute("loading-text-color");
|
|
333
|
+
// if (loadingTextColor) {
|
|
334
|
+
// messageContainer.style.color = loadingTextColor;
|
|
335
|
+
// }
|
|
336
|
+
// }
|
|
345
337
|
|
|
346
338
|
this.handleRuntimeLicense(this._loadingElement);
|
|
347
339
|
|
|
@@ -4,8 +4,8 @@ import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
|
|
|
4
4
|
import { PUBLIC_KEY, VERSION } from "../engine_constants.js";
|
|
5
5
|
import { registerLoader } from "../engine_gltf.js";
|
|
6
6
|
import { hasCommercialLicense } from "../engine_license.js";
|
|
7
|
-
import { setDracoDecoderPath, setDracoDecoderType, setKtx2TranscoderPath } from "../engine_loaders.js";
|
|
8
|
-
import { NeedleLoader } from "../
|
|
7
|
+
import { setDracoDecoderPath, setDracoDecoderType, setKtx2TranscoderPath } from "../engine_loaders.gltf.js";
|
|
8
|
+
import { NeedleLoader } from "../engine_loaders.js";
|
|
9
9
|
import { Context, ContextCreateArgs } from "../engine_setup.js";
|
|
10
10
|
import { type INeedleEngineComponent, type LoadedModel } from "../engine_types.js";
|
|
11
11
|
import { getParam } from "../engine_utils.js";
|
|
@@ -3,7 +3,7 @@ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
|
3
3
|
|
|
4
4
|
import { InstantiateOptions } from "../engine/engine_gameobject.js";
|
|
5
5
|
import { getLoader } from "../engine/engine_gltf.js";
|
|
6
|
-
import * as loaders from "../engine/engine_loaders.js"
|
|
6
|
+
import * as loaders from "../engine/engine_loaders.gltf.js"
|
|
7
7
|
import { Context } from "../engine/engine_setup.js";
|
|
8
8
|
import * as utils from "../engine/engine_utils.js"
|
|
9
9
|
import { GameObject } from "./Component.js";
|
|
@@ -110,6 +110,21 @@ export class ContactShadows extends Behaviour {
|
|
|
110
110
|
*/
|
|
111
111
|
minSize?: Partial<Vec3>;
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* When enabled the shadows will not be updated automatically. Use `needsUpdate()` to update the shadows manually.
|
|
115
|
+
* This is useful when you want to update the shadows only when the scene changes.
|
|
116
|
+
*/
|
|
117
|
+
manualUpdate: boolean = false;
|
|
118
|
+
/**
|
|
119
|
+
* Call this method to update the shadows manually. The update will be done in the next frame.
|
|
120
|
+
*/
|
|
121
|
+
set needsUpdate(val: boolean) {
|
|
122
|
+
this._needsUpdate = val;
|
|
123
|
+
}
|
|
124
|
+
get needsUpdate(): boolean {
|
|
125
|
+
return this._needsUpdate;
|
|
126
|
+
}
|
|
127
|
+
private _needsUpdate: boolean = false;
|
|
113
128
|
|
|
114
129
|
/** All shadow objects are parented to this object.
|
|
115
130
|
* The gameObject itself should not be transformed because we want the ContactShadows object e.g. also have a GroundProjectedEnv component
|
|
@@ -288,6 +303,10 @@ export class ContactShadows extends Behaviour {
|
|
|
288
303
|
else this.applyMinSize();
|
|
289
304
|
}
|
|
290
305
|
|
|
306
|
+
onEnable(): void {
|
|
307
|
+
this._needsUpdate = true;
|
|
308
|
+
}
|
|
309
|
+
|
|
291
310
|
/** @internal */
|
|
292
311
|
onDestroy(): void {
|
|
293
312
|
const instance = ContactShadows._instances.get(this.context);
|
|
@@ -313,6 +332,11 @@ export class ContactShadows extends Behaviour {
|
|
|
313
332
|
/** @internal */
|
|
314
333
|
onBeforeRender(_frame: XRFrame | null): void {
|
|
315
334
|
|
|
335
|
+
if (this.manualUpdate) {
|
|
336
|
+
if (!this._needsUpdate) return;
|
|
337
|
+
}
|
|
338
|
+
this._needsUpdate = false;
|
|
339
|
+
|
|
316
340
|
if (!this.renderTarget || !this.renderTargetBlur ||
|
|
317
341
|
!this.depthMaterial || !this.shadowCamera ||
|
|
318
342
|
!this.blurPlane || !this.shadowGroup || !this.plane ||
|
|
@@ -3,13 +3,11 @@ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
|
3
3
|
import { XRControllerModelFactory } from "three/examples/jsm/webxr/XRControllerModelFactory.js";
|
|
4
4
|
import { XRHandMeshModel } from "three/examples/jsm/webxr/XRHandMeshModel.js";
|
|
5
5
|
|
|
6
|
-
import { showBalloonWarning } from "../../../engine/debug/index.js";
|
|
7
6
|
import { AssetReference } from "../../../engine/engine_addressables.js";
|
|
8
7
|
import { setDontDestroy } from "../../../engine/engine_gameobject.js";
|
|
9
8
|
import { Gizmos } from "../../../engine/engine_gizmos.js";
|
|
10
9
|
import { getLoader } from "../../../engine/engine_gltf.js";
|
|
11
|
-
import {
|
|
12
|
-
import { addDracoAndKTX2Loaders } from "../../../engine/engine_loaders.js";
|
|
10
|
+
import { addDracoAndKTX2Loaders } from "../../../engine/engine_loaders.gltf.js";
|
|
13
11
|
import { serializable } from "../../../engine/engine_serialization_decorator.js";
|
|
14
12
|
import type { IGameObject, SourceIdentifier } from "../../../engine/engine_types.js";
|
|
15
13
|
import { getParam } from "../../../engine/engine_utils.js";
|
|
@@ -306,7 +304,7 @@ export class XRControllerModel extends Behaviour {
|
|
|
306
304
|
// @ts-ignore
|
|
307
305
|
const handmesh = new XRHandMeshModel(handObject, hand, loader.path, filename, loader, (object: Object3D) => {
|
|
308
306
|
|
|
309
|
-
const gltf = componentsExtension
|
|
307
|
+
const gltf = componentsExtension?.gltf;
|
|
310
308
|
// The XRHandMeshController removes the hand from the gltf before calling this callback
|
|
311
309
|
// we need this in the GLTF scene however for creating the builtin components
|
|
312
310
|
if (gltf?.scene.children?.length === 0) {
|
|
@@ -314,7 +312,8 @@ export class XRControllerModel extends Behaviour {
|
|
|
314
312
|
}
|
|
315
313
|
|
|
316
314
|
// console.log(controller.side, componentsExtension.gltf, object, componentsExtension.gltf.scene?.children)
|
|
317
|
-
|
|
315
|
+
if (componentsExtension?.gltf)
|
|
316
|
+
getLoader().createBuiltinComponents(comp.context, comp.sourceId || filename, componentsExtension.gltf, null, componentsExtension);
|
|
318
317
|
|
|
319
318
|
// The hand mesh should not receive raycasts
|
|
320
319
|
object.traverse(child => {
|