@needle-tools/usd 0.0.1-412624
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 +8 -0
- package/README.md +100 -0
- package/examples/index.html +58 -0
- package/examples/package-lock.json +1548 -0
- package/examples/package.json +24 -0
- package/examples/public/HttpReferences copy.usda +46 -0
- package/examples/public/HttpReferences.usda +44 -0
- package/examples/public/gingerbread/GingerbreadHouse.usda +35 -0
- package/examples/public/gingerbread/house/GingerBreadHouse.usdc +0 -0
- package/examples/public/gingerbread/house/textures/color.jpg +0 -0
- package/examples/public/gingerbread/house/textures/metallic_roughness.jpg +0 -0
- package/examples/public/gingerbread/house/textures/normal.jpg +0 -0
- package/examples/public/gingerbread/snowman/Snowman.usdc +0 -0
- package/examples/public/gingerbread/snowman/textures/color.jpg +0 -0
- package/examples/public/gingerbread/snowman/textures/metallic_roughness.jpg +0 -0
- package/examples/public/gingerbread/snowman/textures/normal.jpg +0 -0
- package/examples/public/test.usdz +0 -0
- package/examples/public/vite.svg +1 -0
- package/examples/src/fileHandling.ts +256 -0
- package/examples/src/main.ts +167 -0
- package/examples/src/three.ts +140 -0
- package/examples/src/vite-env.d.ts +1 -0
- package/examples/tsconfig.json +23 -0
- package/examples/vite.config.js +21 -0
- package/package.json +50 -0
- package/src/bindings/.gitattributes +2 -0
- package/src/bindings/emHdBindings.data +19331 -0
- package/src/bindings/emHdBindings.js +12227 -0
- package/src/bindings/emHdBindings.wasm +0 -0
- package/src/bindings/emHdBindings.worker.js +124 -0
- package/src/bindings/index.js +124 -0
- package/src/create.three.js +252 -0
- package/src/hydra/ThreeJsRenderDelegate.js +872 -0
- package/src/hydra/consoleRenderDelegate.js +47 -0
- package/src/hydra/index.js +5 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +5 -0
- package/src/plugins/index.js +2 -0
- package/src/plugins/needle.js +158 -0
- package/src/types/bindings.d.ts +82 -0
- package/src/types/create.three.d.ts +65 -0
- package/src/types/hydra.d.ts +32 -0
- package/src/types/index.d.ts +5 -0
- package/src/types/plugins.d.ts +9 -0
- package/src/types/vite.d.ts +19 -0
- package/src/utils.js +24 -0
- package/src/vite/index.js +22 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// This is a complete Hydra render delegate.
|
|
2
|
+
// It doesn't do anything useful, but it logs out all the calls and arguments it receives.
|
|
3
|
+
export const delegate = {
|
|
4
|
+
createSPrim: (...args) => {
|
|
5
|
+
console.log("createSPrim", args);
|
|
6
|
+
return {
|
|
7
|
+
updateNode: (...args) => {
|
|
8
|
+
console.log("updateNode", args);
|
|
9
|
+
},
|
|
10
|
+
updateFinished: (...args) => {
|
|
11
|
+
console.log("updateFinished", args);
|
|
12
|
+
},
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
createRPrim: (...args) => {
|
|
16
|
+
console.log("createRPrim", args);
|
|
17
|
+
return {
|
|
18
|
+
setMaterial(...args) {
|
|
19
|
+
console.log("setMaterial", args);
|
|
20
|
+
},
|
|
21
|
+
updatePoints(...args) {
|
|
22
|
+
console.log("updatePoints", args);
|
|
23
|
+
},
|
|
24
|
+
updateIndices(...args) {
|
|
25
|
+
console.log("updateIndices", args);
|
|
26
|
+
},
|
|
27
|
+
updateNormals(...args) {
|
|
28
|
+
console.log("updateNormals", args);
|
|
29
|
+
},
|
|
30
|
+
setTransform(...args) {
|
|
31
|
+
console.log("setTransform", args);
|
|
32
|
+
},
|
|
33
|
+
updatePrimvar(...args) {
|
|
34
|
+
console.log("updatePrimvar", args);
|
|
35
|
+
},
|
|
36
|
+
skelDetected(...args) {
|
|
37
|
+
console.log("skelDetected", args);
|
|
38
|
+
},
|
|
39
|
+
setGeomSubsetMaterial(...args) {
|
|
40
|
+
console.log("setGeomSubsetMaterial", args);
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
CommitResources(...args) {
|
|
45
|
+
console.log("CommitResources", args);
|
|
46
|
+
},
|
|
47
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ThreeRenderDelegateInterface } from "./ThreeJsRenderDelegate.js";
|
|
2
|
+
import { delegate as ConsoleDelegate } from "./consoleRenderDelegate.js";
|
|
3
|
+
|
|
4
|
+
export { ThreeRenderDelegateInterface as threeJsRenderDelegate };
|
|
5
|
+
export { ConsoleDelegate as consoleRenderDelegate }
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./types";
|
package/src/index.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Loader, Object3D } from "three";
|
|
2
|
+
import { createThreeHydra, getUsdModule } from "../index.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/** @type {import("../types").addPluginForNeedleEngine} */
|
|
6
|
+
export async function addPluginForNeedleEngine(options) {
|
|
7
|
+
if (options.debug) console.debug("🐉 Adding USDZ plugin to Needle Engine");
|
|
8
|
+
return import("@needle-tools/engine").then(module => {
|
|
9
|
+
return onAddNeedlePlugin(module, options);
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {typeof import("@needle-tools/engine")} NEEDLE
|
|
16
|
+
* @param {import("../types").PluginContext} opts
|
|
17
|
+
*/
|
|
18
|
+
function onAddNeedlePlugin(NEEDLE, opts) {
|
|
19
|
+
|
|
20
|
+
class NeedleUSDZHHandler extends NEEDLE.Behaviour {
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
/**
|
|
24
|
+
* @type {import("..").NeedleThreeHydraHandle | null}
|
|
25
|
+
*/
|
|
26
|
+
this.handle = null;
|
|
27
|
+
this.root = new Object3D();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
update() {
|
|
31
|
+
if (this.handle) {
|
|
32
|
+
this.handle.update(this.context.time.deltaTime);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
onDestroy() {
|
|
36
|
+
if (this.handle) {
|
|
37
|
+
this.handle.dispose();
|
|
38
|
+
this.handle = null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Needle USDZ Loader
|
|
46
|
+
* @extends {Loader<Object3D>}
|
|
47
|
+
*/
|
|
48
|
+
class NeedleUSDZLoader extends Loader {
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* the usd module promise - initialized when the first loader is created
|
|
52
|
+
* @type {Promise<import("../types").USD> | null}
|
|
53
|
+
* @private
|
|
54
|
+
* @static
|
|
55
|
+
*/
|
|
56
|
+
static usdModule = null;
|
|
57
|
+
|
|
58
|
+
// LOADER IMPL:
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {NeedleUSDZHHandler} comp
|
|
62
|
+
*/
|
|
63
|
+
constructor(comp) {
|
|
64
|
+
super();
|
|
65
|
+
this.comp = comp;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @type {Loader<Object3D>["loadAsync"]}
|
|
70
|
+
*/
|
|
71
|
+
async loadAsync(url, onProgress) {
|
|
72
|
+
|
|
73
|
+
const debug = opts.debug || false;;
|
|
74
|
+
|
|
75
|
+
onProgress?.(new ProgressEvent("load", { lengthComputable: false, loaded: 0, total: 0 }));
|
|
76
|
+
|
|
77
|
+
// Get the files immediately (don't wait for the USD module to be loaded)
|
|
78
|
+
const files = opts.getFiles();
|
|
79
|
+
|
|
80
|
+
NeedleUSDZLoader.usdModule ??= getUsdModule({
|
|
81
|
+
debug
|
|
82
|
+
// setURLModifier: USDLoadingManager.urlModifier,
|
|
83
|
+
}).then(res => {
|
|
84
|
+
if (debug) console.debug("🐉 USD HYDRA IS READY");
|
|
85
|
+
return res;
|
|
86
|
+
})
|
|
87
|
+
const usd = await NeedleUSDZLoader.usdModule;
|
|
88
|
+
|
|
89
|
+
onProgress?.(new ProgressEvent("load", { lengthComputable: true, loaded: .5, total: 1 }));
|
|
90
|
+
|
|
91
|
+
// Load hydra
|
|
92
|
+
const handle = await createThreeHydra({
|
|
93
|
+
debug,
|
|
94
|
+
USD: usd,
|
|
95
|
+
scene: this.comp.root,
|
|
96
|
+
url: url,
|
|
97
|
+
files: files,
|
|
98
|
+
});
|
|
99
|
+
this.comp.handle = handle;
|
|
100
|
+
|
|
101
|
+
if (debug) console.debug("Loaded", this.comp);
|
|
102
|
+
|
|
103
|
+
onProgress?.(new ProgressEvent("load", { lengthComputable: true, loaded: 1, total: 1 }));
|
|
104
|
+
|
|
105
|
+
return this.comp.root;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
parse() {
|
|
109
|
+
console.error("🐉 USDZ LOADER PARSE CALLED: Not implemented");
|
|
110
|
+
return this.comp.root;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
const removeFiletype = NEEDLE.NeedleEngineModelLoader.onDetermineModelMimetype(cb => {
|
|
119
|
+
|
|
120
|
+
if (cb.contentType === "application/vnd.usd") {
|
|
121
|
+
return "model/vnd.usd";
|
|
122
|
+
}
|
|
123
|
+
const ext = cb.url.split('.').pop()?.toLowerCase();
|
|
124
|
+
switch (ext) {
|
|
125
|
+
case "usdz":
|
|
126
|
+
return "model/vnd.usdz+zip"
|
|
127
|
+
case "usda":
|
|
128
|
+
return "model/vnd.usda"
|
|
129
|
+
case "usdc":
|
|
130
|
+
return "model/vnd.usdc"
|
|
131
|
+
case "usd":
|
|
132
|
+
return "model/vnd.usd"
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const handlers = new Array();
|
|
138
|
+
const removeCustomLoader = NEEDLE.NeedleEngineModelLoader.onCreateCustomModelLoader(cb => {
|
|
139
|
+
if (cb.mimetype.startsWith("model/vnd.usd")) {
|
|
140
|
+
const handler = new NeedleUSDZHHandler();
|
|
141
|
+
handlers.push(handler);
|
|
142
|
+
NEEDLE.addComponent(cb.context.scene, handler);
|
|
143
|
+
return new NeedleUSDZLoader(handler);
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
return () => {
|
|
150
|
+
removeFiletype();
|
|
151
|
+
removeCustomLoader();
|
|
152
|
+
for (const handler of handlers) {
|
|
153
|
+
handler.destroy();
|
|
154
|
+
}
|
|
155
|
+
handlers.length = 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
|
|
2
|
+
declare type FSNode = {
|
|
3
|
+
contents: ArrayLike,
|
|
4
|
+
id: number,
|
|
5
|
+
mode: number,
|
|
6
|
+
name: string,
|
|
7
|
+
timestamp: number,
|
|
8
|
+
isFolder: boolean,
|
|
9
|
+
isDevice: boolean,
|
|
10
|
+
read: boolean,
|
|
11
|
+
write: boolean,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare type USD = {
|
|
15
|
+
FS_createDataFile: (parent: string, filepath: string, data: Uint8Array, canRead: boolean, canWrite: boolean, canOwn: boolean) => FSNode,
|
|
16
|
+
FS_createPath: (parent: string, path: string, canRead: boolean, canWrite: boolean) => FSNode,
|
|
17
|
+
FS_unlink: (path: string) => void,
|
|
18
|
+
FS_readdir: (path: string) => string[],
|
|
19
|
+
FS_rmdir: (path: string) => void,
|
|
20
|
+
FS_analyzePath: (path: string) => FSNode,
|
|
21
|
+
HdWebSyncDriver: new (delegate: hydraDelegate, filepath: string) => HdWebSyncDriver,
|
|
22
|
+
flushPendingDeletes: () => void,
|
|
23
|
+
ready: Promise<any>,
|
|
24
|
+
debug: boolean;
|
|
25
|
+
calledRun: boolean;
|
|
26
|
+
stderr: any;
|
|
27
|
+
stdin: any;
|
|
28
|
+
stdout: any;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
declare type USDStage = {
|
|
32
|
+
GetStartTimeCode(): number,
|
|
33
|
+
GetEndTimeCode(): number,
|
|
34
|
+
GetTimeCodesPerSecond(): number,
|
|
35
|
+
GetUpAxis(): number,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
declare type HdWebSyncDriver = {
|
|
39
|
+
getFile: (path: string, cb: (loadedFile: ArrayBufferLike) => void) => void,
|
|
40
|
+
GetStage: () => USDStage,
|
|
41
|
+
SetTime(timecode: number): void,
|
|
42
|
+
GetTime(): number,
|
|
43
|
+
Draw(): void,
|
|
44
|
+
|
|
45
|
+
/** ??? */
|
|
46
|
+
clone(): HdWebSyncDriver,
|
|
47
|
+
/** ??? */
|
|
48
|
+
delete(): void,
|
|
49
|
+
/** ??? */
|
|
50
|
+
deleteLater(): void,
|
|
51
|
+
isDeleted(): boolean,
|
|
52
|
+
/** ??? */
|
|
53
|
+
isAliasOf(): boolean,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type GetUsdModuleOptions = {
|
|
57
|
+
debug?: boolean,
|
|
58
|
+
mainScriptUrlOrBlob?: string,
|
|
59
|
+
wasmBinary?: ArrayBufferLike,
|
|
60
|
+
locateFile?: (path: string) => string,
|
|
61
|
+
getPreloadedPackage?: (file: string, size: number) => ArrayBuffer | null,
|
|
62
|
+
setStatus?: (status: string) => void,
|
|
63
|
+
onDownloadProgress?: (downloaded: number, total: number) => void,
|
|
64
|
+
/** Returns a transferable object that can be resolved to an ArrayBuffer,
|
|
65
|
+
* or an URL that can be fetched to get an ArrayBuffer.
|
|
66
|
+
*/
|
|
67
|
+
urlModifier?: (url: string) =>
|
|
68
|
+
Promise<
|
|
69
|
+
ArrayBuffer | File | FileSystemFileHandle | FileSystemFileEntry | string
|
|
70
|
+
> | ArrayBuffer | File | FileSystemFileHandle | FileSystemFileEntry | string,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Loads the USD Module.
|
|
75
|
+
* @example
|
|
76
|
+
* ```javascript
|
|
77
|
+
* getUsdModule({ mainScriptUrlOrBlob: "/emHdBindings.js" }).then(USD => { ... })
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export function getUsdModule(opts?: GetUsdModuleOptions): Promise<USD>;
|
|
81
|
+
|
|
82
|
+
export type USDRoot = {}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Scene } from "three"
|
|
2
|
+
import { HdWebSyncDriver, USD } from ".."
|
|
3
|
+
|
|
4
|
+
export declare type HydraFile = File & { path: string };
|
|
5
|
+
|
|
6
|
+
export declare type createThreeHydraConfig = {
|
|
7
|
+
|
|
8
|
+
debug?: boolean,
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* USD Module
|
|
12
|
+
* @example
|
|
13
|
+
* ```javascript
|
|
14
|
+
* getUsdModule({
|
|
15
|
+
* mainScriptUrlOrBlob: "/emHdBindings.js"
|
|
16
|
+
* }).then(USD => { ... })
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
USD: USD,
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Optional buffer of the usdz file
|
|
23
|
+
*/
|
|
24
|
+
buffer?: ArrayBuffer,
|
|
25
|
+
|
|
26
|
+
url?: string,
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The scene to be loaded as the root of the USD stage.
|
|
30
|
+
*/
|
|
31
|
+
scene: Object3D,
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Files to be loaded into the virtual file system.
|
|
35
|
+
* The first file will be loaded as the root file, others will be loaded as dependencies.
|
|
36
|
+
*/
|
|
37
|
+
files: Array<HydraFile>,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Use the hydra handle to update the usd scene periodically.
|
|
42
|
+
*/
|
|
43
|
+
export declare type NeedleThreeHydraHandle = {
|
|
44
|
+
/** The hydra driver
|
|
45
|
+
*/
|
|
46
|
+
driver: HdWebSyncDriver,
|
|
47
|
+
/** Call update periodically to update the usd scene.
|
|
48
|
+
* @param dt The delta time since the last update.
|
|
49
|
+
*/
|
|
50
|
+
update: (dt: number) => void,
|
|
51
|
+
/** Call this to update the usd scene immediately.
|
|
52
|
+
* @param dt The delta time since the last update.
|
|
53
|
+
*/
|
|
54
|
+
dispose: () => void,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export declare class USDLoadingManager {
|
|
58
|
+
static setURLModifier(callback: (url: string) => string): void;
|
|
59
|
+
static urlModifier: (url: string) => string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Creates a new three.js hydra handle.
|
|
64
|
+
*/
|
|
65
|
+
export function createThreeHydra(config: createThreeHydraConfig): Promise<NeedleThreeHydraHandle>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Object3D, Texture } from 'three';
|
|
2
|
+
import { HdWebSyncDriver } from './bindings';
|
|
3
|
+
|
|
4
|
+
export class hydraDelegate { }
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export const consoleRenderDelegate: hydraDelegate = {}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export type threeJsRenderDelegateConfig = {
|
|
19
|
+
driver: () => HdWebSyncDriver,
|
|
20
|
+
usdRoot: Object3D,
|
|
21
|
+
/** Paths for resolving textures */
|
|
22
|
+
paths?: string[],
|
|
23
|
+
/** @deprecated */
|
|
24
|
+
envMap?: Texture,
|
|
25
|
+
}
|
|
26
|
+
export class threeJsRenderDelegate extends hydraDelegate {
|
|
27
|
+
constructor(path: string, config: threeJsRenderDelegateConfig)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Enable USD WASM support for vite based applications.
|
|
6
|
+
* @example sveltekit
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { needleUSD } from '@needle-tools/usd';
|
|
9
|
+
* export default defineConfig(async ({ command }) => {
|
|
10
|
+
* return {
|
|
11
|
+
* plugins: [
|
|
12
|
+
* ...needleUSD(),
|
|
13
|
+
* sveltekit(),
|
|
14
|
+
* ],
|
|
15
|
+
* }
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function needleUSD(): Array<Plugin>;
|
package/src/utils.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {ArrayBuffer} buffer
|
|
5
|
+
* @returns {"usdz" | "usd" | "usda" | "unknown"}
|
|
6
|
+
*/
|
|
7
|
+
export function tryDetermineFileFormat(buffer) {
|
|
8
|
+
|
|
9
|
+
const bytes = new Uint8Array(buffer, 0, 16);
|
|
10
|
+
|
|
11
|
+
// USDZ
|
|
12
|
+
if (bytes[0] == 80 && bytes[1] == 75 && bytes[2] == 3 && bytes[3] == 4) {
|
|
13
|
+
return "usdz";
|
|
14
|
+
}
|
|
15
|
+
// USD
|
|
16
|
+
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) {
|
|
17
|
+
return "usd";
|
|
18
|
+
}
|
|
19
|
+
if (bytes[0] === 35 && bytes[1] === 117 && bytes[2] === 115 && bytes[3] === 100) {
|
|
20
|
+
return "usda";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return "unknown";
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
/** @type {import('vite').Plugin} */
|
|
3
|
+
const crossOriginIsolatedPlugin = {
|
|
4
|
+
name: 'needle:usd-crossoriginisolated',
|
|
5
|
+
configureServer: (server) => {
|
|
6
|
+
server.middlewares.use((_req, res, next) => {
|
|
7
|
+
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
|
|
8
|
+
res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
|
|
9
|
+
next();
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Needle USD plugin for vite.
|
|
17
|
+
* This plugin sets the Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers
|
|
18
|
+
* @returns {Array<import('vite').Plugin>} plugins
|
|
19
|
+
*/
|
|
20
|
+
export function needleUSD() {
|
|
21
|
+
return [crossOriginIsolatedPlugin]
|
|
22
|
+
}
|