Needle Engine

Changes between version 3.41.2-beta and 3.41.2-beta.1
Files changed (3) hide show
  1. src/engine/engine_scenetools.ts +2 -16
  2. src/engine/engine_utils_format.ts +39 -2
  3. src/engine/codegen/register_types.ts +2 -2
src/engine/engine_scenetools.ts CHANGED
@@ -97,24 +97,9 @@
97
97
  await getLoader().createBuiltinComponents(context, gltfId, gltf, seed, componentsExtension);
98
98
  }
99
99
 
100
- async function determineFileTypeFromURL(url: string): Promise<FileType> {
101
-
102
- const ext = url.split("?")[0].split(".").pop()?.toUpperCase() || "";
103
- switch (ext) {
104
- case "GLTF":
105
- return "gltf";
106
- case "GLB":
107
- return "glb";
108
- case "FBX":
109
- return "fbx";
110
- }
111
-
112
- return await tryDetermineFileTypeFromURL(url) || "unknown";
113
- }
114
-
115
100
  export async function createLoader(url: string, context: Context): Promise<GLTFLoader | FBXLoader | USDZLoader | OBJLoader | null> {
116
101
 
117
- const type = await determineFileTypeFromURL(url);
102
+ const type = await tryDetermineFileTypeFromURL(url) || "unknown";
118
103
 
119
104
  switch (type) {
120
105
  case "unknown":
@@ -134,6 +119,7 @@
134
119
  console.warn("Unknown file type:", type);
135
120
  case "gltf":
136
121
  case "glb":
122
+ case "vrm":
137
123
  const loader = new GLTFLoader();
138
124
  await registerExtensions(loader, context, url);
139
125
  return loader;
src/engine/engine_utils_format.ts CHANGED
@@ -5,14 +5,51 @@
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" | "usd" | "usda" | "unknown";
8
+ export declare type FileType = "gltf" | "glb" | "vrm" | "fbx" | "obj" | "usdz" | "usd" | "usda" | "unknown";
9
9
 
10
10
  /**
11
11
  * Tries to determine the file type of a file from its URL
12
12
  * This method does perform a range request to the server to get the first few bytes of the file
13
+ * If the file type can not be determined it will return "unknown"
14
+ * @param url The URL of the file
15
+ * @param lazy If true the file type will be determined by the file extension first - if the file extension is not known it will then check the header
16
+ * @example
17
+ * ```typescript
18
+ * const url = "https://example.com/model.glb";
19
+ * const fileType = await tryDetermineFileTypeFromURL(url);
20
+ * console.log(fileType); // "glb"
13
21
  */
14
- export async function tryDetermineFileTypeFromURL(url: string): Promise<FileType> {
22
+ export async function tryDetermineFileTypeFromURL(url: string, lazy: boolean = true): Promise<FileType> {
15
23
 
24
+ if (lazy) {
25
+ // We want to save on requests so we first check the file extension if there's any
26
+ // In some scenarios we might not have one (e.g. if we're dealing with blob: files or if the URL doesn't contain the filename)
27
+ // In that case we need to check the header
28
+ const urlobj = new URL(url);
29
+ let ext: string | null | undefined = null;
30
+ const query = urlobj.searchParams.get("filetype");
31
+ if (query) ext = query.toUpperCase();
32
+ if (!ext?.length) {
33
+ ext = urlobj.pathname.split(".").pop()?.toUpperCase();
34
+ }
35
+ switch (ext) {
36
+ case "GLTF":
37
+ return "gltf";
38
+ case "VRM":
39
+ return "vrm";
40
+ case "GLB":
41
+ return "glb";
42
+ case "FBX":
43
+ return "fbx";
44
+ case "USD":
45
+ return "usd";
46
+ case "USDA":
47
+ return "usda";
48
+ case "USDZ":
49
+ return "usdz";
50
+ }
51
+ }
52
+
16
53
  // If the URL doesnt contain a filetype we need to check the header
17
54
  // This is the case for example if we load a file from a data url
18
55
  const header = await fetch(url, {
src/engine/codegen/register_types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
  import { TypeStore } from "./../engine_typestore.js"
3
-
3
+
4
4
  // Import types
5
5
  import { __Ignore } from "../../engine-components/codegen/components.js";
6
6
  import { ActionBuilder } from "../../engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js";
@@ -220,7 +220,7 @@
220
220
  import { XRFlag } from "../../engine-components/webxr/XRFlag.js";
221
221
  import { XRRig } from "../../engine-components/webxr/WebXRRig.js";
222
222
  import { XRState } from "../../engine-components/webxr/XRFlag.js";
223
-
223
+
224
224
  // Register types
225
225
  TypeStore.add("__Ignore", __Ignore);
226
226
  TypeStore.add("ActionBuilder", ActionBuilder);