@needle-tools/gltf-progressive 1.2.0-alpha.2 → 1.2.0-alpha.4

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 CHANGED
@@ -4,7 +4,23 @@ All notable changes to this package will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [1.2.0-alpha] - 2023-06-06
7
+ ## [1.2.0-alpha.4] - 2023-06-07
8
+ - add: `useRaycastMeshes` method:
9
+ ```ts
10
+ // call to enable raycasting with low poly raycast meshes
11
+ // this can be done once in your project
12
+ useRaycastMeshes(true);
13
+
14
+ // then use the raycaster as usual
15
+ const raycaster = new Raycaster();
16
+ raycaster.setFromCamera(mouse, camera);
17
+ const intersects = raycaster.intersectObjects(scene.children, true);
18
+
19
+ // call to disable raycasting with low polwy meshes
20
+ useRaycastMeshes(false);
21
+ ```
22
+
23
+ ## [1.2.0-alpha.3] - 2023-06-06
8
24
  - add: automatically load the highest LOD first to show a slightly better quality level as soon as possible
9
25
  - fix: improve Texture LOD selection by taking LOD level height into account
10
26
  - fix: correctly assign LOD level information to initially loaded texture
package/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Support for loading of glTF or GLB files with progressive mesh or texture data for three.js based engines.
4
4
 
5
+ ## Features
6
+ - Automatic loading of mesh and texture LODs.
7
+ - High quality LOD levels are loaded on demand based on screen density.
8
+ - Use low-poly LOD meshes for raycasting which allows the usage of high-poly meshes with smooth interaction
5
9
 
6
10
 
7
11
  ## Examples
@@ -3,6 +3,7 @@
3
3
 
4
4
  <head>
5
5
  <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
7
  <title>Threejs Progressive Loading</title>
7
8
  <style>
8
9
  body {
@@ -14,8 +15,7 @@
14
15
  "imports": {
15
16
  "three": "https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js",
16
17
  "three/addons/": "https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/",
17
- "three/examples/": "https://cdn.jsdelivr.net/npm/three@latest/examples/",
18
- "@needle-engine/gltf-progressive": "https://www.unpkg.com/@needle-tools/gltf-progressive@latest"
18
+ "three/examples/": "https://cdn.jsdelivr.net/npm/three@latest/examples/"
19
19
  }
20
20
  }
21
21
  </script>
@@ -2,7 +2,9 @@ import * as THREE from 'three';
2
2
  import { EXRLoader } from 'three/addons/loaders/EXRLoader.js';
3
3
  import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
4
4
  import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
5
- import { useNeedleProgressive, } from "@needle-engine/gltf-progressive"
5
+ import { useNeedleProgressive, getRaycastMesh, useRaycastMeshes } from "https://www.unpkg.com/@needle-tools/gltf-progressive@latest"
6
+ import { Pane } from 'https://cdn.jsdelivr.net/npm/tweakpane@4.0.3/dist/tweakpane.min.js';
7
+
6
8
 
7
9
  const scene = new THREE.Scene();
8
10
  scene.background = new THREE.Color(0x555555);
@@ -10,7 +12,7 @@ const renderer = new THREE.WebGLRenderer();
10
12
  renderer.setSize(window.innerWidth, window.innerHeight);
11
13
  document.body.appendChild(renderer.domElement);
12
14
 
13
- const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
15
+ const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 200);
14
16
 
15
17
 
16
18
  window.addEventListener('resize', () => {
@@ -20,10 +22,10 @@ window.addEventListener('resize', () => {
20
22
  });
21
23
 
22
24
  const orbit = new OrbitControls(camera, renderer.domElement);
23
- orbit.target = new THREE.Vector3(0, 14, 0);
24
- camera.position.x = 20;
25
- camera.position.y = 20.5;
26
- camera.position.z = 20.8;
25
+ orbit.target = new THREE.Vector3(0, .5, 0);
26
+ camera.position.x = .5;
27
+ camera.position.y = 1.3;
28
+ camera.position.z = 2;
27
29
 
28
30
  const grid = new THREE.GridHelper(50, 50, 0x444444, 0x666666);
29
31
  scene.add(grid);
@@ -54,23 +56,95 @@ new EXRLoader().load(environmentTextureUrl, texture => {
54
56
 
55
57
 
56
58
 
57
- // Integrate @needle-tools/gltf-progressive
58
- // This is the model we want to load
59
- const url = "https://engine.needle.tools/demos/gltf-progressive/assets/church/model.glb";
59
+ const modelUrls = [
60
+ "https://engine.needle.tools/demos/gltf-progressive/assets/putti gruppe/model.glb",
61
+ "https://engine.needle.tools/demos/gltf-progressive/assets/robot/model.glb",
62
+ "https://engine.needle.tools/demos/gltf-progressive/assets/vase/model.glb",
63
+ "https://engine.needle.tools/demos/gltf-progressive/assets/jupiter_und_ganymed/model.glb",
64
+ "https://engine.needle.tools/demos/gltf-progressive/assets/church/model.glb",
65
+ ]
66
+ let currentUrl = "";
67
+ /** @type {null | THREE.Scene} */
68
+ let currentScene = null;
69
+ let wireframe = false;
70
+
71
+ function loadScene() {
72
+ let currentIndex = modelUrls.indexOf(currentUrl);
73
+ currentIndex += 1;
74
+ if (currentIndex >= modelUrls.length) {
75
+ currentIndex = 0;
76
+ }
77
+ const url = modelUrls[currentIndex];
78
+ currentUrl = url;
79
+ wireframe = false;
80
+
81
+ // Integrate @needle-tools/gltf-progressive
82
+ // Create a new GLTFLoader instance
83
+ const gltfLoader = new GLTFLoader();
84
+ /** Call this method to register the progressive loader */
85
+ useNeedleProgressive(url, renderer, gltfLoader)
86
+
87
+ // just call the load method as usual
88
+ gltfLoader.load(url, gltf => {
89
+ // we're basically just adding our glTF to the scene here
90
+ // the rest of the code is just for the demo
91
+ console.log(gltf)
92
+ if (currentUrl != url) return;
93
+ currentScene?.removeFromParent();
94
+ currentScene = gltf.scene;
95
+ scene.add(gltf.scene)
96
+ gltf.scene.position.y += .01;
97
+
98
+ // the church is huge - scaling it down so we don't have a big difference between the models
99
+ if (url.includes("church")) {
100
+ gltf.scene.scale.multiplyScalar(.1);
101
+ }
102
+ })
103
+ }
104
+ loadScene();
105
+
106
+
107
+ useRaycastMeshes();
108
+ const raycaster = new THREE.Raycaster();
109
+ raycaster.params.Line.threshold = 0;
110
+ window.addEventListener("click", evt => {
111
+ const mousePos = {
112
+ x: (evt.clientX / window.innerWidth) * 2 - 1,
113
+ y: -(evt.clientY / window.innerHeight) * 2 + 1
114
+ }
115
+ raycaster.setFromCamera(mousePos, camera);
116
+ const hits = raycaster.intersectObjects(scene.children, true);
117
+ if (hits?.length) {
118
+ const obj = hits[0].object;
119
+ const raycastMesh = getRaycastMesh(obj);
120
+ if (raycastMesh) {
121
+ const newMesh = new THREE.Mesh(raycastMesh, new THREE.MeshBasicMaterial({ color: 0xffddff, wireframe: true, transparent: true, opacity: .5, depthTest: false }));
122
+ newMesh.matrix.copy(obj.matrixWorld);
123
+ newMesh.matrixAutoUpdate = false;
124
+ scene.add(newMesh);
125
+ setTimeout(() => {
126
+ newMesh.removeFromParent();
127
+ }, 1000)
128
+ }
129
+ }
130
+ })
60
131
 
61
- const gltfLoader = new GLTFLoader();
62
132
 
63
- /**
64
- * Call this method to register the progressive loader
65
- */
66
- useNeedleProgressive(url, renderer, gltfLoader)
67
133
 
68
- // just call the load method as usual
69
- gltfLoader.load(url, gltf => {
70
- console.log(gltf)
71
- scene.add(gltf.scene)
72
- gltf.scene.position.y += .95;
73
- })
74
134
 
75
135
 
136
+ const pane = new Pane();
137
+ pane.addButton({
138
+ title: 'Change Scene',
139
+ }).on('click', loadScene);
76
140
 
141
+ pane.addButton({
142
+ title: 'Toggle Wireframe',
143
+ }).on('click', () => {
144
+ wireframe = !wireframe;
145
+ scene.traverse(child => {
146
+ if (child instanceof THREE.Mesh) {
147
+ child.material.wireframe = wireframe;
148
+ }
149
+ })
150
+ });