@needle-tools/gltf-progressive 1.0.0-alpha.1 → 1.0.0-alpha.11

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.
@@ -0,0 +1,134 @@
1
+ import { LODsManager } from "../lods_manager.js";
2
+ import { EXTENSION_NAME, NEEDLE_progressive } from "../extension.js";
3
+ const $meshLODSymbol = Symbol("NEEDLE_mesh_lod");
4
+ const $textureLODSymbol = Symbol("NEEDLE_texture_lod");
5
+ /** Patch modelviewer to support NEEDLE progressive system
6
+ * @returns a function to remove the patch
7
+ */
8
+ export function patchModelViewer(modelviewer) {
9
+ if (!modelviewer)
10
+ return null;
11
+ let renderer = null;
12
+ let scene = null;
13
+ for (let p = modelviewer; p != null; p = Object.getPrototypeOf(p)) {
14
+ const privateAPI = Object.getOwnPropertySymbols(p);
15
+ const rendererSymbol = privateAPI.find((value) => value.toString() == 'Symbol(renderer)');
16
+ const sceneSymbol = privateAPI.find((value) => value.toString() == 'Symbol(scene)');
17
+ if (!renderer && rendererSymbol != null) {
18
+ renderer = modelviewer[rendererSymbol].threeRenderer;
19
+ }
20
+ if (!scene && sceneSymbol != null) {
21
+ scene = modelviewer[sceneSymbol];
22
+ }
23
+ }
24
+ if (renderer) {
25
+ console.log("Adding Needle LODs to modelviewer");
26
+ const lod = new LODsManager(renderer);
27
+ lod.plugins.push(new RegisterModelviewerDataPlugin(modelviewer));
28
+ lod.enable();
29
+ if (scene) {
30
+ const camera = scene["camera"] || scene.traverse((o) => o.type == "PerspectiveCamera")[0];
31
+ if (camera) {
32
+ renderer.render(scene, camera);
33
+ // setTimeout(() => {
34
+ // renderer.render(scene, camera);
35
+ // }, 100)
36
+ // setTimeout(() => {
37
+ // renderer.render(scene, camera);
38
+ // }, 1200)
39
+ }
40
+ }
41
+ return () => {
42
+ lod.disable();
43
+ };
44
+ }
45
+ return null;
46
+ }
47
+ /**
48
+ * LODs manager plugin that registers LOD data to the NEEDLE progressive system
49
+ */
50
+ class RegisterModelviewerDataPlugin {
51
+ modelviewer;
52
+ _didWarnAboutMissingUrl = false;
53
+ constructor(modelviewer) {
54
+ this.modelviewer = modelviewer;
55
+ }
56
+ onBeforeUpdateLOD(_renderer, scene, _camera, object) {
57
+ this.tryParseMeshLOD(scene, object);
58
+ this.tryParseTextureLOD(scene, object);
59
+ }
60
+ getUrl() {
61
+ let url = this.modelviewer.getAttribute("src");
62
+ // fallback in case the attribute is not set but the src property is
63
+ if (!url) {
64
+ url = this.modelviewer["src"];
65
+ }
66
+ if (!url) {
67
+ if (!this._didWarnAboutMissingUrl)
68
+ console.warn("No url found in modelviewer", this.modelviewer);
69
+ this._didWarnAboutMissingUrl = true;
70
+ }
71
+ return url;
72
+ }
73
+ tryGetCurrentGLTF(scene) {
74
+ return scene._currentGLTF;
75
+ }
76
+ tryParseTextureLOD(scene, object) {
77
+ if (object[$textureLODSymbol] == true)
78
+ return;
79
+ object[$textureLODSymbol] = true;
80
+ const currentGLTF = this.tryGetCurrentGLTF(scene);
81
+ const url = this.getUrl();
82
+ if (!url) {
83
+ return;
84
+ }
85
+ if (currentGLTF) {
86
+ if (object.material) {
87
+ const mat = object.material;
88
+ if (Array.isArray(mat))
89
+ for (const m of mat)
90
+ handleMaterial(m);
91
+ else
92
+ handleMaterial(mat);
93
+ function handleMaterial(mat) {
94
+ if (mat[$textureLODSymbol] == true)
95
+ return;
96
+ mat[$textureLODSymbol] = true;
97
+ // make sure to force the material to be updated
98
+ if (mat.userData)
99
+ mat.userData.LOD = -1;
100
+ const keys = Object.keys(mat);
101
+ for (let i = 0; i < keys.length; i++) {
102
+ const key = keys[i];
103
+ const value = mat[key];
104
+ if (value?.isTexture === true) {
105
+ const textureIndex = value.userData?.associations?.textures;
106
+ const textureData = currentGLTF.parser.json.textures[textureIndex];
107
+ if (textureData.extensions?.[EXTENSION_NAME]) {
108
+ const ext = textureData.extensions[EXTENSION_NAME];
109
+ if (ext && url) {
110
+ NEEDLE_progressive.registerTexture(url, value, ext.lods.length, ext);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ tryParseMeshLOD(_scene, object) {
120
+ if (object[$meshLODSymbol] == true)
121
+ return;
122
+ object[$meshLODSymbol] = true;
123
+ const url = this.getUrl();
124
+ if (!url) {
125
+ return;
126
+ }
127
+ // modelviewer has all the information we need in the userData (associations + gltfExtensions)
128
+ const ext = object.userData?.["gltfExtensions"]?.[EXTENSION_NAME];
129
+ if (ext && url) {
130
+ const lodKey = object.uuid;
131
+ NEEDLE_progressive.registerMesh(url, lodKey, object, 0, ext.lods.length, ext);
132
+ }
133
+ }
134
+ }
@@ -1,14 +1,24 @@
1
- import { WebGLRenderer, Scene, Camera, Mesh } from 'three';
2
- import { NEEDLE_progressive_mesh_model } from '../extension.js';
3
- export interface NEEDLE_progressive_plugin {
4
- /** Called before the LOD level will be requested/updated for a object */
5
- onBeforeUpdateLOD?(renderer: WebGLRenderer, scene: Scene, camera: Camera, object: Mesh): void;
6
- /** Called after the LOD level has been requested */
7
- onAfterUpdatedLOD?(renderer: WebGLRenderer, scene: Scene, camera: Camera, object: Mesh, level: number): void;
8
- /** Called when a new mesh is registered */
9
- onRegisteredNewMesh?(mesh: Mesh, ext: NEEDLE_progressive_mesh_model): void;
10
- /** Called before the LOD mesh is fetched */
11
- onBeforeGetLODMesh?(mesh: Mesh, level: number): void;
12
- }
13
- export declare const plugins: NEEDLE_progressive_plugin[];
14
- export declare function registerPlugin(plugin: NEEDLE_progressive_plugin): void;
1
+ import { WebGLRenderer, Scene, Camera, Mesh } from 'three';
2
+ import { NEEDLE_progressive_mesh_model } from '../extension.js';
3
+ /**
4
+ * This interface is used to define a plugin for the progressive extension. It can be registered using the `registerPlugin` function.
5
+ */
6
+ export interface NEEDLE_progressive_plugin {
7
+ /** Called before the LOD level will be requested/updated for a object */
8
+ onBeforeUpdateLOD?(renderer: WebGLRenderer, scene: Scene, camera: Camera, object: Mesh): void;
9
+ /** Called after the LOD level has been requested */
10
+ onAfterUpdatedLOD?(renderer: WebGLRenderer, scene: Scene, camera: Camera, object: Mesh, level: number): void;
11
+ /** Called when a new mesh is registered */
12
+ onRegisteredNewMesh?(mesh: Mesh, ext: NEEDLE_progressive_mesh_model): void;
13
+ /** Called before the LOD mesh is fetched */
14
+ onBeforeGetLODMesh?(mesh: Mesh, level: number): void;
15
+ }
16
+ /**
17
+ * List of registered plugins for the progressive extension. Please use the `registerPlugin` function to add a plugin.
18
+ * @internal
19
+ */
20
+ export declare const plugins: NEEDLE_progressive_plugin[];
21
+ /**
22
+ * Register a plugin for the progressive extension. The plugin callbacks will be called at different stages of the progressive extension.
23
+ */
24
+ export declare function registerPlugin(plugin: NEEDLE_progressive_plugin): void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * List of registered plugins for the progressive extension. Please use the `registerPlugin` function to add a plugin.
3
+ * @internal
4
+ */
5
+ export const plugins = new Array();
6
+ /**
7
+ * Register a plugin for the progressive extension. The plugin callbacks will be called at different stages of the progressive extension.
8
+ */
9
+ export function registerPlugin(plugin) {
10
+ plugins.push(plugin);
11
+ }
@@ -1,2 +1,2 @@
1
- export declare function getParam(name: string): boolean | string;
2
- export declare function resolveUrl(source: string | undefined, uri: string): string;
1
+ export declare function getParam(name: string): boolean | string;
2
+ export declare function resolveUrl(source: string | undefined, uri: string): string;
package/lib/utils.js ADDED
@@ -0,0 +1,36 @@
1
+ export function getParam(name) {
2
+ const url = new URL(window.location.href);
3
+ const param = url.searchParams.get(name);
4
+ if (param == null || param === "0" || param === "false")
5
+ return false;
6
+ if (param === "")
7
+ return true;
8
+ return param;
9
+ }
10
+ export function resolveUrl(source, uri) {
11
+ if (uri === undefined) {
12
+ return uri;
13
+ }
14
+ if (uri.startsWith("./")) {
15
+ return uri;
16
+ }
17
+ if (uri.startsWith("http")) {
18
+ return uri;
19
+ }
20
+ if (source === undefined) {
21
+ return uri;
22
+ }
23
+ const pathIndex = source.lastIndexOf("/");
24
+ if (pathIndex >= 0) {
25
+ // Take the source uri as the base path
26
+ const basePath = source.substring(0, pathIndex + 1);
27
+ // make sure we don't have double slashes
28
+ while (basePath.endsWith("/") && uri.startsWith("/"))
29
+ uri = uri.substring(1);
30
+ // Append the relative uri
31
+ const newUri = basePath + uri;
32
+ // newUri = new URL(newUri, globalThis.location.href).href;
33
+ return newUri;
34
+ }
35
+ return uri;
36
+ }
package/package.json CHANGED
@@ -1,20 +1,48 @@
1
1
  {
2
2
  "name": "@needle-tools/gltf-progressive",
3
- "version": "1.0.0-alpha.1",
4
- "description": "",
3
+ "version": "1.0.0-alpha.11",
4
+ "description": "three.js support for loading glTF or GLB files that contain progressive loading data",
5
5
  "homepage": "https://needle.tools",
6
6
  "author": {
7
7
  "name": "Needle",
8
8
  "email": "hi@needle.tools",
9
9
  "url": "https://needle.tools/"
10
10
  },
11
+ "readme": "README.md",
12
+ "keywords": [
13
+ "three.js",
14
+ "gltf",
15
+ "glb",
16
+ "progressive",
17
+ "loading",
18
+ "needle",
19
+ "engine",
20
+ "webgl",
21
+ "optimization"
22
+ ],
23
+ "main": "./lib/index.js",
24
+ "exports": {
25
+ ".": {
26
+ "import": "./lib/index.js",
27
+ "require": "./gltf-progressive.js"
28
+ }
29
+ },
11
30
  "peerDependencies": {
12
31
  "three": ">= 0.160.0"
13
32
  },
14
33
  "devDependencies": {
15
34
  "@types/three": "0.162.0",
16
35
  "three": ">= 0.160.0",
17
- "vite": "<= 4.3.9"
36
+ "vite": "<= 4.3.9",
37
+ "@stylistic/eslint-plugin-ts": "^1.5.4",
38
+ "@typescript-eslint/eslint-plugin": "^6.2.0",
39
+ "@typescript-eslint/parser": "^6.2.0",
40
+ "eslint": "^8.56.0",
41
+ "eslint-plugin-import": "^2.29.1",
42
+ "eslint-plugin-no-secrets": "^0.8.9",
43
+ "eslint-plugin-no-unsanitized": "^4.0.2",
44
+ "eslint-plugin-promise": "^6.1.1",
45
+ "eslint-plugin-xss": "^0.1.12"
18
46
  },
19
- "types": "./types/index.d.ts"
47
+ "types": "./lib/index.d.ts"
20
48
  }