@tonybfox/threejs-tools 1.0.5 → 1.0.6

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 (41) hide show
  1. package/dist/asset-loader/index.cjs +3 -417
  2. package/dist/asset-loader/index.mjs +1 -6
  3. package/dist/camera/index.cjs +1 -393
  4. package/dist/camera/index.mjs +1 -6
  5. package/dist/chunk-4O4ENFL7.mjs +83 -0
  6. package/dist/chunk-55YVGK52.mjs +1 -0
  7. package/dist/chunk-B75TYEOO.mjs +44 -0
  8. package/dist/chunk-EQRUOKFV.mjs +1 -0
  9. package/dist/chunk-JRJBW66X.mjs +1 -0
  10. package/dist/chunk-OJFYE56U.mjs +1 -0
  11. package/dist/chunk-UJF4S4J3.mjs +1 -0
  12. package/dist/chunk-WZ4X7GQ2.mjs +1 -0
  13. package/dist/chunk-Z5VL3O6M.mjs +43 -0
  14. package/dist/compass/index.cjs +3 -304
  15. package/dist/compass/index.mjs +1 -6
  16. package/dist/grid/index.cjs +3 -159
  17. package/dist/grid/index.mjs +1 -6
  18. package/dist/index.cjs +7 -5406
  19. package/dist/index.mjs +1 -384
  20. package/dist/measurements/index.cjs +1 -1197
  21. package/dist/measurements/index.mjs +1 -8
  22. package/dist/sunlight/index.cjs +1 -440
  23. package/dist/sunlight/index.d.mts +19 -0
  24. package/dist/sunlight/index.d.ts +19 -0
  25. package/dist/sunlight/index.mjs +1 -6
  26. package/dist/terrain/index.cjs +1 -422
  27. package/dist/terrain/index.mjs +1 -6
  28. package/dist/transform-controls/index.cjs +1 -1586
  29. package/dist/transform-controls/index.mjs +1 -12
  30. package/dist/view-helper/index.cjs +1 -435
  31. package/dist/view-helper/index.mjs +1 -6
  32. package/package.json +1 -1
  33. package/dist/chunk-2CDI7ORN.mjs +0 -163
  34. package/dist/chunk-FBTT6MU6.mjs +0 -386
  35. package/dist/chunk-IAZH4OHC.mjs +0 -399
  36. package/dist/chunk-LUE7VHLK.mjs +0 -422
  37. package/dist/chunk-OZKJ3GAD.mjs +0 -1160
  38. package/dist/chunk-W4DAAAW6.mjs +0 -404
  39. package/dist/chunk-XA7OKYSM.mjs +0 -357
  40. package/dist/chunk-YMMLYGHV.mjs +0 -1578
  41. package/dist/chunk-ZNGFST7K.mjs +0 -348
@@ -1,422 +0,0 @@
1
- // packages/asset-loader/src/AssetLoader.ts
2
- import * as THREE from "three";
3
- import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
4
- import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
5
- import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader.js";
6
- import { USDLoader } from "three/examples/jsm/loaders/USDLoader.js";
7
- import { ColladaLoader } from "three/examples/jsm/loaders/ColladaLoader.js";
8
- import { STLLoader } from "three/examples/jsm/loaders/STLLoader.js";
9
- import { PLYLoader } from "three/examples/jsm/loaders/PLYLoader.js";
10
- import { ThreeMFLoader } from "three/examples/jsm/loaders/3MFLoader.js";
11
- var AssetLoader = class extends THREE.EventDispatcher {
12
- constructor() {
13
- super();
14
- this.cache = /* @__PURE__ */ new Map();
15
- this.placeholder = null;
16
- this.loadedAsset = null;
17
- this.lowResAsset = null;
18
- this.errorColor = 16729156;
19
- this.errorOpacity = 0.5;
20
- this.gltfLoader = new GLTFLoader();
21
- this.fbxLoader = new FBXLoader();
22
- this.objLoader = new OBJLoader();
23
- this.usdLoader = new USDLoader();
24
- this.colladaLoader = new ColladaLoader();
25
- this.stlLoader = new STLLoader();
26
- this.plyLoader = new PLYLoader();
27
- this.threeMFLoader = new ThreeMFLoader();
28
- }
29
- /**
30
- * Create a placeholder cube with shader effect
31
- */
32
- createPlaceholder(size, color = 5227511, opacity = 0.3) {
33
- const [width, height, depth] = size;
34
- const geometry = new THREE.BoxGeometry(width, height, depth);
35
- const material = new THREE.ShaderMaterial({
36
- side: THREE.DoubleSide,
37
- depthWrite: false,
38
- blending: THREE.AdditiveBlending,
39
- transparent: true,
40
- uniforms: {
41
- color: { value: new THREE.Color(color) },
42
- opacity: { value: opacity },
43
- fillProgress: { value: 0 },
44
- time: { value: 0 },
45
- isError: { value: 0 },
46
- yMin: { value: -height / 2 },
47
- yMax: { value: height / 2 }
48
- },
49
- vertexShader: `
50
- varying vec3 vPosition;
51
- void main() {
52
- vPosition = position;
53
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
54
- }
55
- `,
56
- fragmentShader: `
57
- uniform vec3 color;
58
- uniform float opacity;
59
- uniform float fillProgress;
60
- uniform float time;
61
- uniform float isError;
62
- uniform float yMin;
63
- uniform float yMax;
64
- varying vec3 vPosition;
65
-
66
- void main() {
67
- float normalizedY = (vPosition.y - yMin) / (yMax - yMin); // Normalize based on actual geometry bounds
68
- float alpha = opacity;
69
-
70
- // Create fill-up effect
71
- if (normalizedY > fillProgress) {
72
- alpha *= 0.1; // Reduce opacity for unfilled parts
73
- }
74
-
75
- // Error state effects
76
- if (isError > 0.5) {
77
- // Add pulsing effect for error state
78
- float pulse = 0.5 + 0.5 * sin(time * 4.0);
79
- alpha *= (0.3 + 0.4 * pulse);
80
-
81
- // Add error pattern
82
- float stripe = sin(vPosition.y * 20.0 + time * 2.0);
83
- alpha *= (0.7 + 0.3 * step(0.0, stripe));
84
- }
85
-
86
- // Add edge glow
87
- vec3 viewDirection = normalize(cameraPosition - vPosition);
88
- float edgeIntensity = pow(1.0 - abs(dot(viewDirection, normalize(vPosition))), 2.0);
89
-
90
- vec3 finalColor = color + edgeIntensity * 0.5;
91
- gl_FragColor = vec4(finalColor, alpha);
92
- }
93
- `
94
- });
95
- const mesh = new THREE.Mesh(geometry, material);
96
- this.positionAssetAtBottomCenter(mesh);
97
- return mesh;
98
- }
99
- /**
100
- * Update placeholder fill progress based on loading progress
101
- */
102
- updatePlaceholder(progress) {
103
- if (this.placeholder && this.placeholder instanceof THREE.Mesh) {
104
- const material = this.placeholder.material;
105
- if (material.uniforms && material.uniforms.fillProgress) {
106
- material.uniforms.fillProgress.value = progress;
107
- }
108
- }
109
- }
110
- /**
111
- * Set placeholder to error state with configurable color and opacity
112
- */
113
- setPlaceholderError() {
114
- if (this.placeholder && this.placeholder instanceof THREE.Mesh) {
115
- const material = this.placeholder.material;
116
- if (material.uniforms) {
117
- if (material.uniforms.color) {
118
- material.uniforms.color.value = new THREE.Color(this.errorColor);
119
- }
120
- if (material.uniforms.opacity) {
121
- material.uniforms.opacity.value = this.errorOpacity;
122
- }
123
- if (material.uniforms.fillProgress) {
124
- material.uniforms.fillProgress.value = 0;
125
- }
126
- if (material.uniforms.isError) {
127
- material.uniforms.isError.value = 1;
128
- }
129
- }
130
- }
131
- }
132
- /**
133
- * Update placeholder animation time (call this in your render loop)
134
- */
135
- updatePlaceholderAnimation(deltaTime) {
136
- if (this.placeholder && this.placeholder instanceof THREE.Mesh) {
137
- const material = this.placeholder.material;
138
- if (material.uniforms && material.uniforms.time) {
139
- material.uniforms.time.value += deltaTime;
140
- }
141
- }
142
- }
143
- /**
144
- * Reposition an asset so that its bottom-center sits at the local origin.
145
- */
146
- positionAssetAtBottomCenter(object) {
147
- object.updateMatrixWorld(true);
148
- const boundingBox = new THREE.Box3().setFromObject(object);
149
- if (boundingBox.isEmpty()) {
150
- return;
151
- }
152
- const center = boundingBox.getCenter(new THREE.Vector3());
153
- const bottomCenter = new THREE.Vector3(
154
- center.x,
155
- boundingBox.min.y - 0.01,
156
- center.z
157
- );
158
- if (!Number.isFinite(bottomCenter.x) || !Number.isFinite(bottomCenter.y) || !Number.isFinite(bottomCenter.z)) {
159
- return;
160
- }
161
- object.position.sub(bottomCenter);
162
- object.userData.bottomCenterOffset = bottomCenter;
163
- object.updateMatrixWorld(true);
164
- }
165
- ensureBottomCenterOffset(object) {
166
- const offset = object.userData.bottomCenterOffset;
167
- if (offset instanceof THREE.Vector3) {
168
- return offset;
169
- }
170
- if (offset && typeof offset === "object") {
171
- const {
172
- x = 0,
173
- y = 0,
174
- z = 0
175
- } = offset;
176
- const normalized = new THREE.Vector3(x ?? 0, y ?? 0, z ?? 0);
177
- object.userData.bottomCenterOffset = normalized;
178
- return normalized;
179
- }
180
- return null;
181
- }
182
- normalizeBottomCenterData(object) {
183
- const hasOffset = this.ensureBottomCenterOffset(object) !== null;
184
- object.children.forEach((child) => this.normalizeBottomCenterData(child));
185
- return hasOffset;
186
- }
187
- /**
188
- * Load an asset with the specified options
189
- */
190
- async load(options) {
191
- const {
192
- type,
193
- url,
194
- size,
195
- lowResUrl,
196
- enableCaching = true,
197
- disablePlaceholder = false,
198
- placeholderColor = 5227511,
199
- placeholderOpacity = 0.4,
200
- errorColor = 16729156,
201
- errorOpacity = 0.5
202
- } = options;
203
- if (enableCaching && this.cache.has(url)) {
204
- const cachedClone = this.cache.get(url).clone(true);
205
- const hasOffset = this.normalizeBottomCenterData(cachedClone);
206
- if (!hasOffset) {
207
- this.positionAssetAtBottomCenter(cachedClone);
208
- } else {
209
- cachedClone.updateMatrixWorld(true);
210
- }
211
- this.loadedAsset = cachedClone;
212
- this.dispatchEvent({ type: "loaded", asset: cachedClone });
213
- return cachedClone;
214
- }
215
- this.errorColor = errorColor;
216
- this.errorOpacity = errorOpacity;
217
- if (size && !disablePlaceholder) {
218
- this.placeholder = this.createPlaceholder(
219
- size,
220
- placeholderColor,
221
- placeholderOpacity
222
- );
223
- this.dispatchEvent({
224
- type: "placeholderCreated",
225
- placeholder: this.placeholder
226
- });
227
- }
228
- try {
229
- if (lowResUrl) {
230
- const lowRes = await this.loadModel(type, lowResUrl, true);
231
- this.lowResAsset = lowRes;
232
- this.dispatchEvent({ type: "lowResLoaded", lowRes });
233
- }
234
- const asset = await this.loadModel(type, url, false);
235
- this.loadedAsset = asset;
236
- if (enableCaching) {
237
- const cacheEntry = asset.clone(true);
238
- const hasOffset = this.normalizeBottomCenterData(cacheEntry);
239
- if (!hasOffset) {
240
- this.positionAssetAtBottomCenter(cacheEntry);
241
- } else {
242
- cacheEntry.updateMatrixWorld(true);
243
- }
244
- this.cache.set(url, cacheEntry);
245
- }
246
- this.dispatchEvent({ type: "loaded", asset });
247
- return asset;
248
- } catch (error) {
249
- this.setPlaceholderError();
250
- this.dispatchEvent({ type: "error", error });
251
- throw error;
252
- }
253
- }
254
- /**
255
- * Load a model based on type
256
- */
257
- loadModel(type, url, isLowRes) {
258
- return new Promise((resolve, reject) => {
259
- const onProgress = (event) => {
260
- let percentage = -1;
261
- if (event.lengthComputable && event.total > 0 && event.loaded <= event.total) {
262
- percentage = event.loaded / event.total * 100;
263
- }
264
- this.dispatchEvent({
265
- type: "progress",
266
- loaded: event.loaded,
267
- total: event.total,
268
- percentage
269
- });
270
- if (!isLowRes && percentage >= 0) {
271
- this.updatePlaceholder(percentage / 100);
272
- }
273
- };
274
- const onError = (error) => {
275
- reject(error);
276
- };
277
- switch (type) {
278
- case "gltf":
279
- this.gltfLoader.load(
280
- url,
281
- (gltf) => {
282
- const scene = gltf.scene;
283
- this.positionAssetAtBottomCenter(scene);
284
- resolve(scene);
285
- },
286
- onProgress,
287
- onError
288
- );
289
- break;
290
- case "fbx":
291
- this.fbxLoader.load(
292
- url,
293
- (fbx) => {
294
- this.positionAssetAtBottomCenter(fbx);
295
- resolve(fbx);
296
- },
297
- onProgress,
298
- onError
299
- );
300
- break;
301
- case "obj":
302
- this.objLoader.load(
303
- url,
304
- (obj) => {
305
- this.positionAssetAtBottomCenter(obj);
306
- resolve(obj);
307
- },
308
- onProgress,
309
- onError
310
- );
311
- break;
312
- case "usd":
313
- case "usdz":
314
- this.usdLoader.load(
315
- url,
316
- (usd) => {
317
- this.positionAssetAtBottomCenter(usd);
318
- resolve(usd);
319
- },
320
- onProgress,
321
- onError
322
- );
323
- break;
324
- case "dae":
325
- this.colladaLoader.load(
326
- url,
327
- (collada) => {
328
- const scene = collada.scene;
329
- this.positionAssetAtBottomCenter(scene);
330
- resolve(scene);
331
- },
332
- onProgress,
333
- onError
334
- );
335
- break;
336
- case "stl":
337
- this.stlLoader.load(
338
- url,
339
- (geometry) => {
340
- const material = new THREE.MeshStandardMaterial({
341
- color: 8947848
342
- });
343
- const mesh = new THREE.Mesh(geometry, material);
344
- this.positionAssetAtBottomCenter(mesh);
345
- resolve(mesh);
346
- },
347
- onProgress,
348
- onError
349
- );
350
- break;
351
- case "ply":
352
- this.plyLoader.load(
353
- url,
354
- (geometry) => {
355
- const material = new THREE.MeshStandardMaterial({
356
- vertexColors: true
357
- });
358
- const mesh = new THREE.Mesh(geometry, material);
359
- this.positionAssetAtBottomCenter(mesh);
360
- resolve(mesh);
361
- },
362
- onProgress,
363
- onError
364
- );
365
- break;
366
- case "3mf":
367
- this.threeMFLoader.load(
368
- url,
369
- (object) => {
370
- this.positionAssetAtBottomCenter(object);
371
- resolve(object);
372
- },
373
- onProgress,
374
- onError
375
- );
376
- break;
377
- default:
378
- reject(new Error(`Unsupported asset type: ${type}`));
379
- }
380
- });
381
- }
382
- /**
383
- * Get the placeholder object
384
- */
385
- getPlaceholder() {
386
- return this.placeholder;
387
- }
388
- /**
389
- * Get the loaded asset
390
- */
391
- getAsset() {
392
- return this.loadedAsset;
393
- }
394
- /**
395
- * Get the low-res asset
396
- */
397
- getLowResAsset() {
398
- return this.lowResAsset;
399
- }
400
- /**
401
- * Clear the cache
402
- */
403
- clearCache() {
404
- this.cache.clear();
405
- }
406
- /**
407
- * Remove an item from cache
408
- */
409
- removeFromCache(url) {
410
- this.cache.delete(url);
411
- }
412
- /**
413
- * Get cache size
414
- */
415
- getCacheSize() {
416
- return this.cache.size;
417
- }
418
- };
419
-
420
- export {
421
- AssetLoader
422
- };