Needle Engine

Changes between version 3.41.0-alpha.2 and 3.41.0-alpha.3
Files changed (4) hide show
  1. src/engine-components/Animation.ts +2 -2
  2. src/engine/engine_scenetools.ts +17 -8
  3. src/engine/engine_utils_format.ts +10 -6
  4. plugins/types/userconfig.d.ts +15 -15
src/engine-components/Animation.ts CHANGED
@@ -210,8 +210,8 @@
210
210
  return this.internalOnPlay(act, options);
211
211
  }
212
212
  }
213
- if (!(clip instanceof AnimationClip)) {
214
- console.warn("Clip is no AnimationClip", clip, "on object: " + this.name)
213
+ if (!clip.tracks) {
214
+ console.warn("Clip is no AnimationClip", clip)
215
215
  return;
216
216
  }
217
217
  const act = this.mixer.clipAction(clip);
src/engine/engine_scenetools.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
3
3
  import { type GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
4
4
  import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
5
+ import { USDZLoader } from 'three/examples/jsm/loaders/USDZLoader.js';
5
6
 
6
7
  import { showBalloonMessage } from "./debug/index.js";
7
8
  import { getLoader, type INeedleGltfLoader, registerLoader } from "./engine_gltf.js";
@@ -111,7 +112,7 @@
111
112
  return await tryDetermineFileTypeFromURL(url) || "unknown";
112
113
  }
113
114
 
114
- export async function createLoader(url: string, context: Context): Promise<GLTFLoader | FBXLoader | OBJLoader | null> {
115
+ export async function createLoader(url: string, context: Context): Promise<GLTFLoader | FBXLoader | USDZLoader | OBJLoader | null> {
115
116
 
116
117
  const type = await determineFileTypeFromURL(url);
117
118
 
@@ -123,10 +124,16 @@
123
124
  return new FBXLoader();
124
125
  case "obj":
125
126
  return new OBJLoader();
127
+ case "usd":
128
+ console.warn("USD files are not supported.")
129
+ return null;
130
+ break;
126
131
  case "usdz":
127
- console.warn("USDZ is not supported yet...");
132
+ console.warn("USDZ files are not supported.")
128
133
  return null;
134
+ // return new USDZLoader();
129
135
  default:
136
+ console.warn("Unknown file type:", type);
130
137
  case "gltf":
131
138
  case "glb":
132
139
  const loader = new GLTFLoader();
@@ -321,20 +328,22 @@
321
328
 
322
329
  function postprocessLoadedFile(loader: Loader, result: Object3D | GLTF) {
323
330
 
324
- if (result instanceof Object3D) {
325
-
331
+ if ((result as Object3D)?.isObject3D) {
332
+ const obj = result as Object3D;
333
+
326
334
  if (loader instanceof FBXLoader) {
327
- result.traverse(child => {
335
+ obj.traverse((child) => {
336
+ const mesh = child as Mesh;
328
337
 
329
338
  // See https://github.com/needle-tools/three.js/blob/b8df3843ff123ac9dc0ed0d3ccc5b568f840c804/examples/webgl_loader_multiple.html#L377
330
- if (child instanceof Mesh) {
331
- postprocessFBXMaterials(child, child.material as Material);
339
+ if (mesh?.isMesh) {
340
+ postprocessFBXMaterials(mesh, mesh.material as Material);
332
341
  }
333
342
  });
334
343
  }
335
344
  else if (loader instanceof OBJLoader) {
336
345
 
337
- result.traverse(_child => {
346
+ obj.traverse(_child => {
338
347
 
339
348
  // TODO: Needs testing
340
349
 
src/engine/engine_utils_format.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * The supported file types that can be determined by the engine. Used in {@link tryDetermineFileTypeFromURL} and {@link tryDetermineFileTypeFromBinary}
7
7
  */
8
- export declare type FileType = "gltf" | "glb" | "fbx" | "obj" | "usdz" | "unknown";
8
+ export declare type FileType = "gltf" | "glb" | "fbx" | "obj" | "usdz" | "usd" | "unknown";
9
9
 
10
10
  /**
11
11
  * Tries to determine the file type of a file from its URL
@@ -27,7 +27,7 @@
27
27
  if (header?.ok) {
28
28
  const data = await header.arrayBuffer();
29
29
  const res = tryDetermineFileTypeFromBinary(data);
30
- if (debug) console.log("Determined file type from header", res);
30
+ if (debug) console.log("Determined file type from header: " + res);
31
31
  return res;
32
32
  }
33
33
 
@@ -50,18 +50,22 @@
50
50
  console.warn("Trying to determine file type from binary data\n", "\"" + new TextDecoder().decode(data) + "\"\n", bytes);
51
51
  }
52
52
 
53
+ // GLTF or GLB
54
+ if (bytes[0] == 103 && bytes[1] == 108 && bytes[2] == 84 && bytes[3] == 70) {
55
+ return "glb";
56
+ }
53
57
  // USDZ
54
58
  if (bytes[0] == 80 && bytes[1] == 75 && bytes[2] == 3 && bytes[3] == 4) {
55
59
  return "usdz";
56
60
  }
61
+ // USD
62
+ if (bytes[0] == 80 && bytes[1] == 88 && bytes[2] == 82 && bytes[3] == 45 && bytes[4] == 85 && bytes[5] == 83 && bytes[6] == 68 && bytes[7] == 67) {
63
+ return "usd";
64
+ }
57
65
  // FBX
58
66
  if (bytes[0] == 75 && bytes[1] == 97 && bytes[2] == 121 && bytes[3] == 100 && bytes[4] == 97 && bytes[5] == 114 && bytes[6] == 97 && bytes[7] == 32) {
59
67
  return "fbx";
60
68
  }
61
- // GLTF or GLB
62
- else if (bytes[0] == 103 && bytes[1] == 108 && bytes[2] == 84 && bytes[3] == 70) {
63
- return "glb";
64
- }
65
69
  // OBJ - in this case exported from blender it starts with "# Blender" - we only check the first 10 bytes, technically it could still be a different file so we should do this check at the end
66
70
  else if (bytes[0] == 35 && bytes[1] == 32 && bytes[2] == 66 && bytes[3] == 108 && bytes[4] == 101 && bytes[5] == 110 && bytes[6] == 100 && bytes[7] == 101 && bytes[8] == 114 && bytes[9] == 32) {
67
71
  // const text = new TextDecoder().decode(data.slice(0, 9));
plugins/types/userconfig.d.ts CHANGED
@@ -8,30 +8,30 @@
8
8
  export type userSettings = {
9
9
 
10
10
  /** disable needle asap plugin */
11
- noAsap: boolean;
11
+ noAsap?: boolean;
12
12
 
13
13
  /** disable vite.alias modification */
14
- noAlias: boolean;
14
+ noAlias?: boolean;
15
15
  /** disable automatic copying of files to include and output directory (dist) */
16
- noCopy: boolean;
16
+ noCopy?: boolean;
17
17
  /** set to false to tree-shake rapier physics engine to the reduce bundle size */
18
- useRapier: boolean;
19
- noDependencyWatcher: boolean;
18
+ useRapier?: boolean;
19
+ noDependencyWatcher?: boolean;
20
20
  /** set to false to suppress editor-sync package installation and connection */
21
- dontInstallEditor: boolean;
21
+ dontInstallEditor?: boolean;
22
22
  /** set to false to prevent meta.html modifications (vite only) */
23
- allowMetaPlugin: boolean;
23
+ allowMetaPlugin?: boolean;
24
24
  /** set to true to prevent injecting peerjs `parcelRequire` global variable declaration */
25
- noPeer: boolean;
25
+ noPeer?: boolean;
26
26
  /** set to true to disable reload plugin */
27
- noReload: boolean;
27
+ noReload?: boolean;
28
28
  /** Set to false to disable hot reload for the needle plugin. */
29
- allowHotReload: boolean;
29
+ allowHotReload?: boolean;
30
30
 
31
- noCodegenTransform: boolean;
32
- noFacebookInstantGames: boolean;
31
+ noCodegenTransform?: boolean;
32
+ noFacebookInstantGames?: boolean;
33
33
  /** Set to true to create an imports.log file that shows all module imports. The file is generated when stopping the server. */
34
- logModuleImportChains: boolean;
34
+ logModuleImportChains?: boolean;
35
35
 
36
36
  /** Set to true to disable generating the buildinfo.json file in your output directory */
37
37
  noBuildInfo?: boolean;
@@ -45,7 +45,7 @@
45
45
  buildPipelineVersion?: string;
46
46
 
47
47
  /** required for @serializable https://github.com/vitejs/vite/issues/13736 */
48
- vite44Hack: boolean;
48
+ vite44Hack?: boolean;
49
49
 
50
50
  /** set to true to disable poster generation */
51
51
  noPoster?: boolean;
@@ -61,7 +61,7 @@
61
61
  pwa?: undefined;
62
62
 
63
63
  /** used by nextjs config to forward the webpack module */
64
- modules: needleModules;
64
+ modules?: needleModules;
65
65
 
66
66
  /**
67
67
  * Use to activate a needle engine license