@needle-tools/usd 0.0.2-next.de2e82b → 1.0.0-next.4d692f6

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/README.md +245 -28
  3. package/package.json +46 -10
  4. package/src/bindings/emHdBindings.js +5 -12227
  5. package/src/bindings/emHdBindings.wasm +0 -0
  6. package/src/bindings/index.js +130 -47
  7. package/src/bindings/openusd-build-info.json +40 -0
  8. package/src/create.three.js +368 -53
  9. package/src/hydra/ThreeJsRenderDelegate.js +1128 -75
  10. package/src/plugins/index.js +1 -2
  11. package/src/plugins/needle.js +38 -2
  12. package/src/types/bindings.d.ts +296 -3
  13. package/src/types/create.three.d.ts +87 -7
  14. package/src/types/hydra.d.ts +7 -5
  15. package/src/types/plugins.d.ts +7 -0
  16. package/src/types/usd-core-bindings.d.ts +240 -0
  17. package/src/utils.js +3 -3
  18. package/src/vite/index.js +13 -1
  19. package/examples/index.html +0 -58
  20. package/examples/package-lock.json +0 -1548
  21. package/examples/package.json +0 -24
  22. package/examples/public/HttpReferences copy.usda +0 -46
  23. package/examples/public/HttpReferences.usda +0 -44
  24. package/examples/public/gingerbread/GingerbreadHouse.usda +0 -35
  25. package/examples/public/gingerbread/house/GingerBreadHouse.usdc +0 -0
  26. package/examples/public/gingerbread/house/textures/color.jpg +0 -0
  27. package/examples/public/gingerbread/house/textures/metallic_roughness.jpg +0 -0
  28. package/examples/public/gingerbread/house/textures/normal.jpg +0 -0
  29. package/examples/public/gingerbread/snowman/Snowman.usdc +0 -0
  30. package/examples/public/gingerbread/snowman/textures/color.jpg +0 -0
  31. package/examples/public/gingerbread/snowman/textures/metallic_roughness.jpg +0 -0
  32. package/examples/public/gingerbread/snowman/textures/normal.jpg +0 -0
  33. package/examples/public/test.usdz +0 -0
  34. package/examples/public/vite.svg +0 -1
  35. package/examples/src/fileHandling.ts +0 -256
  36. package/examples/src/main.ts +0 -167
  37. package/examples/src/three.ts +0 -140
  38. package/examples/src/vite-env.d.ts +0 -1
  39. package/examples/tsconfig.json +0 -23
  40. package/examples/vite.config.js +0 -21
  41. package/src/bindings/emHdBindings.data +0 -19331
  42. package/src/bindings/emHdBindings.worker.js +0 -124
@@ -1,24 +0,0 @@
1
- {
2
- "name": "@needle-tools/usd-example-three",
3
- "private": true,
4
- "version": "0.0.0",
5
- "type": "module",
6
- "scripts": {
7
- "start": "npm run dev",
8
- "dev": "vite",
9
- "build": "tsc && vite build",
10
- "preview": "vite preview"
11
- },
12
- "devDependencies": {
13
- "typescript": "^5.2.2",
14
- "vite": "^5.0.8",
15
- "vite-plugin-static-copy": "^1.0.5"
16
- },
17
- "dependencies": {
18
- "@needle-tools/usd": "file:..",
19
- "@types/three": "^0.165.0",
20
- "three": "^0.164.1",
21
- "vite-plugin-top-level-await": "^1.4.1",
22
- "vite-plugin-wasm": "^3.3.0"
23
- }
24
- }
@@ -1,46 +0,0 @@
1
- #usda 1.0
2
- (
3
- customLayerData = {
4
- string creator = "Mira Ly Herbst, Binh Minh Herbst, Felix Herbst, 2025"
5
- }
6
- defaultPrim = "Scenery"
7
- metersPerUnit = 1
8
- upAxis = "Z"
9
- )
10
-
11
- def Xform "Scenery"
12
- {
13
- def "GingerBreadHouse" (
14
- prepend references = @https://cloud-staging.needle.tools/-/assets/Z23hmXB22WdG2-22WdG2/house/GingerBreadHouse.usdc@
15
- displayName = "Gingerbread House"
16
- )
17
- {
18
- quatf xformOp:orient = (0.5092794, 0, 0, -0.8606013)
19
- float3 xformOp:scale = (1, 0.99999994, 0.9999998)
20
- float3 xformOp:translate = (0.04039519, -0.0057177544, 0)
21
- uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
22
- }
23
-
24
- def "Snowman" (
25
- prepend references = @gingerbread/snowman/Snowman.usdc@
26
- displayName = "Snowman"
27
- )
28
- {
29
- quatf xformOp:orient = (0.8868096, 0, 0, -0.46213505)
30
- float3 xformOp:scale = (0.99999994, 0.99999994, 0.9999998)
31
- float3 xformOp:translate = (-0.03819806, -0.0054023676, 0)
32
- uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
33
-
34
- # make an over here with /root/_materials/material/Principled_BSDF
35
-
36
- over "_materials" {
37
- over "material" {
38
- over "Principled_BSDF" {
39
- color3f inputs:diffuseColor = (1.0, 0.0, 0.0)
40
- float inputs:specular = 0.0
41
- }
42
- }
43
- }
44
- }
45
-
46
- }
@@ -1,44 +0,0 @@
1
- #usda 1.0
2
- (
3
- customLayerData = {
4
- string creator = "Mira Ly Herbst, Binh Minh Herbst, Felix Herbst, 2025"
5
- }
6
- defaultPrim = "Scenery"
7
- metersPerUnit = 1
8
- upAxis = "Z"
9
- )
10
-
11
- def Xform "Scenery"
12
- {
13
- def "GingerBreadHouse" (
14
- prepend references = @https://cloud-staging.needle.tools/-/assets/Z23hmXB22WdG2-22WdG2/house/GingerBreadHouse.usdc@
15
- displayName = "Gingerbread House"
16
- )
17
- {
18
- quatf xformOp:orient = (0.5092794, 0, 0, -0.8606013)
19
- float3 xformOp:scale = (1, 0.99999994, 0.9999998)
20
- float3 xformOp:translate = (0.04039519, -0.0057177544, 0)
21
- uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
22
- }
23
-
24
- def "Snowman" (
25
- prepend references = @https://cloud-staging.needle.tools/-/assets/Z23hmXB22WdG2-22WdG2/snowman/Snowman.usdc@
26
- displayName = "Snowman"
27
- )
28
- {
29
- quatf xformOp:orient = (0.8868096, 0, 0, -0.46213505)
30
- float3 xformOp:scale = (0.99999994, 0.99999994, 0.9999998)
31
- float3 xformOp:translate = (-0.03819806, -0.0054023676, 0)
32
- uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
33
-
34
- # make an over here with /root/_materials/material/Principled_BSDF
35
- over "_materials" {
36
- over "material" {
37
- over "Principled_BSDF" {
38
- color3f inputs:diffuseColor = (1.0, 0.0, 0.0)
39
- float inputs:specular = 0.0
40
- }
41
- }
42
- }
43
- }
44
- }
@@ -1,35 +0,0 @@
1
- #usda 1.0
2
- (
3
- customLayerData = {
4
- string creator = "Mira Ly Herbst, Binh Minh Herbst, Felix Herbst, 2025"
5
- }
6
- defaultPrim = "Scenery"
7
- metersPerUnit = 1
8
- upAxis = "Z"
9
- )
10
-
11
- def Xform "Scenery"
12
- {
13
- def "GingerBreadHouse" (
14
- prepend references = @house/GingerBreadHouse.usdc@
15
- displayName = "Gingerbread House"
16
- )
17
- {
18
- quatf xformOp:orient = (0.5092794, 0, 0, -0.8606013)
19
- float3 xformOp:scale = (1, 0.99999994, 0.9999998)
20
- float3 xformOp:translate = (0.04039519, -0.0057177544, 0)
21
- uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
22
- }
23
-
24
- def "Snowman" (
25
- prepend references = @snowman/Snowman.usdc@
26
- displayName = "Snowman"
27
- )
28
- {
29
- quatf xformOp:orient = (0.8868096, 0, 0, -0.46213505)
30
- float3 xformOp:scale = (0.99999994, 0.99999994, 0.9999998)
31
- float3 xformOp:translate = (-0.03819806, -0.0054023676, 0)
32
- uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
33
- }
34
- }
35
-
Binary file
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -1,256 +0,0 @@
1
- document.addEventListener("dragover", function (ev) {
2
- ev.preventDefault();
3
- });
4
-
5
- document.addEventListener("drop", function (ev) {
6
- ev.preventDefault();
7
-
8
- if (ev.dataTransfer?.items)
9
- {
10
- /** @type {FileSystemEntry[]} */
11
- const allEntries = [];
12
-
13
- let haveGetAsFileSystemHandle = false;
14
- let haveGetAsEntry = false;
15
- if (ev.dataTransfer.items.length > 0) {
16
- haveGetAsEntry = ("getAsEntry" in ev.dataTransfer.items[0]) || ("webkitGetAsEntry" in ev.dataTransfer.items[0]);
17
- haveGetAsFileSystemHandle = ("getAsFileSystemHandle" in ev.dataTransfer.items[0]);
18
- }
19
-
20
- /*
21
- async function* getFilesRecursively(entry) {
22
- if (entry.kind === "file") {
23
- const file = await entry.getFile();
24
- if (file !== null) {
25
- file.relativePath = getRelativePath(entry);
26
- yield file;
27
- }
28
- } else if (entry.kind === "directory") {
29
- for await (const handle of entry.values()) {
30
- yield* getFilesRecursively(handle);
31
- }
32
- }
33
- }
34
-
35
- if (haveGetAsFileSystemHandle) {
36
- for (var i = 0; i < ev.dataTransfer.items.length; i++)
37
- {
38
- let item = ev.dataTransfer.items[i];
39
- let handle = item.getAsFileSystemHandle();
40
- allEntries.push(handle);
41
- }
42
- handleFilesystemEntries(allEntries);
43
- return;
44
- }
45
- */
46
-
47
- if (haveGetAsEntry) {
48
- for (var i = 0; i < ev.dataTransfer.items.length; i++)
49
- {
50
- let item = ev.dataTransfer.items[i];
51
- /** @type {FileSystemEntry} */
52
- let entry = ("getAsEntry" in item) ? item.getAsEntry() : item.webkitGetAsEntry();
53
- allEntries.push(entry);
54
- }
55
- handleFilesystemEntries(allEntries);
56
- return;
57
- }
58
-
59
- for (var i = 0; i < ev.dataTransfer.items.length; i++)
60
- {
61
- let item = ev.dataTransfer.items[i];
62
-
63
- // API when there's no "getAsEntry" support
64
- console.log(item.kind, item, entry);
65
- if (item.kind === 'file')
66
- {
67
- var file = item.getAsFile();
68
- testAndLoadFile(file);
69
- }
70
- // could also be a directory
71
- else if (item.kind === 'directory')
72
- {
73
- var dirReader = item.createReader();
74
- dirReader.readEntries(function(entries) {
75
- for (var i = 0; i < entries.length; i++) {
76
- console.log(entries[i].name);
77
- var entry = entries[i];
78
- if (entry.isFile) {
79
- entry.file(function(file) {
80
- testAndLoadFile(file);
81
- });
82
- }
83
- }
84
- });
85
- }
86
- }
87
- } else {
88
- for (var i = 0; i < ev.dataTransfer.files.length; i++) {
89
- let file = ev.dataTransfer.files[i];
90
- testAndLoadFile(file);
91
- }
92
- }
93
- });
94
-
95
- /**
96
- * @param {FileSystemEntry[]} entries
97
- */
98
- async function handleFilesystemEntries(entries) {
99
- /** @type {FileSystemEntry[]} */
100
- const allFiles = [];
101
- const fileIgnoreList = [
102
- '.gitignore',
103
- 'README.md',
104
- '.DS_Store',
105
- ]
106
- const dirIgnoreList = [
107
- '.git',
108
- 'node_modules',
109
- ]
110
- const debugFileHandling = false;
111
-
112
- for (let entry of entries) {
113
- if (debugFileHandling) console.log("file entry", entry)
114
- if (entry.isFile) {
115
- if (debugFileHandling) console.log("single file", entry);
116
- if (fileIgnoreList.includes(entry.name)) {
117
- continue;
118
- }
119
- allFiles.push(entry);
120
- }
121
- else if (entry.isDirectory) {
122
- if (dirIgnoreList.includes(entry.name)) {
123
- continue;
124
- }
125
- const files = await readDirectory(entry);
126
- if (debugFileHandling) console.log("all files", files);
127
- for (const file of files) {
128
- if (fileIgnoreList.includes(file.name)) {
129
- continue;
130
- }
131
- allFiles.push(file);
132
- }
133
- }
134
- }
135
-
136
- // determine which of these is likely the root file
137
- let rootFileCandidates = [];
138
- let usdaCandidates = [];
139
-
140
- // sort so shorter paths come first
141
- allFiles.sort((a, b) => {
142
- const diff = a.fullPath.split('/').length - b.fullPath.split('/').length;
143
- if (diff !== 0) return diff;
144
- return a.fullPath.localeCompare(b.fullPath);
145
- });
146
-
147
- // console.log("path candidates", allFiles);
148
-
149
- for (const file of allFiles) {
150
- let ext = file.name.split('.').pop();
151
- if(ext == 'usd' || ext == 'usdz' || ext == 'usda' || ext == 'usdc') {
152
- rootFileCandidates.push(file);
153
- }
154
- if(ext == 'usda') {
155
- usdaCandidates.push(file);
156
- }
157
- }
158
-
159
- let rootFile = undefined;
160
-
161
- // if there's multiple, use the first usda
162
- if (rootFileCandidates.length > 1) {
163
- if (usdaCandidates.length > 0) {
164
- rootFile = usdaCandidates[0];
165
- }
166
- else {
167
- rootFile = rootFileCandidates[0];
168
- }
169
- }
170
- else {
171
- // find the first usda file
172
- for (const file of allFiles) {
173
- let ext = file.name.split('.').pop();
174
- if(ext == 'usda' || ext == 'usdc' || ext == 'usdz' || ext == 'usd') {
175
- rootFile = file;
176
- break;
177
- }
178
- }
179
- }
180
-
181
- if (!rootFile && allFiles.length > 0) {
182
- // use first file
183
- rootFile = allFiles[0];
184
- }
185
-
186
- // TODO if there are still multiple candidates we should ask the user which one to use
187
- console.log("Assuming this is the root file: " + rootFile?.name); // + ". Total: " + allFiles.length, allFiles.map(f => f.fullPath).join('\n'));
188
-
189
-
190
- async function getFile(fileEntry) {
191
- try {
192
- return new Promise((resolve, reject) => fileEntry.file(resolve, reject));
193
- } catch (err) {
194
- console.log(err);
195
- }
196
- }
197
-
198
- console.log("All files", allFiles);
199
-
200
- allDroppedFiles = allFiles;
201
-
202
- return;
203
- }
204
-
205
- /**
206
- * @param {FileSystemDirectoryEntry} directory
207
- */
208
- async function readDirectory(directory) {
209
- let entries = [];
210
-
211
- let getAllDirectoryEntries = async (dirReader) => {
212
- let entries = [];
213
- let readEntries = async () => {
214
- let result = await new Promise((resolve, reject) => dirReader.readEntries(resolve, reject));
215
- if (result.length === 0)
216
- return entries;
217
- else
218
- return entries.concat(result, await readEntries());
219
- }
220
- return await readEntries();
221
- }
222
-
223
- /**
224
- * @param {FileSystemDirectoryReader} dirReader
225
- * @param {FileSystemDirectoryEntry} directory
226
- * @returns {Promise<number>}
227
- */
228
- let getEntries = async (directory) => {
229
- let dirReader = directory.createReader();
230
- await new Promise(async (resolve, reject) => {
231
- // Call the reader.readEntries() until no more results are returned.
232
-
233
- const results = await getAllDirectoryEntries(dirReader);
234
-
235
- if (results.length) {
236
- // entries = entries.concat(results);
237
- for (let entry of results) {
238
- if (entry.isDirectory) {
239
- const foundFiles = await getEntries(entry);
240
- if (foundFiles === 100)
241
- console.warn("Found more than 100 files in directory", entry);
242
- }
243
- else {
244
- entries.push(entry);
245
- }
246
- }
247
- }
248
- resolve(results.length);
249
- });
250
- };
251
-
252
- await getEntries(directory);
253
- return entries;
254
- }
255
-
256
- export let allDroppedFiles: FileSystemFileEntry[] = [];
@@ -1,167 +0,0 @@
1
-
2
- import { getUsdModule, createThreeHydra, USD, createThreeHydraReturnType } from '@needle-tools/usd';
3
- import { loadEnvMap, run } from './three';
4
- import { Object3D, Scene, WebGLRenderer } from 'three';
5
-
6
- import { allDroppedFiles } from './fileHandling';
7
-
8
- let hydraDelegate: createThreeHydraReturnType | null;
9
- let scene: Scene;
10
- let usdContent: Object3D;
11
- let usd: USD;
12
- let app: { fitCamera: () => void };
13
-
14
- getUsdModule({
15
- debug: true,
16
- urlModifier: async (url: string) => {
17
- // Resolve GitHub-specific URLs
18
- // rewrite GitHub links in the form https://github.com/usd-wg/assets/blob/main/full_assets/ElephantWithMonochord/SoC-ElephantWithMonochord.usdc
19
- // to the raw version https://raw.githubusercontent.com/usd-wg/assets/main/full_assets/ElephantWithMonochord/SoC-ElephantWithMonochord.usdc
20
- if (url.startsWith("https://github.com")) {
21
- url = url.replace("github.com", "raw.githubusercontent.com");
22
- url = url.replace("/blob/", "/");
23
- }
24
-
25
- console.log(url);
26
-
27
- // Check if we find this URL in the dropped files, if there are any
28
- if (allDroppedFiles && allDroppedFiles.length > 0) {
29
- const found = allDroppedFiles.find(f => f.fullPath == url);
30
-
31
- if (found) {
32
- console.log("found file, returning handle", url, found);
33
- if ("file" in found) {
34
- return await new Promise((resolve, reject) => found.file(resolve, reject));
35
- }
36
- else if ("getFile" in found) {
37
- return await found.getFile();
38
- }
39
- }
40
- else {
41
- console.warn("File not found", url, allDroppedFiles);
42
- }
43
- }
44
-
45
- // return "./gingerbread/house/" + url;
46
- return url;
47
- }
48
- }).then(async (USD: USD) => {
49
-
50
- const testUrls = [
51
- { label: "USDZ Cube", url: "/test.usdz" },
52
- { label: "Gingerbread House USDC", url: "/gingerbread/house/GingerBreadHouse.usdc" },
53
- { label: "Gingerbread House USDA", url: "/gingerbread/GingerbreadHouse.usda", },
54
- { label: "USDA file with HTTPS references", url: "/HttpReferences.usda" },
55
- { label: "Gingerbread House from Needle Cloud", url: "https://cloud-staging.needle.tools/-/assets/Z23hmXB22WdG2-22WdG2/file.usda" },
56
- { label: "Gingerbread House Subasset from Needle Cloud", url: "https://cloud-staging.needle.tools/-/assets/Z23hmXB22WdG2-22WdG2/house/GingerBreadHouse.usdc" },
57
- { label: "USD Kitchen from Needle Cloud", url: "https://cloud-staging.needle.tools/-/assets/Z23hmXBZCdB4p-ZCdB4p/file.usdz" },
58
- { label: "Car with Variants", url: "https://github.com/usd-wg/assets/blob/main/full_assets/Vehicles/USD_Mini_Car_Kit/assets/vehicles/vehicleVariants.usda" },
59
- { label: "Carbon Frame Bike USDZ", url: "https://github.com/usd-wg/assets/blob/jcowles/discoverability/full_assets/CarbonFrameBike/CarbonFrameBike.usdz" },
60
- { label: "Carbon Frame Bike USDA", url: "https://github.com/usd-wg/assets/blob/jcowles/discoverability/full_assets/CarbonFrameBike/index.usda" },
61
- { label: "McUsd USDA", url: "https://github.com/usd-wg/assets/blob/jcowles/discoverability/full_assets/McUsd/McUsd.usda" },
62
- { label: "Teapot USD", url: "https://github.com/usd-wg/assets/blob/main/full_assets/Teapot/Teapot.usd" },
63
- ];
64
-
65
- const div = document.createElement("div");
66
- div.className = "test-buttons";
67
-
68
- for (const url of testUrls) {
69
- const button = document.createElement("button");
70
- button.innerText = url.label;
71
- button.onclick = () => loadFile(url.url);
72
- div.appendChild(button);
73
- }
74
-
75
- document.body.appendChild(div);
76
-
77
- const div2 = document.createElement("div");
78
- div2.className = "options";
79
- const frameButton = document.createElement("button");
80
- frameButton.innerText = "Fit Camera";
81
- frameButton.onclick = () => app.fitCamera();
82
- div2.appendChild(frameButton);
83
- div.appendChild(div2);
84
-
85
- // const url = "test.usdz"; // local file
86
- // const url = "/gingerbread/house/GingerBreadHouse.usdc";
87
- // const url = "/gingerbread/GingerbreadHouse.usda";
88
- const url = "/HttpReferences.usda";
89
- // ... all the URLs
90
- // --> put them all into the virtual file system
91
- // --> load the first one (assume which one that actually is)
92
-
93
- // const url = "https://cloud-staging.needle.tools/-/assets/Z23hmXB22WdG2-22WdG2/file.usda"; // remote file
94
- // const url = "https://cloud-staging.needle.tools/-/assets/Z23hmXB22WdG2-22WdG2/house/GingerBreadHouse.usdc"; // remote file
95
-
96
- // using a file/buffer
97
- /*
98
- const buffer = await fetch(url).then(response => response.arrayBuffer());
99
- const file = new File([buffer], url, { type: "model/usd" });
100
- file.path = url; // used to determine the directory structure
101
- */
102
-
103
- const renderer = new WebGLRenderer({ antialias: true, alpha: true });
104
- const envmapUrl = "https://dl.polyhaven.org/file/ph-assets/HDRIs/exr/1k/studio_small_09_1k.exr";
105
- const envmap = await loadEnvMap(envmapUrl, renderer);
106
-
107
- scene = new Scene();
108
- scene.environment = envmap;
109
- scene.background = envmap;
110
- scene.backgroundBlurriness = 0.8;
111
- scene.backgroundIntensity = 0.2;
112
-
113
- usd = USD;
114
-
115
- /*
116
- usdContent = new Object3D();
117
- scene.add(usdContent);
118
- hydraDelegate = await createThreeHydra({
119
- debug: true,
120
- USD,
121
- url: url,
122
- // files: [file],
123
- // @ts-ignore
124
- scene: usdContent,
125
- })
126
- */
127
-
128
- // loadFile(url);
129
-
130
- app = run({
131
- renderer,
132
- scene: scene,
133
- onRender: (dt) => {
134
- hydraDelegate?.update(dt);
135
- }
136
- });
137
- })
138
-
139
- async function loadFile(url: string) {
140
-
141
- if (hydraDelegate)
142
- hydraDelegate.dispose();
143
- hydraDelegate = null;
144
-
145
- if (usdContent) {
146
- scene.remove(usdContent);
147
- // TODO dispose as well
148
- }
149
-
150
- usdContent = new Object3D();
151
- scene.add(usdContent);
152
-
153
- const delegate = await createThreeHydra({
154
- debug: true,
155
- USD: usd,
156
- url: url,
157
- // @ts-ignore
158
- scene: usdContent,
159
- })
160
-
161
- hydraDelegate = delegate;
162
-
163
- console.log("Scene content", usdContent);
164
- app.fitCamera();
165
- }
166
-
167
- window.loadFile = loadFile;