@tonybfox/threejs-tools 1.0.7 → 1.0.8
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/README.md +95 -26
- package/dist/asset-loader/index.cjs +2 -2
- package/dist/asset-loader/index.mjs +1 -1
- package/dist/camera/index.cjs +1 -1
- package/dist/camera/index.d.mts +2 -2
- package/dist/camera/index.d.ts +2 -2
- package/dist/camera/index.mjs +1 -1
- package/dist/chunk-MJRTSO3X.mjs +1 -0
- package/dist/chunk-RDWDUKW6.mjs +1 -0
- package/dist/{chunk-B75TYEOO.mjs → chunk-WVTKB6A6.mjs} +2 -2
- package/dist/index.cjs +3 -3
- package/dist/index.d.mts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.mjs +1 -1
- package/dist/measurements/index.cjs +1 -1
- package/dist/measurements/index.d.mts +1 -1
- package/dist/measurements/index.d.ts +1 -1
- package/dist/measurements/index.mjs +1 -1
- package/package.json +5 -5
- package/dist/chunk-JRJBW66X.mjs +0 -1
- package/dist/chunk-OJFYE56U.mjs +0 -1
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
A collection of utilities and tools for Three.js development, organized as a monorepo with separate packages for different functionalities. The root `@tonybfox/threejs-tools` package now bundles every tool so you can install a single npm package while still importing submodules (for example `@tonybfox/threejs-tools/camera` or `@tonybfox/threejs-tools/terrain`).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Packages
|
|
6
6
|
|
|
7
|
-
- **[@tonybfox/threejs-camera](
|
|
8
|
-
- **[@tonybfox/threejs-grid](
|
|
9
|
-
- **[@tonybfox/threejs-measurements](
|
|
10
|
-
- **[@tonybfox/threejs-asset-loader](
|
|
7
|
+
- **[@tonybfox/threejs-camera](https://github.com/tonybfox/threejs-tools/blob/main/examples/packages/camera/)** - Camera utilities and controls
|
|
8
|
+
- **[@tonybfox/threejs-grid](https://github.com/tonybfox/threejs-tools/blob/main/examples/packages/grid/)** - Infinite grid component
|
|
9
|
+
- **[@tonybfox/threejs-measurements](https://github.com/tonybfox/threejs-tools/blob/main/examples/packages/measurements/)** - Measurement tools for 3D scenes
|
|
10
|
+
- **[@tonybfox/threejs-asset-loader](https://github.com/tonybfox/threejs-tools/blob/main/example/packages/asset-loader/)** - Universal asset loader with progress tracking and caching
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Prerequisites
|
|
13
13
|
|
|
14
14
|
Make sure you have the following installed on your system:
|
|
15
15
|
|
|
@@ -22,7 +22,7 @@ If you don't have pnpm installed, you can install it globally:
|
|
|
22
22
|
npm install -g pnpm
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## Installation
|
|
26
26
|
|
|
27
27
|
1. **Clone the repository:**
|
|
28
28
|
|
|
@@ -39,7 +39,7 @@ npm install -g pnpm
|
|
|
39
39
|
|
|
40
40
|
This will install all dependencies for the root workspace and all packages.
|
|
41
41
|
|
|
42
|
-
##
|
|
42
|
+
## Building
|
|
43
43
|
|
|
44
44
|
### Build the publishable bundle
|
|
45
45
|
|
|
@@ -81,7 +81,7 @@ To clean all build outputs:
|
|
|
81
81
|
pnpm clean
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
##
|
|
84
|
+
## Running Examples
|
|
85
85
|
|
|
86
86
|
The project includes interactive examples demonstrating each package's functionality.
|
|
87
87
|
|
|
@@ -113,9 +113,9 @@ pnpm build
|
|
|
113
113
|
pnpm preview
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
##
|
|
116
|
+
## Examples Overview
|
|
117
117
|
|
|
118
|
-
###
|
|
118
|
+
### Grid Package Example
|
|
119
119
|
|
|
120
120
|
- **Location:** `/examples/grid/`
|
|
121
121
|
- **Features:**
|
|
@@ -125,7 +125,7 @@ pnpm preview
|
|
|
125
125
|
- Grid positioning and rotation
|
|
126
126
|
- **Controls:** Use the control panel to modify grid properties
|
|
127
127
|
|
|
128
|
-
###
|
|
128
|
+
### Camera Package Example
|
|
129
129
|
|
|
130
130
|
- **Location:** `/examples/camera/`
|
|
131
131
|
- **Features:**
|
|
@@ -136,7 +136,7 @@ pnpm preview
|
|
|
136
136
|
- Real-time camera info display
|
|
137
137
|
- **Controls:** Click buttons to change camera views and modes
|
|
138
138
|
|
|
139
|
-
###
|
|
139
|
+
### Measurements Package Example
|
|
140
140
|
|
|
141
141
|
- **Location:** `/examples/measurements/`
|
|
142
142
|
- **Features:**
|
|
@@ -148,7 +148,7 @@ pnpm preview
|
|
|
148
148
|
- Interactive labels
|
|
149
149
|
- **Usage:** Select a tool and click in the 3D scene to measure
|
|
150
150
|
|
|
151
|
-
###
|
|
151
|
+
### Asset Loader Package Example
|
|
152
152
|
|
|
153
153
|
- **Location:** `/examples/asset-loader/`
|
|
154
154
|
- **Features:**
|
|
@@ -160,7 +160,76 @@ pnpm preview
|
|
|
160
160
|
- Event-driven architecture
|
|
161
161
|
- **Usage:** Use the control panel to create placeholders and see the loading system in action
|
|
162
162
|
|
|
163
|
-
###
|
|
163
|
+
### Outline Package Example
|
|
164
|
+
|
|
165
|
+
- **Location:** `/examples/outline/`
|
|
166
|
+
- **Features:**
|
|
167
|
+
- Mesh mode with inverted hull + edge lines (no post-processing)
|
|
168
|
+
- Post-processing mode with ID buffer edge detection
|
|
169
|
+
- Auto-updating outlines for animated objects
|
|
170
|
+
- Smart exclusions for helpers and gizmos
|
|
171
|
+
- **Usage:** Toggle outline modes and settings to compare visual styles
|
|
172
|
+
|
|
173
|
+
### Terrain Package Example
|
|
174
|
+
|
|
175
|
+
- **Location:** `/examples/terrain/`
|
|
176
|
+
- **Features:**
|
|
177
|
+
- Real elevation data terrain mesh generation
|
|
178
|
+
- Configurable resolution and elevation scaling
|
|
179
|
+
- Optional imagery overlay and demo mode
|
|
180
|
+
- Loading events for progress feedback
|
|
181
|
+
- **Usage:** Adjust location and terrain settings to update the mesh
|
|
182
|
+
|
|
183
|
+
### Transform Controls Package Example
|
|
184
|
+
|
|
185
|
+
- **Location:** `/examples/transform-controls/`
|
|
186
|
+
- **Features:**
|
|
187
|
+
- Translate, rotate, and scale gizmo controls
|
|
188
|
+
- Axis and plane constraints
|
|
189
|
+
- World vs local space modes
|
|
190
|
+
- Snap support for precise transforms
|
|
191
|
+
- **Usage:** Manipulate objects with the gizmo and toggle modes
|
|
192
|
+
|
|
193
|
+
### View Helper Package Example
|
|
194
|
+
|
|
195
|
+
- **Location:** `/examples/view-helper/`
|
|
196
|
+
- **Features:**
|
|
197
|
+
- Clickable axis gizmo for quick camera reorientation
|
|
198
|
+
- Configurable size, colors, and labels
|
|
199
|
+
- Smooth animated transitions
|
|
200
|
+
- **Usage:** Click axis labels to snap the camera to preset views
|
|
201
|
+
|
|
202
|
+
### Sun Light Package Example
|
|
203
|
+
|
|
204
|
+
- **Location:** `/examples/sunlight/`
|
|
205
|
+
- **Features:**
|
|
206
|
+
- Real-time sun position from latitude, longitude, and date
|
|
207
|
+
- Weather presets for color and intensity
|
|
208
|
+
- Sunrise/sunset color transitions based on solar altitude
|
|
209
|
+
- Optional system clock sync for live daylight simulation
|
|
210
|
+
- Directional light helper and scene objects to show shadows
|
|
211
|
+
- **Usage:** Adjust the control panel to explore lighting scenarios or enable real-time mode
|
|
212
|
+
|
|
213
|
+
### Compass Package Example
|
|
214
|
+
|
|
215
|
+
- **Location:** `/examples/compass/`
|
|
216
|
+
- **Features:**
|
|
217
|
+
- Stylized compass gizmo with heading, latitude, and longitude
|
|
218
|
+
- Declination slider with live heading updates
|
|
219
|
+
- Location presets plus manual coordinate entry
|
|
220
|
+
- Optional dynamic north resolver
|
|
221
|
+
- **Usage:** Move the compass or adjust coordinates to see live updates
|
|
222
|
+
|
|
223
|
+
### Combined Scene Example
|
|
224
|
+
|
|
225
|
+
- **Location:** `/examples/combined-scene/`
|
|
226
|
+
- **Features:**
|
|
227
|
+
- Terrain, sun lighting, and compass overlay in one scene
|
|
228
|
+
- Optional Mapbox imagery overlay for terrain
|
|
229
|
+
- Interactive control panel for location and lighting
|
|
230
|
+
- **Usage:** Use the control panel to explore combined tool behavior
|
|
231
|
+
|
|
232
|
+
### Interactive Features
|
|
164
233
|
|
|
165
234
|
Each example includes:
|
|
166
235
|
|
|
@@ -170,7 +239,7 @@ Each example includes:
|
|
|
170
239
|
- **Real-time Updates:** Live parameter adjustment
|
|
171
240
|
- **Performance Monitoring:** Optional FPS and render statistics
|
|
172
241
|
|
|
173
|
-
###
|
|
242
|
+
### Example Development
|
|
174
243
|
|
|
175
244
|
#### Shared Utilities
|
|
176
245
|
|
|
@@ -198,7 +267,7 @@ Examples use Vite for development with:
|
|
|
198
267
|
- Three.js optimization
|
|
199
268
|
- Workspace linking for package imports
|
|
200
269
|
|
|
201
|
-
##
|
|
270
|
+
## Publishing to npm
|
|
202
271
|
|
|
203
272
|
Steps to publish the unified `threejs-tools` package:
|
|
204
273
|
|
|
@@ -211,7 +280,7 @@ The published package exposes:
|
|
|
211
280
|
- `@tonybfox/threejs-tools` – combined exports (tree-shakeable)
|
|
212
281
|
- `@tonybfox/threejs-tools/<tool>` – direct submodule imports for each tool (`camera`, `terrain`, `measurements`, etc.)
|
|
213
282
|
|
|
214
|
-
##
|
|
283
|
+
## Development Workflow
|
|
215
284
|
|
|
216
285
|
### Working on packages
|
|
217
286
|
|
|
@@ -234,7 +303,7 @@ The examples use workspace references (`workspace:*`), so your local changes wil
|
|
|
234
303
|
2. Add a `package.json` with the `@tonybfox/threejs-*` naming convention
|
|
235
304
|
3. The workspace will automatically include it
|
|
236
305
|
|
|
237
|
-
##
|
|
306
|
+
## Code Formatting
|
|
238
307
|
|
|
239
308
|
This project uses Prettier for code formatting:
|
|
240
309
|
|
|
@@ -246,7 +315,7 @@ pnpm format
|
|
|
246
315
|
pnpm format:check
|
|
247
316
|
```
|
|
248
317
|
|
|
249
|
-
##
|
|
318
|
+
## Project Structure
|
|
250
319
|
|
|
251
320
|
```
|
|
252
321
|
threejs-tools/
|
|
@@ -265,7 +334,7 @@ threejs-tools/
|
|
|
265
334
|
└── tsconfig.json # TypeScript configuration
|
|
266
335
|
```
|
|
267
336
|
|
|
268
|
-
##
|
|
337
|
+
## Scripts Reference
|
|
269
338
|
|
|
270
339
|
| Script | Description |
|
|
271
340
|
| --------------------- | -------------------------------------- |
|
|
@@ -276,7 +345,7 @@ threejs-tools/
|
|
|
276
345
|
| `pnpm format` | Format all files with Prettier |
|
|
277
346
|
| `pnpm format:check` | Check code formatting |
|
|
278
347
|
|
|
279
|
-
##
|
|
348
|
+
## Troubleshooting
|
|
280
349
|
|
|
281
350
|
### Common Issues
|
|
282
351
|
|
|
@@ -292,7 +361,7 @@ threejs-tools/
|
|
|
292
361
|
- Monitor memory usage with large scenes
|
|
293
362
|
- Use appropriate LOD for complex geometries
|
|
294
363
|
|
|
295
|
-
##
|
|
364
|
+
## Contributing
|
|
296
365
|
|
|
297
366
|
1. Fork the repository
|
|
298
367
|
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
@@ -304,11 +373,11 @@ threejs-tools/
|
|
|
304
373
|
8. Push to the branch (`git push origin feature/amazing-feature`)
|
|
305
374
|
9. Open a Pull Request
|
|
306
375
|
|
|
307
|
-
##
|
|
376
|
+
## License
|
|
308
377
|
|
|
309
378
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
310
379
|
|
|
311
|
-
##
|
|
380
|
+
## Issues & Support
|
|
312
381
|
|
|
313
382
|
If you encounter any issues or have questions:
|
|
314
383
|
|
|
@@ -318,4 +387,4 @@ If you encounter any issues or have questions:
|
|
|
318
387
|
|
|
319
388
|
---
|
|
320
389
|
|
|
321
|
-
Made with
|
|
390
|
+
Made with love for the Three.js community
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var H=Object.create;var u=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var D=(n,c)=>{for(var e in c)u(n,e,{get:c[e],enumerable:!0})},b=(n,c,e,t)=>{if(c&&typeof c=="object"||typeof c=="function")for(let a of O(c))!x.call(n,a)&&a!==e&&u(n,a,{get:()=>c[a],enumerable:!(t=M(c,a))||t.enumerable});return n};var B=(n,c,e)=>(e=n!=null?H(P(n)):{},b(c||!n||!n.__esModule?u(e,"default",{value:n,enumerable:!0}):e,n)),z=n=>b(u({},"__esModule",{value:!0}),n);var
|
|
1
|
+
"use strict";var H=Object.create;var u=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var D=(n,c)=>{for(var e in c)u(n,e,{get:c[e],enumerable:!0})},b=(n,c,e,t)=>{if(c&&typeof c=="object"||typeof c=="function")for(let a of O(c))!x.call(n,a)&&a!==e&&u(n,a,{get:()=>c[a],enumerable:!(t=M(c,a))||t.enumerable});return n};var B=(n,c,e)=>(e=n!=null?H(P(n)):{},b(c||!n||!n.__esModule?u(e,"default",{value:n,enumerable:!0}):e,n)),z=n=>b(u({},"__esModule",{value:!0}),n);var F={};D(F,{AssetLoader:()=>E});module.exports=z(F);var o=B(require("three")),y=require("three/examples/jsm/loaders/GLTFLoader.js"),v=require("three/examples/jsm/loaders/FBXLoader.js"),R=require("three/examples/jsm/loaders/OBJLoader.js"),L=require("three/examples/jsm/loaders/USDLoader.js"),T=require("three/examples/jsm/loaders/ColladaLoader.js"),g=require("three/examples/jsm/loaders/STLLoader.js"),C=require("three/examples/jsm/loaders/PLYLoader.js"),w=require("three/examples/jsm/loaders/3MFLoader.js"),E=class extends o.EventDispatcher{constructor(){super();this.cache=new Map;this.placeholder=null;this.loadedAsset=null;this.lowResAsset=null;this.errorColor=16729156;this.errorOpacity=.5;this.gltfLoader=new y.GLTFLoader,this.fbxLoader=new v.FBXLoader,this.objLoader=new R.OBJLoader,this.usdLoader=new L.USDLoader,this.colladaLoader=new T.ColladaLoader,this.stlLoader=new g.STLLoader,this.plyLoader=new C.PLYLoader,this.threeMFLoader=new w.ThreeMFLoader}createPlaceholder(e,t=5227511,a=.3){let[s,h,l]=e,p=new o.BoxGeometry(s,h,l),r=new o.ShaderMaterial({side:o.DoubleSide,depthWrite:!1,blending:o.AdditiveBlending,transparent:!0,uniforms:{color:{value:new o.Color(t)},opacity:{value:a},fillProgress:{value:0},time:{value:0},isError:{value:0},yMin:{value:-h/2},yMax:{value:h/2}},vertexShader:`
|
|
2
2
|
varying vec3 vPosition;
|
|
3
3
|
void main() {
|
|
4
4
|
vPosition = position;
|
|
@@ -41,4 +41,4 @@
|
|
|
41
41
|
vec3 finalColor = color + edgeIntensity * 0.5;
|
|
42
42
|
gl_FragColor = vec4(finalColor, alpha);
|
|
43
43
|
}
|
|
44
|
-
`}),i=new o.Mesh(
|
|
44
|
+
`}),i=new o.Mesh(p,r);return this.positionAssetAtBottomCenter(i),i}updatePlaceholder(e){if(this.placeholder&&this.placeholder instanceof o.Mesh){let t=this.placeholder.material;t.uniforms&&t.uniforms.fillProgress&&(t.uniforms.fillProgress.value=e)}}setPlaceholderError(){if(this.placeholder&&this.placeholder instanceof o.Mesh){let e=this.placeholder.material;e.uniforms&&(e.uniforms.color&&(e.uniforms.color.value=new o.Color(this.errorColor)),e.uniforms.opacity&&(e.uniforms.opacity.value=this.errorOpacity),e.uniforms.fillProgress&&(e.uniforms.fillProgress.value=0),e.uniforms.isError&&(e.uniforms.isError.value=1))}}updatePlaceholderAnimation(e){if(this.placeholder&&this.placeholder instanceof o.Mesh){let t=this.placeholder.material;t.uniforms&&t.uniforms.time&&(t.uniforms.time.value+=e)}}positionAssetAtBottomCenter(e){e.updateMatrixWorld(!0);let t=new o.Box3().setFromObject(e);if(t.isEmpty())return;let a=t.getCenter(new o.Vector3),s=new o.Vector3(a.x,t.min.y-.01,a.z);!Number.isFinite(s.x)||!Number.isFinite(s.y)||!Number.isFinite(s.z)||(e.position.sub(s),e.userData.bottomCenterOffset=s,e.updateMatrixWorld(!0))}ensureBottomCenterOffset(e){let t=e.userData.bottomCenterOffset;if(t instanceof o.Vector3)return t;if(t&&typeof t=="object"){let{x:a=0,y:s=0,z:h=0}=t,l=new o.Vector3(a??0,s??0,h??0);return e.userData.bottomCenterOffset=l,l}return null}normalizeBottomCenterData(e){let t=this.ensureBottomCenterOffset(e)!==null;return e.children.forEach(a=>this.normalizeBottomCenterData(a)),t}async load(e){let{type:t,url:a,size:s,lowResUrl:h,enableCaching:l=!0,disablePlaceholder:p=!1,placeholderColor:r=5227511,placeholderOpacity:i=.4,errorColor:m=16729156,errorOpacity:A=.5}=e;if(l&&this.cache.has(a)){let d=this.cache.get(a).clone(!0);return this.normalizeBottomCenterData(d)?d.updateMatrixWorld(!0):this.positionAssetAtBottomCenter(d),this.loadedAsset=d,this.dispatchEvent({type:"loaded",asset:d}),d}this.errorColor=m,this.errorOpacity=A,s&&!p&&(this.placeholder=this.createPlaceholder(s,r,i),this.dispatchEvent({type:"placeholderCreated",placeholder:this.placeholder}));try{if(h){let f=await this.loadModel(t,h,!0);this.lowResAsset=f,this.dispatchEvent({type:"lowResLoaded",lowRes:f})}let d=await this.loadModel(t,a,!1);if(this.loadedAsset=d,l){let f=d.clone(!0);this.normalizeBottomCenterData(f)?f.updateMatrixWorld(!0):this.positionAssetAtBottomCenter(f),this.cache.set(a,f)}return this.dispatchEvent({type:"loaded",asset:d}),d}catch(d){throw this.setPlaceholderError(),this.dispatchEvent({type:"error",error:d}),d}}loadModel(e,t,a){return new Promise((s,h)=>{let l=r=>{let i=-1;r.lengthComputable&&r.total>0&&r.loaded<=r.total&&(i=r.loaded/r.total*100),this.dispatchEvent({type:"progress",loaded:r.loaded,total:r.total,percentage:i}),!a&&i>=0&&this.updatePlaceholder(i/100)},p=r=>{h(r)};switch(e){case"gltf":this.gltfLoader.load(t,r=>{let i=r.scene;this.positionAssetAtBottomCenter(i),s(i)},l,p);break;case"fbx":this.fbxLoader.load(t,r=>{this.positionAssetAtBottomCenter(r),s(r)},l,p);break;case"obj":this.objLoader.load(t,r=>{this.positionAssetAtBottomCenter(r),s(r)},l,p);break;case"usd":case"usdz":this.usdLoader.load(t,r=>{this.positionAssetAtBottomCenter(r),s(r)},l,p);break;case"dae":this.colladaLoader.load(t,r=>{if(!r){h(new Error(`Failed to load Collada asset: ${t}`));return}let i=r.scene;this.positionAssetAtBottomCenter(i),s(i)},l,p);break;case"stl":this.stlLoader.load(t,r=>{let i=new o.MeshStandardMaterial({color:8947848}),m=new o.Mesh(r,i);this.positionAssetAtBottomCenter(m),s(m)},l,p);break;case"ply":this.plyLoader.load(t,r=>{let i=new o.MeshStandardMaterial({vertexColors:!0}),m=new o.Mesh(r,i);this.positionAssetAtBottomCenter(m),s(m)},l,p);break;case"3mf":this.threeMFLoader.load(t,r=>{this.positionAssetAtBottomCenter(r),s(r)},l,p);break;default:h(new Error(`Unsupported asset type: ${e}`))}})}getPlaceholder(){return this.placeholder}getAsset(){return this.loadedAsset}getLowResAsset(){return this.lowResAsset}clearCache(){this.cache.clear()}removeFromCache(e){this.cache.delete(e)}getCacheSize(){return this.cache.size}};0&&(module.exports={AssetLoader});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a}from"../chunk-
|
|
1
|
+
import{a}from"../chunk-WVTKB6A6.mjs";export{a as AssetLoader};
|
package/dist/camera/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var O=Object.create;var
|
|
1
|
+
"use strict";var O=Object.create;var l=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var b=(i,a)=>{for(var e in a)l(i,e,{get:a[e],enumerable:!0})},R=(i,a,e,t)=>{if(a&&typeof a=="object"||typeof a=="function")for(let r of z(a))!L.call(i,r)&&r!==e&&l(i,r,{get:()=>a[r],enumerable:!(t=P(a,r))||t.enumerable});return i};var x=(i,a,e)=>(e=i!=null?O(V(i)):{},R(a||!i||!i.__esModule?l(e,"default",{value:i,enumerable:!0}):e,i)),w=i=>R(l({},"__esModule",{value:!0}),i);var U={};b(U,{DualCameraControls:()=>H});module.exports=w(U);var n=x(require("three")),v=x(require("camera-controls")),y=!1,m=new n.Vector3,u=new n.Vector3,k=new n.Vector2;function A(){y||(v.default.install({THREE:n}),y=!0)}function C(i,a,e){return i?Array.isArray(i)?(e.set(i[0],i[1],i[2]),e):(e.copy(i),e):(e.set(a[0],a[1],a[2]),e)}var H=class extends v.default{constructor(e,t={}){A();let{domElement:r=e.domElement}=t,o=g(e,r),s=t.perspective??{},h=t.orthographic??{},c=new n.PerspectiveCamera(s.fov??60,o,s.near??.1,s.far??2e3);c.position.copy(C(s.position,[12,12,12],new n.Vector3)),s.zoom!==void 0&&(c.zoom=s.zoom,c.updateProjectionMatrix());let p=Math.max(h.size??20,.001)*.5,T=p*o,d=new n.OrthographicCamera(-T,T,p,-p,h.near??.1,h.far??2e3);d.position.copy(C(h.position,[12,12,12],new n.Vector3)),h.zoom!==void 0&&(d.zoom=h.zoom,d.updateProjectionMatrix());let f=t.initialMode??"perspective",E=f==="orthographic"?d:c;super(E,r);this.updateTimer=B();this.externalCamera=null;let M=C(t.initialTarget,[0,0,0],new n.Vector3);this.setLookAt(E.position.x,E.position.y,E.position.z,M.x,M.y,M.z,!1),this.renderer=e,this.domElementRef=r,this.perspectiveCamera=c,this.orthographicCamera=d,this.activeMode=f,this.minOrthoHalfHeight=p,this.updateInputBindingsForMode(f)}get mode(){return this.activeMode}get activeCamera(){return this.camera}switchToPerspective(e=!1){if(this.activeMode==="perspective"&&!this.externalCamera)return;this.externalCamera=null;let t=this.getTarget(m),r=this.getPosition(u),o=g(this.renderer,this.domElementRef);this.perspectiveCamera.aspect=o,this.perspectiveCamera.position.copy(r),this.perspectiveCamera.quaternion.copy(this.camera.quaternion),this.perspectiveCamera.up.copy(this.camera.up),this.perspectiveCamera.updateProjectionMatrix(),this.camera=this.perspectiveCamera,this.activeMode="perspective",this.updateInputBindingsForMode("perspective"),this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:"orthographic",camera:this.perspectiveCamera})}switchToOrthographic(e=!1){if(this.activeMode==="orthographic"&&!this.externalCamera)return;this.externalCamera=null;let t=this.getTarget(m),r=this.getPosition(u),o=g(this.renderer,this.domElementRef);this.updateOrthographicFrustum(r,t,o),this.orthographicCamera.position.copy(r),this.orthographicCamera.quaternion.copy(this.camera.quaternion),this.orthographicCamera.up.copy(this.camera.up),this.orthographicCamera.updateProjectionMatrix(),this.camera=this.orthographicCamera,this.activeMode="orthographic",this.updateInputBindingsForMode("orthographic"),this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:"perspective",camera:this.orthographicCamera})}toggleCameraMode(e=!1){this.activeMode==="perspective"?this.switchToOrthographic(e):this.switchToPerspective(e)}get isUsingExternalCamera(){return this.externalCamera!==null}setCamera(e,t,r=!1){let o=this.camera;this.externalCamera=e;let s=g(this.renderer,this.domElementRef);if(e.type==="PerspectiveCamera")e.aspect=s,e.updateProjectionMatrix();else if(e.type==="OrthographicCamera"){let p=e,d=(p.top-p.bottom)*.5*s;p.left=-d,p.right=d,p.updateProjectionMatrix()}this.camera=e;let h=e.type==="PerspectiveCamera"?"perspective":"orthographic";this.activeMode=h,this.updateInputBindingsForMode(h);let c=C(t,[0,0,0],m);this.setLookAt(e.position.x,e.position.y,e.position.z,c.x,c.y,c.z,r),this.dispatchEvent({type:"externalcamerachange",camera:e,previousCamera:o})}clearExternalCamera(e=!1){if(!this.externalCamera)return;let t=this.getTarget(m),r=this.getPosition(u);this.externalCamera=null;let o=this.activeMode==="orthographic"?this.orthographicCamera:this.perspectiveCamera;o.position.copy(r),o.quaternion.copy(this.camera.quaternion),o.up.copy(this.camera.up);let s=g(this.renderer,this.domElementRef);this.activeMode==="orthographic"?this.updateOrthographicFrustum(r,t,s):(this.perspectiveCamera.aspect=s,this.perspectiveCamera.updateProjectionMatrix()),this.camera=o,this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:this.activeMode,camera:o})}handleResize(e,t){let r=t===0?1:e/t;this.perspectiveCamera.aspect=r,this.perspectiveCamera.updateProjectionMatrix();let o=this.getTarget(m),s=this.getPosition(u);this.updateOrthographicFrustum(s,o,r),this.activeMode==="orthographic"&&(this.camera=this.orthographicCamera,this.setLookAt(s.x,s.y,s.z,o.x,o.y,o.z,!1))}moveCamera(e,t,r=!0){return C(e,[0,0,0],m),C(t,[0,0,0],u),this.setLookAt(m.x,m.y,m.z,u.x,u.y,u.z,r)}updateDelta(e){this.updateTimer.update?.(e);let t=this.updateTimer.getDelta();return super.update(t)}updateInputBindingsForMode(e){let{ACTION:t}=v.default;e==="orthographic"?(this.mouseButtons.left=t.TRUCK,this.mouseButtons.right=t.ROTATE,this.mouseButtons.wheel=t.ZOOM,this.touches.one=t.TOUCH_TRUCK,this.touches.two=t.TOUCH_ZOOM_TRUCK):(this.mouseButtons.left=t.ROTATE,this.mouseButtons.right=t.TRUCK,this.mouseButtons.wheel=t.DOLLY,this.touches.one=t.TOUCH_ROTATE,this.touches.two=t.TOUCH_DOLLY_TRUCK)}updateOrthographicFrustum(e,t,r){let o=Math.max(e.distanceTo(t),.001),s=this.perspectiveCamera.fov,h=Math.max(o*Math.tan(n.MathUtils.degToRad(s*.5)),this.minOrthoHalfHeight),c=h*r;this.orthographicCamera.left=-c,this.orthographicCamera.right=c,this.orthographicCamera.top=h,this.orthographicCamera.bottom=-h,this.orthographicCamera.updateProjectionMatrix()}};function B(){let i=n.Timer;if(i){let a=new i;return a.reset(),a}return new n.Clock}function g(i,a){let e=i.getSize(k);if(e.y>0)return e.x/e.y;let{clientWidth:t,clientHeight:r}=a;return r>0?t/r:1}0&&(module.exports={DualCameraControls});
|
package/dist/camera/index.d.mts
CHANGED
|
@@ -48,7 +48,7 @@ declare class DualCameraControls extends CameraControls {
|
|
|
48
48
|
private readonly domElementRef;
|
|
49
49
|
private activeMode;
|
|
50
50
|
private readonly minOrthoHalfHeight;
|
|
51
|
-
private readonly
|
|
51
|
+
private readonly updateTimer;
|
|
52
52
|
private externalCamera;
|
|
53
53
|
constructor(renderer: THREE.WebGLRenderer, options?: DualCameraControlsOptions);
|
|
54
54
|
get mode(): CameraMode;
|
|
@@ -95,7 +95,7 @@ declare class DualCameraControls extends CameraControls {
|
|
|
95
95
|
* Updates the controls using an internally managed clock.
|
|
96
96
|
* Useful when you don't want to pass delta time each frame.
|
|
97
97
|
*/
|
|
98
|
-
updateDelta(): ReturnType<CameraControls['update']>;
|
|
98
|
+
updateDelta(timestamp?: number): ReturnType<CameraControls['update']>;
|
|
99
99
|
private updateInputBindingsForMode;
|
|
100
100
|
private updateOrthographicFrustum;
|
|
101
101
|
}
|
package/dist/camera/index.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ declare class DualCameraControls extends CameraControls {
|
|
|
48
48
|
private readonly domElementRef;
|
|
49
49
|
private activeMode;
|
|
50
50
|
private readonly minOrthoHalfHeight;
|
|
51
|
-
private readonly
|
|
51
|
+
private readonly updateTimer;
|
|
52
52
|
private externalCamera;
|
|
53
53
|
constructor(renderer: THREE.WebGLRenderer, options?: DualCameraControlsOptions);
|
|
54
54
|
get mode(): CameraMode;
|
|
@@ -95,7 +95,7 @@ declare class DualCameraControls extends CameraControls {
|
|
|
95
95
|
* Updates the controls using an internally managed clock.
|
|
96
96
|
* Useful when you don't want to pass delta time each frame.
|
|
97
97
|
*/
|
|
98
|
-
updateDelta(): ReturnType<CameraControls['update']>;
|
|
98
|
+
updateDelta(timestamp?: number): ReturnType<CameraControls['update']>;
|
|
99
99
|
private updateInputBindingsForMode;
|
|
100
100
|
private updateOrthographicFrustum;
|
|
101
101
|
}
|
package/dist/camera/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a}from"../chunk-
|
|
1
|
+
import{a}from"../chunk-MJRTSO3X.mjs";export{a as DualCameraControls};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as o from"three";import f from"camera-controls";var M=!1,m=new o.Vector3,u=new o.Vector3,R=new o.Vector2;function x(){M||(f.install({THREE:o}),M=!0)}function C(n,p,e){return n?Array.isArray(n)?(e.set(n[0],n[1],n[2]),e):(e.copy(n),e):(e.set(p[0],p[1],p[2]),e)}var H=class extends f{constructor(e,t={}){x();let{domElement:r=e.domElement}=t,i=g(e,r),a=t.perspective??{},s=t.orthographic??{},h=new o.PerspectiveCamera(a.fov??60,i,a.near??.1,a.far??2e3);h.position.copy(C(a.position,[12,12,12],new o.Vector3)),a.zoom!==void 0&&(h.zoom=a.zoom,h.updateProjectionMatrix());let c=Math.max(s.size??20,.001)*.5,l=c*i,d=new o.OrthographicCamera(-l,l,c,-c,s.near??.1,s.far??2e3);d.position.copy(C(s.position,[12,12,12],new o.Vector3)),s.zoom!==void 0&&(d.zoom=s.zoom,d.updateProjectionMatrix());let v=t.initialMode??"perspective",E=v==="orthographic"?d:h;super(E,r);this.updateTimer=y();this.externalCamera=null;let T=C(t.initialTarget,[0,0,0],new o.Vector3);this.setLookAt(E.position.x,E.position.y,E.position.z,T.x,T.y,T.z,!1),this.renderer=e,this.domElementRef=r,this.perspectiveCamera=h,this.orthographicCamera=d,this.activeMode=v,this.minOrthoHalfHeight=c,this.updateInputBindingsForMode(v)}get mode(){return this.activeMode}get activeCamera(){return this.camera}switchToPerspective(e=!1){if(this.activeMode==="perspective"&&!this.externalCamera)return;this.externalCamera=null;let t=this.getTarget(m),r=this.getPosition(u),i=g(this.renderer,this.domElementRef);this.perspectiveCamera.aspect=i,this.perspectiveCamera.position.copy(r),this.perspectiveCamera.quaternion.copy(this.camera.quaternion),this.perspectiveCamera.up.copy(this.camera.up),this.perspectiveCamera.updateProjectionMatrix(),this.camera=this.perspectiveCamera,this.activeMode="perspective",this.updateInputBindingsForMode("perspective"),this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:"orthographic",camera:this.perspectiveCamera})}switchToOrthographic(e=!1){if(this.activeMode==="orthographic"&&!this.externalCamera)return;this.externalCamera=null;let t=this.getTarget(m),r=this.getPosition(u),i=g(this.renderer,this.domElementRef);this.updateOrthographicFrustum(r,t,i),this.orthographicCamera.position.copy(r),this.orthographicCamera.quaternion.copy(this.camera.quaternion),this.orthographicCamera.up.copy(this.camera.up),this.orthographicCamera.updateProjectionMatrix(),this.camera=this.orthographicCamera,this.activeMode="orthographic",this.updateInputBindingsForMode("orthographic"),this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:"perspective",camera:this.orthographicCamera})}toggleCameraMode(e=!1){this.activeMode==="perspective"?this.switchToOrthographic(e):this.switchToPerspective(e)}get isUsingExternalCamera(){return this.externalCamera!==null}setCamera(e,t,r=!1){let i=this.camera;this.externalCamera=e;let a=g(this.renderer,this.domElementRef);if(e.type==="PerspectiveCamera")e.aspect=a,e.updateProjectionMatrix();else if(e.type==="OrthographicCamera"){let c=e,d=(c.top-c.bottom)*.5*a;c.left=-d,c.right=d,c.updateProjectionMatrix()}this.camera=e;let s=e.type==="PerspectiveCamera"?"perspective":"orthographic";this.activeMode=s,this.updateInputBindingsForMode(s);let h=C(t,[0,0,0],m);this.setLookAt(e.position.x,e.position.y,e.position.z,h.x,h.y,h.z,r),this.dispatchEvent({type:"externalcamerachange",camera:e,previousCamera:i})}clearExternalCamera(e=!1){if(!this.externalCamera)return;let t=this.getTarget(m),r=this.getPosition(u);this.externalCamera=null;let i=this.activeMode==="orthographic"?this.orthographicCamera:this.perspectiveCamera;i.position.copy(r),i.quaternion.copy(this.camera.quaternion),i.up.copy(this.camera.up);let a=g(this.renderer,this.domElementRef);this.activeMode==="orthographic"?this.updateOrthographicFrustum(r,t,a):(this.perspectiveCamera.aspect=a,this.perspectiveCamera.updateProjectionMatrix()),this.camera=i,this.setLookAt(r.x,r.y,r.z,t.x,t.y,t.z,e),this.dispatchEvent({type:"modechange",mode:this.activeMode,previousMode:this.activeMode,camera:i})}handleResize(e,t){let r=t===0?1:e/t;this.perspectiveCamera.aspect=r,this.perspectiveCamera.updateProjectionMatrix();let i=this.getTarget(m),a=this.getPosition(u);this.updateOrthographicFrustum(a,i,r),this.activeMode==="orthographic"&&(this.camera=this.orthographicCamera,this.setLookAt(a.x,a.y,a.z,i.x,i.y,i.z,!1))}moveCamera(e,t,r=!0){return C(e,[0,0,0],m),C(t,[0,0,0],u),this.setLookAt(m.x,m.y,m.z,u.x,u.y,u.z,r)}updateDelta(e){this.updateTimer.update?.(e);let t=this.updateTimer.getDelta();return super.update(t)}updateInputBindingsForMode(e){let{ACTION:t}=f;e==="orthographic"?(this.mouseButtons.left=t.TRUCK,this.mouseButtons.right=t.ROTATE,this.mouseButtons.wheel=t.ZOOM,this.touches.one=t.TOUCH_TRUCK,this.touches.two=t.TOUCH_ZOOM_TRUCK):(this.mouseButtons.left=t.ROTATE,this.mouseButtons.right=t.TRUCK,this.mouseButtons.wheel=t.DOLLY,this.touches.one=t.TOUCH_ROTATE,this.touches.two=t.TOUCH_DOLLY_TRUCK)}updateOrthographicFrustum(e,t,r){let i=Math.max(e.distanceTo(t),.001),a=this.perspectiveCamera.fov,s=Math.max(i*Math.tan(o.MathUtils.degToRad(a*.5)),this.minOrthoHalfHeight),h=s*r;this.orthographicCamera.left=-h,this.orthographicCamera.right=h,this.orthographicCamera.top=s,this.orthographicCamera.bottom=-s,this.orthographicCamera.updateProjectionMatrix()}};function y(){let n=o.Timer;if(n){let p=new n;return p.reset(),p}return new o.Clock}function g(n,p){let e=n.getSize(R);if(e.y>0)return e.x/e.y;let{clientWidth:t,clientHeight:r}=p;return r>0?t/r:1}export{H as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as a from"three";import{CSS2DObject as m}from"three/examples/jsm/renderers/CSS2DRenderer.js";var u=(i=>(i.VERTEX="vertex",i.FACE="face",i.EDGE="edge",i.DISABLED="disabled",i))(u||{});var h=class extends a.EventDispatcher{constructor(e,t,i={}){super();this.measurements=[];this.raycaster=new a.Raycaster;this.isInteractive=!1;this.domElement=null;this.controls=null;this.defaultTargets=[];this.activeTargets=[];this.currentMeasurement=null;this.activeInteractionOptions=null;this.pendingMeasurementOptions=null;this.previewLine=null;this.previewLabel=null;this.snapMarker=null;this.originalCursor="";this.cursorHidden=!1;this.defaultOptions={lineColor:16711680,labelColor:"#ffffff",lineWidth:2,fontSize:16,fontFamily:"Arial, sans-serif",snapMode:"vertex",snapEnabled:!0,snapDistance:.05,targets:[],isDynamic:!1};this.previewColor=65535;this.markerColor=65280;this.markerSize=.08;this.markerVisible=!0;this.isEditMode=!1;this.editingMeasurement=null;this.editingPoint=null;this.startEditSprite=null;this.endEditSprite=null;this.editSpriteMaterial=null;this.isDragging=!1;this.onMouseClick=e=>{if(!this.isInteractive)return;let t=this.getSnapResult(e);t&&(this.currentMeasurement?this.completeMeasurement(t):this.startMeasurement(t))};this.onMouseMove=e=>{if(!this.isInteractive)return;let t=this.getSnapResult(e);if(!t){this.hideSnapMarker(),this.showCursor();return}this.currentMeasurement?(this.updateSnapMarker(t.point,!0),this.hideCursor(),this.updatePreview(t.point)):(this.updateSnapMarker(t.point,!0),this.hideCursor())};this.onKeyDown=e=>{this.isInteractive&&e.key==="Escape"&&this.cancelCurrentMeasurement()};this.onEditMouseDown=e=>{if(!this.isEditMode||!this.domElement)return;let t=new a.Vector2,i=this.domElement.getBoundingClientRect();t.x=(e.clientX-i.left)/i.width*2-1,t.y=-((e.clientY-i.top)/i.height)*2+1,this.raycaster.setFromCamera(t,this.camera);let n=[this.startEditSprite,this.endEditSprite].filter(r=>r!==null),s=this.raycaster.intersectObjects(n);if(s.length>0){let r=s[0].object;this.editingPoint=r.userData.editPoint,this.isDragging=!0,this.disableControls(),this.editingPoint==="start"&&this.startEditSprite?this.startEditSprite.visible=!1:this.editingPoint==="end"&&this.endEditSprite&&(this.endEditSprite.visible=!1),this.createSnapMarker(),this.snapMarker&&(this.snapMarker.position.copy(r.position),this.snapMarker.visible=!0),this.hideCursor()}};this.onEditMouseMove=e=>{if(!this.isEditMode||!this.isDragging||!this.editingMeasurement)return;let t=this.getSnapResult(e);t&&(this.snapMarker&&(this.snapMarker.position.copy(t.point),this.snapMarker.visible=this.markerVisible),this.editingPoint==="start"?this.updateMeasurementPreview(t.point,this.editingMeasurement.end.position):this.editingPoint==="end"&&this.updateMeasurementPreview(this.editingMeasurement.start.position,t.point))};this.onEditMouseUp=e=>{if(!this.isEditMode||!this.isDragging||!this.editingMeasurement||!this.editingPoint)return;let t=this.getSnapResult(e);if(!t){this.cancelEdit();return}let i=this.editingPoint==="start"?this.editingMeasurement.start:this.editingMeasurement.end;if(i.position.copy(t.point),this.editingMeasurement.options.isDynamic&&t.object){let l=t.object.worldToLocal(t.point.clone());i.anchor={object:t.object,localPosition:l}}else i.anchor=void 0;let s=this.editingMeasurement.start.position.distanceTo(this.editingMeasurement.end.position);this.editingMeasurement.distance=s;let r=[this.editingMeasurement.start.position,this.editingMeasurement.end.position];this.editingMeasurement.line.geometry.setFromPoints(r),this.editingMeasurement.line.geometry.attributes.position.needsUpdate=!0;let o=this.editingMeasurement.start.position.clone().add(this.editingMeasurement.end.position).multiplyScalar(.5);this.editingMeasurement.label.position.copy(o),this.updateLabelText(this.editingMeasurement.label.element,s),this.startEditSprite&&(this.startEditSprite.position.copy(this.editingMeasurement.start.position),this.startEditSprite.visible=!0),this.endEditSprite&&(this.endEditSprite.position.copy(this.editingMeasurement.end.position),this.endEditSprite.visible=!0),this.removeSnapMarker(),this.showCursor(),this.enableControls(),this.dispatchEvent({type:"measurementUpdated",measurement:this.editingMeasurement}),this.isDragging=!1,this.editingPoint=null};this.scene=e,this.camera=t;let{domElement:n,controls:s}=i;n&&(this.domElement=n),s&&(this.controls=s),this.previewMaterial=new a.LineDashedMaterial({color:this.previewColor,linewidth:this.defaultOptions.lineWidth,dashSize:.1,gapSize:.05}),this.markerMaterial=new a.SpriteMaterial({map:this.createCrosshairTexture(),color:this.markerColor,transparent:!0,opacity:.8,sizeAttenuation:!1,depthTest:!1}),this.editSpriteMaterial=new a.SpriteMaterial({map:this.createDotTexture(),color:16755200,transparent:!0,opacity:.9,sizeAttenuation:!1,depthTest:!1}),this.raycaster.params.Line.threshold=.01,this.raycaster.params.Points.threshold=.01}createCrosshairTexture(){let t=document.createElement("canvas");t.width=64,t.height=64;let i=t.getContext("2d"),n=64/2,s=64/2,r=20,o=6;i.clearRect(0,0,64,64),i.strokeStyle="#ffffff",i.lineWidth=3,i.lineCap="round",i.beginPath(),i.moveTo(n-r,s),i.lineTo(n-o,s),i.moveTo(n+o,s),i.lineTo(n+r,s),i.moveTo(n,s-r),i.lineTo(n,s-o),i.moveTo(n,s+o),i.lineTo(n,s+r),i.stroke(),i.strokeStyle="#000000",i.lineWidth=5,i.globalCompositeOperation="destination-over",i.beginPath(),i.moveTo(n-r,s),i.lineTo(n-o,s),i.moveTo(n+o,s),i.lineTo(n+r,s),i.moveTo(n,s-r),i.lineTo(n,s-o),i.moveTo(n,s+o),i.lineTo(n,s+r),i.stroke();let l=new a.CanvasTexture(t);return l.needsUpdate=!0,l}createDotTexture(){let t=document.createElement("canvas");t.width=64,t.height=64;let i=t.getContext("2d"),n=64/2,s=64/2,r=12;i.clearRect(0,0,64,64),i.fillStyle="#ffffff",i.beginPath(),i.arc(n,s,r,0,Math.PI*2),i.fill(),i.strokeStyle="#000000",i.lineWidth=3,i.beginPath(),i.arc(n,s,r,0,Math.PI*2),i.stroke();let o=new a.CanvasTexture(t);return o.needsUpdate=!0,o}createMeasurementPoint(e,t,i){if(!t)return{position:e.clone()};let n=i?.clone()??t.worldToLocal(e.clone());return{position:t.localToWorld(n.clone()),anchor:{object:t,localPosition:n}}}updateMeasurementPoint(e){if(!e.anchor)return!1;let t=e.anchor.localPosition.clone();return e.anchor.object.localToWorld(t),e.position.equals(t)?!1:(e.position.copy(t),!0)}addMeasurement(e,t,i={}){let n=!!(i.startObject||i.endObject),s=this.resolveMeasurementOptions(i,i.isDynamic??n),r=this.createMeasurementPoint(e,i.startObject,i.startLocalPosition),o=this.createMeasurementPoint(t,i.endObject,i.endLocalPosition);return this.addMeasurementFromPoints(r,o,s,{id:i.id})}resolveMeasurementOptions(e={},t){let i;e.targets&&e.targets.length>0?i=e.targets:this.defaultOptions.targets.length>0?i=this.defaultOptions.targets:this.defaultTargets.length>0&&(i=this.defaultTargets);let n=i&&i.length>0?i:this.getAllMeshes(),s=e.isDynamic??t??this.defaultOptions.isDynamic;return{lineColor:e.lineColor??this.defaultOptions.lineColor,labelColor:e.labelColor??this.defaultOptions.labelColor,lineWidth:e.lineWidth??this.defaultOptions.lineWidth,fontSize:e.fontSize??this.defaultOptions.fontSize,fontFamily:e.fontFamily??this.defaultOptions.fontFamily,snapMode:e.snapMode??this.defaultOptions.snapMode,snapEnabled:e.snapEnabled??this.defaultOptions.snapEnabled,snapDistance:e.snapDistance??this.defaultOptions.snapDistance,targets:n,isDynamic:s}}getActiveMeasurementOptions(){return this.isEditMode&&this.editingMeasurement?this.editingMeasurement.options:this.activeInteractionOptions}addDynamicMeasurement(e,t,i=new a.Vector3,n=new a.Vector3){let s=e.localToWorld(i.clone()),r=t.localToWorld(n.clone());return this.addMeasurement(s,r,{startObject:e,endObject:t,startLocalPosition:i,endLocalPosition:n})}addMeasurementToObject(e,t,i=new a.Vector3){let n=t.localToWorld(i.clone());return this.addMeasurement(e,n,{endObject:t,endLocalPosition:i})}addMeasurementFromPoints(e,t,i,n){let s=n?.id||this.generateId(),r=e.position.distanceTo(t.position),o=new a.BufferGeometry().setFromPoints([e.position,t.position]),l=new a.Line(o,new a.LineBasicMaterial({color:i.lineColor,linewidth:i.lineWidth})),c=this.createLabel(r,i),p=e.position.clone().add(t.position).multiplyScalar(.5);c.position.copy(p);let d={id:s,start:e,end:t,line:l,label:c,distance:r,options:{...i,targets:[...i.targets]}};return this.scene.add(l),this.scene.add(c),this.measurements.push(d),this.dispatchEvent({type:"measurementCreated",measurement:d}),d}updateDynamicMeasurements(){let e=!1;for(let t of this.measurements){if(!t.options.isDynamic)continue;let i=!1;if(this.updateMeasurementPoint(t.start)&&(i=!0),this.updateMeasurementPoint(t.end)&&(i=!0),i){let n=t.start.position.distanceTo(t.end.position);t.distance=n;let s=[t.start.position,t.end.position];t.line.geometry.setFromPoints(s),t.line.geometry.attributes.position.needsUpdate=!0;let r=t.start.position.clone().add(t.end.position).multiplyScalar(.5);t.label.position.copy(r),this.updateLabelText(t.label.element,n),e=!0}}return e}setDynamicMode(e){this.setDefaultMeasurementOptions({isDynamic:e})}getDynamicMode(){return this.defaultOptions.isDynamic}enterEditMode(e,t){this.exitEditMode();let i;if(typeof e=="string"?i=this.measurements.find(s=>s.id===e):i=this.measurements[e],!i){console.warn("Measurement not found:",e);return}if(!this.domElement){console.warn("DOM element not set. Call setDomElement() or enableInteraction() first.");return}this.isEditMode=!0,this.editingMeasurement=i;let n=t&&t.length>0?t:i.options.targets.length>0?i.options.targets:this.getAllMeshes();this.activeTargets=n,t&&t.length>0&&(i.options.targets=[...t]),this.createEditSprites(),this.domElement.addEventListener("mousedown",this.onEditMouseDown),this.domElement.addEventListener("mousemove",this.onEditMouseMove),this.domElement.addEventListener("mouseup",this.onEditMouseUp),this.domElement.style.cursor="pointer",this.dispatchEvent({type:"editModeEntered",measurement:i})}exitEditMode(){if(!this.isEditMode)return;let e=this.editingMeasurement;this.removeEditSprites(),this.domElement&&(this.domElement.removeEventListener("mousedown",this.onEditMouseDown),this.domElement.removeEventListener("mousemove",this.onEditMouseMove),this.domElement.removeEventListener("mouseup",this.onEditMouseUp),this.domElement.style.cursor=this.isInteractive?"crosshair":"default"),this.isEditMode=!1,this.editingMeasurement=null,this.editingPoint=null,this.isDragging=!1,this.activeTargets=[],e&&this.dispatchEvent({type:"editModeExited",measurement:e})}setDomElement(e){this.domElement=e}setControls(e){this.controls=e}setTargetObjects(e){this.defaultTargets=e.length>0?e:this.getAllMeshes(),this.defaultOptions.targets=[...this.defaultTargets]}setDefaultMeasurementOptions(e){e.lineColor!==void 0&&(this.defaultOptions.lineColor=e.lineColor),e.labelColor!==void 0&&(this.defaultOptions.labelColor=e.labelColor),e.lineWidth!==void 0&&(this.defaultOptions.lineWidth=e.lineWidth),e.fontSize!==void 0&&(this.defaultOptions.fontSize=e.fontSize),e.fontFamily!==void 0&&(this.defaultOptions.fontFamily=e.fontFamily),e.snapMode!==void 0&&(this.defaultOptions.snapMode=e.snapMode),e.snapEnabled!==void 0&&(this.defaultOptions.snapEnabled=e.snapEnabled),e.snapDistance!==void 0&&(this.defaultOptions.snapDistance=e.snapDistance),e.targets!==void 0&&(this.defaultTargets=e.targets,this.defaultOptions.targets=[...e.targets],this.activeInteractionOptions&&(this.activeInteractionOptions.targets=[...e.targets],this.activeTargets=e.targets)),e.isDynamic!==void 0&&(this.defaultOptions.isDynamic=e.isDynamic,this.activeInteractionOptions&&(this.activeInteractionOptions.isDynamic=e.isDynamic)),this.activeInteractionOptions&&(e.lineColor!==void 0&&(this.activeInteractionOptions.lineColor=e.lineColor),e.labelColor!==void 0&&(this.activeInteractionOptions.labelColor=e.labelColor),e.lineWidth!==void 0&&(this.activeInteractionOptions.lineWidth=e.lineWidth),e.fontSize!==void 0&&(this.activeInteractionOptions.fontSize=e.fontSize),e.fontFamily!==void 0&&(this.activeInteractionOptions.fontFamily=e.fontFamily),e.snapMode!==void 0&&(this.activeInteractionOptions.snapMode=e.snapMode),e.snapEnabled!==void 0&&(this.activeInteractionOptions.snapEnabled=e.snapEnabled),e.snapDistance!==void 0&&(this.activeInteractionOptions.snapDistance=e.snapDistance))}disableControls(){this.controls&&(this.controls.enabled=!1)}enableControls(){this.controls&&(this.controls.enabled=!0)}enableInteraction(e={}){this.isInteractive&&this.disableInteraction();let t=this.resolveMeasurementOptions(e);this.activeInteractionOptions={...t,targets:[...t.targets]},this.activeTargets=this.activeInteractionOptions.targets.length>0?this.activeInteractionOptions.targets:this.getAllMeshes(),this.isInteractive=!0,this.domElement&&(this.domElement.addEventListener("click",this.onMouseClick),this.domElement.addEventListener("mousemove",this.onMouseMove),this.domElement.addEventListener("keydown",this.onKeyDown),this.domElement.style.cursor="crosshair"),this.createSnapMarker(),this.dispatchEvent({type:"started"})}disableInteraction(){!this.isInteractive||!this.domElement||(this.exitEditMode(),this.domElement.removeEventListener("click",this.onMouseClick),this.domElement.removeEventListener("mousemove",this.onMouseMove),this.domElement.removeEventListener("keydown",this.onKeyDown),this.showCursor(),this.domElement.style.cursor="default",this.cancelCurrentMeasurement(),this.removeSnapMarker(),this.isInteractive=!1,this.activeInteractionOptions=null,this.activeTargets=[],this.dispatchEvent({type:"ended"}))}undoLast(){if(this.measurements.length===0)return;let e=this.measurements.pop();this.removeMeasurementFromScene(e),this.dispatchEvent({type:"measurementRemoved",measurement:e})}removeMeasurement(e){let t=this.measurements.indexOf(e);t!==-1&&(this.measurements.splice(t,1),this.removeMeasurementFromScene(e),this.dispatchEvent({type:"measurementRemoved",measurement:e}))}clearAll(){let e=this.measurements.length;this.measurements.forEach(t=>{this.removeMeasurementFromScene(t)}),this.measurements=[],this.dispatchEvent({type:"measurementsCleared",count:e})}getMeasurements(){return[...this.measurements]}serializeMeasurementPoint(e){return{position:e.position.toArray(),anchorObjectId:e.anchor?.object.uuid,anchorLocalPosition:e.anchor?e.anchor.localPosition.toArray():void 0}}serialize(){return this.measurements.map(e=>({id:e.id,start:this.serializeMeasurementPoint(e.start),end:this.serializeMeasurementPoint(e.end),distance:e.distance,options:{snapMode:e.options.snapMode,snapEnabled:e.options.snapEnabled,snapDistance:e.options.snapDistance,lineColor:e.options.lineColor,labelColor:e.options.labelColor,lineWidth:e.options.lineWidth,fontSize:e.options.fontSize,fontFamily:e.options.fontFamily,isDynamic:e.options.isDynamic,targetObjectIds:e.options.targets.map(t=>t.uuid)}}))}deserialize(e){this.clearAll(),e.forEach(t=>{let i=new a.Vector3().fromArray(t.start.position),n=new a.Vector3().fromArray(t.end.position),s=t.start.anchorObjectId?this.scene.getObjectByProperty("uuid",t.start.anchorObjectId):null,r=t.end.anchorObjectId?this.scene.getObjectByProperty("uuid",t.end.anchorObjectId):null,o=t.options.targetObjectIds&&t.options.targetObjectIds.length>0?t.options.targetObjectIds.map(l=>this.scene.getObjectByProperty("uuid",l)).filter(l=>l!==void 0):void 0;this.addMeasurement(i,n,{id:t.id,targets:o&&o.length>0?o:void 0,snapMode:t.options.snapMode,snapEnabled:t.options.snapEnabled,snapDistance:t.options.snapDistance,lineColor:t.options.lineColor,labelColor:t.options.labelColor,lineWidth:t.options.lineWidth,fontSize:t.options.fontSize,fontFamily:t.options.fontFamily,isDynamic:t.options.isDynamic,startObject:s||void 0,startLocalPosition:t.start.anchorLocalPosition?new a.Vector3().fromArray(t.start.anchorLocalPosition):void 0,endObject:r||void 0,endLocalPosition:t.end.anchorLocalPosition?new a.Vector3().fromArray(t.end.anchorLocalPosition):void 0})})}dispose(){this.exitEditMode(),this.disableInteraction(),this.clearAll(),this.previewMaterial.dispose(),this.markerMaterial.map&&this.markerMaterial.map.dispose(),this.markerMaterial.dispose(),this.editSpriteMaterial&&(this.editSpriteMaterial.map&&this.editSpriteMaterial.map.dispose(),this.editSpriteMaterial.dispose())}hideCursor(){!this.domElement||this.cursorHidden||(this.originalCursor=this.domElement.style.cursor,this.domElement.style.cursor="none",this.cursorHidden=!0)}showCursor(){!this.domElement||!this.cursorHidden||(this.domElement.style.cursor=this.originalCursor||"crosshair",this.cursorHidden=!1)}createSnapMarker(){this.markerVisible&&(this.snapMarker&&this.scene.remove(this.snapMarker),this.snapMarker=new a.Sprite(this.markerMaterial),this.snapMarker.scale.setScalar(this.markerSize),this.snapMarker.visible=!1,this.snapMarker.renderOrder=999,this.snapMarker.material.depthTest=!1,this.scene.add(this.snapMarker))}updateSnapMarker(e,t=!0){!this.snapMarker||!this.markerVisible||(this.snapMarker.position.copy(e),this.snapMarker.visible=t)}hideSnapMarker(){this.snapMarker&&(this.snapMarker.visible=!1)}removeSnapMarker(){this.snapMarker&&(this.scene.remove(this.snapMarker),this.snapMarker=null)}startMeasurement(e){let t=this.generateId(),i=e.point,n=this.activeInteractionOptions??this.defaultOptions,s={...n,targets:[...n.targets]};this.pendingMeasurementOptions=s,this.hideSnapMarker();let r=new a.BufferGeometry().setFromPoints([i,i]);this.previewLine=new a.Line(r,this.previewMaterial),this.previewLine.computeLineDistances(),this.scene.add(this.previewLine),this.previewLabel=this.createLabel(0,s),this.previewLabel.position.copy(i),this.scene.add(this.previewLabel);let o=s.isDynamic&&e.object?this.createMeasurementPoint(i,e.object):this.createMeasurementPoint(i);this.currentMeasurement={id:t,start:o}}updatePreview(e){if(!this.currentMeasurement||!this.previewLine||!this.previewLabel)return;let t=this.currentMeasurement.start,i=t.position.distanceTo(e),n=new a.BufferGeometry().setFromPoints([t.position,e]);this.previewLine.geometry.dispose(),this.previewLine.geometry=n,this.previewLine.computeLineDistances();let s=t.position.clone().add(e).multiplyScalar(.5);this.previewLabel.position.copy(s),this.updateLabelText(this.previewLabel.element,i),this.dispatchEvent({type:"previewUpdated",start:t.position,current:e,distance:i})}completeMeasurement(e){if(!this.currentMeasurement)return;let t=this.currentMeasurement.start,i=e.point,n=this.pendingMeasurementOptions??this.activeInteractionOptions??this.defaultOptions;this.disableInteraction(),this.cleanupPreview();let s={...n,targets:[...n.targets]},r=s.isDynamic&&e.object?this.createMeasurementPoint(i,e.object):this.createMeasurementPoint(i);this.addMeasurementFromPoints(t,r,s),this.currentMeasurement=null,this.pendingMeasurementOptions=null,this.createSnapMarker()}cancelCurrentMeasurement(){this.cleanupPreview(),this.currentMeasurement=null,this.pendingMeasurementOptions=null,this.createSnapMarker()}cleanupPreview(){this.previewLine&&(this.scene.remove(this.previewLine),this.previewLine.geometry.dispose(),this.previewLine=null),this.previewLabel&&(this.scene.remove(this.previewLabel),this.previewLabel.element.parentNode&&this.previewLabel.element.parentNode.removeChild(this.previewLabel.element),this.previewLabel=null)}getSnapResult(e){let t=new a.Vector2,i=this.domElement.getBoundingClientRect();t.x=(e.clientX-i.left)/i.width*2-1,t.y=-((e.clientY-i.top)/i.height)*2+1;let n=this.getActiveMeasurementOptions()??this.defaultOptions,s=this.activeTargets.length>0?this.activeTargets:n.targets.length>0?n.targets:this.getAllMeshes();this.raycaster.setFromCamera(t,this.camera);let r=this.raycaster.intersectObjects(s,!0);if(r.length===0)return null;let o=r[0],l=o.point.clone(),c=!1,p="disabled";if(n.snapEnabled){let d=this.performSnapping(o,n);l=d.point,c=d.snapped,p=d.snapMode}return{point:l,originalPoint:o.point,snapped:c,snapMode:p,object:o.object}}performSnapping(e,t){let i=e.point,n=i.clone(),s=!1,r="disabled";if(t.snapMode==="vertex"){let o=this.snapToVertex(e,t.snapDistance);o&&(n=o,s=!0,r="vertex")}else t.snapMode==="face"&&(s=!0,r="face");return{point:n,originalPoint:i,snapped:s,snapMode:r,object:e.object}}snapToVertex(e,t){let i=e.object.geometry;if(!i.attributes.position)return null;let n=i.attributes.position,s=e.object.matrixWorld,r=new a.Vector3,o=1/0,l=!1;for(let c=0;c<n.count;c++){let p=new a.Vector3;p.fromBufferAttribute(n,c),p.applyMatrix4(s);let d=p.distanceTo(e.point);d<t&&d<o&&(o=d,r.copy(p),l=!0)}return l?r:null}createLabel(e,t){let i=document.createElement("div");i.className="measurement-label",Object.assign(i.style,{color:t.labelColor,fontSize:`${t.fontSize}px`,fontFamily:t.fontFamily,fontWeight:"bold",background:"rgba(0, 0, 0, 0.9)",padding:"8px 12px",borderRadius:"8px",border:"2px solid rgba(255, 255, 255, 0.3)",whiteSpace:"nowrap",userSelect:"none",pointerEvents:"auto",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.5)",textShadow:"1px 1px 2px rgba(0, 0, 0, 0.8)",zIndex:"1000",cursor:"pointer"}),this.updateLabelText(i,e);let n=new m(i);return i.addEventListener("dblclick",s=>{s.stopPropagation();let r=this.measurements.find(o=>o.label===n);r&&this.enterEditMode(r.id)}),n}updateLabelText(e,t){let i=`${t.toFixed(2)}m`;e.textContent=i}removeMeasurementFromScene(e){this.scene.remove(e.line),this.scene.remove(e.label),e.line.geometry.dispose(),e.line.material instanceof a.Material&&e.line.material.dispose(),e.label.element.parentNode&&e.label.element.parentNode.removeChild(e.label.element)}getAllMeshes(){let e=[];return this.scene.traverse(t=>{t instanceof a.Mesh&&e.push(t)}),e}generateId(){return`measurement_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}createEditSprites(){if(!this.editingMeasurement||!this.editSpriteMaterial)return;let e=this.editingMeasurement;this.startEditSprite=new a.Sprite(this.editSpriteMaterial.clone()),this.startEditSprite.position.copy(e.start.position),this.startEditSprite.scale.set(this.markerSize,this.markerSize,1),this.startEditSprite.userData.editPoint="start",this.scene.add(this.startEditSprite),this.endEditSprite=new a.Sprite(this.editSpriteMaterial.clone()),this.endEditSprite.position.copy(e.end.position),this.endEditSprite.scale.set(this.markerSize,this.markerSize,1),this.endEditSprite.userData.editPoint="end",this.scene.add(this.endEditSprite)}removeEditSprites(){this.startEditSprite&&(this.scene.remove(this.startEditSprite),this.startEditSprite.material instanceof a.Material&&this.startEditSprite.material.dispose(),this.startEditSprite=null),this.endEditSprite&&(this.scene.remove(this.endEditSprite),this.endEditSprite.material instanceof a.Material&&this.endEditSprite.material.dispose(),this.endEditSprite=null)}cancelEdit(){this.isDragging=!1,this.editingPoint=null,this.enableControls(),this.startEditSprite&&(this.startEditSprite.visible=!0),this.endEditSprite&&(this.endEditSprite.visible=!0),this.removeSnapMarker(),this.showCursor()}updateMeasurementPreview(e,t){if(!this.editingMeasurement)return;let i=e.distanceTo(t),n=[e,t];this.editingMeasurement.line.geometry.setFromPoints(n),this.editingMeasurement.line.geometry.attributes.position.needsUpdate=!0;let s=e.clone().add(t).multiplyScalar(.5);this.editingMeasurement.label.position.copy(s),this.updateLabelText(this.editingMeasurement.label.element,i)}};export{u as a,h as b};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import*as o from"three";import{GLTFLoader as u}from"three/examples/jsm/loaders/GLTFLoader.js";import{FBXLoader as E}from"three/examples/jsm/loaders/FBXLoader.js";import{OBJLoader as b}from"three/examples/jsm/loaders/OBJLoader.js";import{USDLoader as y}from"three/examples/jsm/loaders/USDLoader.js";import{ColladaLoader as v}from"three/examples/jsm/loaders/ColladaLoader.js";import{STLLoader as R}from"three/examples/jsm/loaders/STLLoader.js";import{PLYLoader as L}from"three/examples/jsm/loaders/PLYLoader.js";import{ThreeMFLoader as T}from"three/examples/jsm/loaders/3MFLoader.js";var f=class extends o.EventDispatcher{constructor(){super();this.cache=new Map;this.placeholder=null;this.loadedAsset=null;this.lowResAsset=null;this.errorColor=16729156;this.errorOpacity=.5;this.gltfLoader=new u,this.fbxLoader=new E,this.objLoader=new b,this.usdLoader=new y,this.colladaLoader=new v,this.stlLoader=new R,this.plyLoader=new L,this.threeMFLoader=new T}createPlaceholder(
|
|
1
|
+
import*as o from"three";import{GLTFLoader as u}from"three/examples/jsm/loaders/GLTFLoader.js";import{FBXLoader as E}from"three/examples/jsm/loaders/FBXLoader.js";import{OBJLoader as b}from"three/examples/jsm/loaders/OBJLoader.js";import{USDLoader as y}from"three/examples/jsm/loaders/USDLoader.js";import{ColladaLoader as v}from"three/examples/jsm/loaders/ColladaLoader.js";import{STLLoader as R}from"three/examples/jsm/loaders/STLLoader.js";import{PLYLoader as L}from"three/examples/jsm/loaders/PLYLoader.js";import{ThreeMFLoader as T}from"three/examples/jsm/loaders/3MFLoader.js";var f=class extends o.EventDispatcher{constructor(){super();this.cache=new Map;this.placeholder=null;this.loadedAsset=null;this.lowResAsset=null;this.errorColor=16729156;this.errorOpacity=.5;this.gltfLoader=new u,this.fbxLoader=new E,this.objLoader=new b,this.usdLoader=new y,this.colladaLoader=new v,this.stlLoader=new R,this.plyLoader=new L,this.threeMFLoader=new T}createPlaceholder(t,r=5227511,l=.3){let[a,d,i]=t,c=new o.BoxGeometry(a,d,i),e=new o.ShaderMaterial({side:o.DoubleSide,depthWrite:!1,blending:o.AdditiveBlending,transparent:!0,uniforms:{color:{value:new o.Color(r)},opacity:{value:l},fillProgress:{value:0},time:{value:0},isError:{value:0},yMin:{value:-d/2},yMax:{value:d/2}},vertexShader:`
|
|
2
2
|
varying vec3 vPosition;
|
|
3
3
|
void main() {
|
|
4
4
|
vPosition = position;
|
|
@@ -41,4 +41,4 @@ import*as o from"three";import{GLTFLoader as u}from"three/examples/jsm/loaders/G
|
|
|
41
41
|
vec3 finalColor = color + edgeIntensity * 0.5;
|
|
42
42
|
gl_FragColor = vec4(finalColor, alpha);
|
|
43
43
|
}
|
|
44
|
-
`}),s=new o.Mesh(
|
|
44
|
+
`}),s=new o.Mesh(c,e);return this.positionAssetAtBottomCenter(s),s}updatePlaceholder(t){if(this.placeholder&&this.placeholder instanceof o.Mesh){let r=this.placeholder.material;r.uniforms&&r.uniforms.fillProgress&&(r.uniforms.fillProgress.value=t)}}setPlaceholderError(){if(this.placeholder&&this.placeholder instanceof o.Mesh){let t=this.placeholder.material;t.uniforms&&(t.uniforms.color&&(t.uniforms.color.value=new o.Color(this.errorColor)),t.uniforms.opacity&&(t.uniforms.opacity.value=this.errorOpacity),t.uniforms.fillProgress&&(t.uniforms.fillProgress.value=0),t.uniforms.isError&&(t.uniforms.isError.value=1))}}updatePlaceholderAnimation(t){if(this.placeholder&&this.placeholder instanceof o.Mesh){let r=this.placeholder.material;r.uniforms&&r.uniforms.time&&(r.uniforms.time.value+=t)}}positionAssetAtBottomCenter(t){t.updateMatrixWorld(!0);let r=new o.Box3().setFromObject(t);if(r.isEmpty())return;let l=r.getCenter(new o.Vector3),a=new o.Vector3(l.x,r.min.y-.01,l.z);!Number.isFinite(a.x)||!Number.isFinite(a.y)||!Number.isFinite(a.z)||(t.position.sub(a),t.userData.bottomCenterOffset=a,t.updateMatrixWorld(!0))}ensureBottomCenterOffset(t){let r=t.userData.bottomCenterOffset;if(r instanceof o.Vector3)return r;if(r&&typeof r=="object"){let{x:l=0,y:a=0,z:d=0}=r,i=new o.Vector3(l??0,a??0,d??0);return t.userData.bottomCenterOffset=i,i}return null}normalizeBottomCenterData(t){let r=this.ensureBottomCenterOffset(t)!==null;return t.children.forEach(l=>this.normalizeBottomCenterData(l)),r}async load(t){let{type:r,url:l,size:a,lowResUrl:d,enableCaching:i=!0,disablePlaceholder:c=!1,placeholderColor:e=5227511,placeholderOpacity:s=.4,errorColor:p=16729156,errorOpacity:m=.5}=t;if(i&&this.cache.has(l)){let n=this.cache.get(l).clone(!0);return this.normalizeBottomCenterData(n)?n.updateMatrixWorld(!0):this.positionAssetAtBottomCenter(n),this.loadedAsset=n,this.dispatchEvent({type:"loaded",asset:n}),n}this.errorColor=p,this.errorOpacity=m,a&&!c&&(this.placeholder=this.createPlaceholder(a,e,s),this.dispatchEvent({type:"placeholderCreated",placeholder:this.placeholder}));try{if(d){let h=await this.loadModel(r,d,!0);this.lowResAsset=h,this.dispatchEvent({type:"lowResLoaded",lowRes:h})}let n=await this.loadModel(r,l,!1);if(this.loadedAsset=n,i){let h=n.clone(!0);this.normalizeBottomCenterData(h)?h.updateMatrixWorld(!0):this.positionAssetAtBottomCenter(h),this.cache.set(l,h)}return this.dispatchEvent({type:"loaded",asset:n}),n}catch(n){throw this.setPlaceholderError(),this.dispatchEvent({type:"error",error:n}),n}}loadModel(t,r,l){return new Promise((a,d)=>{let i=e=>{let s=-1;e.lengthComputable&&e.total>0&&e.loaded<=e.total&&(s=e.loaded/e.total*100),this.dispatchEvent({type:"progress",loaded:e.loaded,total:e.total,percentage:s}),!l&&s>=0&&this.updatePlaceholder(s/100)},c=e=>{d(e)};switch(t){case"gltf":this.gltfLoader.load(r,e=>{let s=e.scene;this.positionAssetAtBottomCenter(s),a(s)},i,c);break;case"fbx":this.fbxLoader.load(r,e=>{this.positionAssetAtBottomCenter(e),a(e)},i,c);break;case"obj":this.objLoader.load(r,e=>{this.positionAssetAtBottomCenter(e),a(e)},i,c);break;case"usd":case"usdz":this.usdLoader.load(r,e=>{this.positionAssetAtBottomCenter(e),a(e)},i,c);break;case"dae":this.colladaLoader.load(r,e=>{if(!e){d(new Error(`Failed to load Collada asset: ${r}`));return}let s=e.scene;this.positionAssetAtBottomCenter(s),a(s)},i,c);break;case"stl":this.stlLoader.load(r,e=>{let s=new o.MeshStandardMaterial({color:8947848}),p=new o.Mesh(e,s);this.positionAssetAtBottomCenter(p),a(p)},i,c);break;case"ply":this.plyLoader.load(r,e=>{let s=new o.MeshStandardMaterial({vertexColors:!0}),p=new o.Mesh(e,s);this.positionAssetAtBottomCenter(p),a(p)},i,c);break;case"3mf":this.threeMFLoader.load(r,e=>{this.positionAssetAtBottomCenter(e),a(e)},i,c);break;default:d(new Error(`Unsupported asset type: ${t}`))}})}getPlaceholder(){return this.placeholder}getAsset(){return this.loadedAsset}getLowResAsset(){return this.lowResAsset}clearCache(){this.cache.clear()}removeFromCache(t){this.cache.delete(t)}getCacheSize(){return this.cache.size}};export{f as a};
|