@tonybfox/threejs-tools 1.0.2 → 1.0.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/dist/asset-loader/index.cjs +27 -7
- package/dist/asset-loader/index.d.mts +2 -1
- package/dist/asset-loader/index.d.ts +2 -1
- package/dist/asset-loader/index.mjs +1 -2
- package/dist/camera/index.cjs +91 -3
- package/dist/camera/index.d.mts +22 -1
- package/dist/camera/index.d.ts +22 -1
- package/dist/camera/index.mjs +1 -2
- package/dist/{chunk-L4VIIJZD.mjs → chunk-27WUVRGX.mjs} +27 -7
- package/dist/{chunk-EQDOX34V.mjs → chunk-2CDI7ORN.mjs} +0 -1
- package/dist/{chunk-EIROAPF7.mjs → chunk-FBTT6MU6.mjs} +0 -1
- package/dist/{chunk-VETFQ3IQ.mjs → chunk-IAZH4OHC.mjs} +0 -1
- package/dist/{chunk-5DP6WDB3.mjs → chunk-OZKJ3GAD.mjs} +0 -1
- package/dist/{chunk-IIAZ2WJJ.mjs → chunk-W4DAAAW6.mjs} +0 -1
- package/dist/{chunk-WMHEIUXE.mjs → chunk-XA7OKYSM.mjs} +91 -3
- package/dist/{chunk-BJKSICFA.mjs → chunk-YMMLYGHV.mjs} +0 -1
- package/dist/{chunk-P35QJCOG.mjs → chunk-ZNGFST7K.mjs} +15 -6
- package/dist/compass/index.cjs +15 -6
- package/dist/compass/index.d.mts +4 -2
- package/dist/compass/index.d.ts +4 -2
- package/dist/compass/index.mjs +1 -2
- package/dist/grid/index.cjs +0 -1
- package/dist/grid/index.mjs +1 -2
- package/dist/index.cjs +133 -14
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +9 -10
- package/dist/measurements/index.cjs +0 -1
- package/dist/measurements/index.mjs +1 -2
- package/dist/sunlight/index.cjs +0 -1
- package/dist/sunlight/index.mjs +1 -2
- package/dist/terrain/index.cjs +0 -1
- package/dist/terrain/index.mjs +1 -2
- package/dist/transform-controls/index.cjs +0 -1
- package/dist/transform-controls/index.mjs +1 -2
- package/dist/view-helper/index.cjs +0 -1
- package/dist/view-helper/index.mjs +1 -2
- package/package.json +1 -1
- package/dist/asset-loader/index.cjs.map +0 -1
- package/dist/asset-loader/index.mjs.map +0 -1
- package/dist/camera/index.cjs.map +0 -1
- package/dist/camera/index.mjs.map +0 -1
- package/dist/chunk-5DP6WDB3.mjs.map +0 -1
- package/dist/chunk-BJKSICFA.mjs.map +0 -1
- package/dist/chunk-EIROAPF7.mjs.map +0 -1
- package/dist/chunk-EQDOX34V.mjs.map +0 -1
- package/dist/chunk-IIAZ2WJJ.mjs.map +0 -1
- package/dist/chunk-L4VIIJZD.mjs.map +0 -1
- package/dist/chunk-P35QJCOG.mjs.map +0 -1
- package/dist/chunk-VETFQ3IQ.mjs.map +0 -1
- package/dist/chunk-WMHEIUXE.mjs.map +0 -1
- package/dist/compass/index.cjs.map +0 -1
- package/dist/compass/index.mjs.map +0 -1
- package/dist/grid/index.cjs.map +0 -1
- package/dist/grid/index.mjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/measurements/index.cjs.map +0 -1
- package/dist/measurements/index.mjs.map +0 -1
- package/dist/sunlight/index.cjs.map +0 -1
- package/dist/sunlight/index.mjs.map +0 -1
- package/dist/terrain/index.cjs.map +0 -1
- package/dist/terrain/index.mjs.map +0 -1
- package/dist/transform-controls/index.cjs.map +0 -1
- package/dist/transform-controls/index.mjs.map +0 -1
- package/dist/view-helper/index.cjs.map +0 -1
- package/dist/view-helper/index.mjs.map +0 -1
|
@@ -39,6 +39,7 @@ var THREE = __toESM(require("three"));
|
|
|
39
39
|
var import_GLTFLoader = require("three/examples/jsm/loaders/GLTFLoader.js");
|
|
40
40
|
var import_FBXLoader = require("three/examples/jsm/loaders/FBXLoader.js");
|
|
41
41
|
var import_OBJLoader = require("three/examples/jsm/loaders/OBJLoader.js");
|
|
42
|
+
var import_USDLoader = require("three/examples/jsm/loaders/USDLoader.js");
|
|
42
43
|
var AssetLoader = class extends THREE.EventDispatcher {
|
|
43
44
|
constructor() {
|
|
44
45
|
super();
|
|
@@ -51,6 +52,7 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
51
52
|
this.gltfLoader = new import_GLTFLoader.GLTFLoader();
|
|
52
53
|
this.fbxLoader = new import_FBXLoader.FBXLoader();
|
|
53
54
|
this.objLoader = new import_OBJLoader.OBJLoader();
|
|
55
|
+
this.usdLoader = new import_USDLoader.USDLoader();
|
|
54
56
|
}
|
|
55
57
|
/**
|
|
56
58
|
* Create a placeholder cube with shader effect
|
|
@@ -68,7 +70,9 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
68
70
|
opacity: { value: opacity },
|
|
69
71
|
fillProgress: { value: 0 },
|
|
70
72
|
time: { value: 0 },
|
|
71
|
-
isError: { value: 0 }
|
|
73
|
+
isError: { value: 0 },
|
|
74
|
+
yMin: { value: -height / 2 },
|
|
75
|
+
yMax: { value: height / 2 }
|
|
72
76
|
},
|
|
73
77
|
vertexShader: `
|
|
74
78
|
varying vec3 vPosition;
|
|
@@ -83,15 +87,17 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
83
87
|
uniform float fillProgress;
|
|
84
88
|
uniform float time;
|
|
85
89
|
uniform float isError;
|
|
90
|
+
uniform float yMin;
|
|
91
|
+
uniform float yMax;
|
|
86
92
|
varying vec3 vPosition;
|
|
87
93
|
|
|
88
94
|
void main() {
|
|
89
|
-
float normalizedY = (vPosition.y
|
|
95
|
+
float normalizedY = (vPosition.y - yMin) / (yMax - yMin); // Normalize based on actual geometry bounds
|
|
90
96
|
float alpha = opacity;
|
|
91
97
|
|
|
92
98
|
// Create fill-up effect
|
|
93
99
|
if (normalizedY > fillProgress) {
|
|
94
|
-
alpha *= 0.
|
|
100
|
+
alpha *= 0.1; // Reduce opacity for unfilled parts
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
// Error state effects
|
|
@@ -217,7 +223,7 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
217
223
|
lowResUrl,
|
|
218
224
|
enableCaching = true,
|
|
219
225
|
placeholderColor = 5227511,
|
|
220
|
-
placeholderOpacity = 0.
|
|
226
|
+
placeholderOpacity = 0.4,
|
|
221
227
|
errorColor = 16729156,
|
|
222
228
|
errorOpacity = 0.5
|
|
223
229
|
} = options;
|
|
@@ -278,14 +284,17 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
278
284
|
loadModel(type, url, isLowRes) {
|
|
279
285
|
return new Promise((resolve, reject) => {
|
|
280
286
|
const onProgress = (event) => {
|
|
281
|
-
|
|
287
|
+
let percentage = -1;
|
|
288
|
+
if (event.lengthComputable && event.total > 0 && event.loaded <= event.total) {
|
|
289
|
+
percentage = event.loaded / event.total * 100;
|
|
290
|
+
}
|
|
282
291
|
this.dispatchEvent({
|
|
283
292
|
type: "progress",
|
|
284
293
|
loaded: event.loaded,
|
|
285
294
|
total: event.total,
|
|
286
295
|
percentage
|
|
287
296
|
});
|
|
288
|
-
if (!isLowRes) {
|
|
297
|
+
if (!isLowRes && percentage >= 0) {
|
|
289
298
|
this.updatePlaceholder(percentage / 100);
|
|
290
299
|
}
|
|
291
300
|
};
|
|
@@ -327,6 +336,18 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
327
336
|
onError
|
|
328
337
|
);
|
|
329
338
|
break;
|
|
339
|
+
case "usd":
|
|
340
|
+
case "usdz":
|
|
341
|
+
this.usdLoader.load(
|
|
342
|
+
url,
|
|
343
|
+
(usd) => {
|
|
344
|
+
this.positionAssetAtBottomCenter(usd);
|
|
345
|
+
resolve(usd);
|
|
346
|
+
},
|
|
347
|
+
onProgress,
|
|
348
|
+
onError
|
|
349
|
+
);
|
|
350
|
+
break;
|
|
330
351
|
default:
|
|
331
352
|
reject(new Error(`Unsupported asset type: ${type}`));
|
|
332
353
|
}
|
|
@@ -373,4 +394,3 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
373
394
|
0 && (module.exports = {
|
|
374
395
|
AssetLoader
|
|
375
396
|
});
|
|
376
|
-
//# sourceMappingURL=index.cjs.map
|
|
@@ -19,7 +19,7 @@ interface AssetLoaderEventMap {
|
|
|
19
19
|
lowRes: THREE.Object3D;
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
-
type AssetType = 'gltf' | 'fbx' | 'obj';
|
|
22
|
+
type AssetType = 'gltf' | 'fbx' | 'obj' | 'usd' | 'usdz';
|
|
23
23
|
interface AssetLoaderOptions {
|
|
24
24
|
type: AssetType;
|
|
25
25
|
url: string;
|
|
@@ -36,6 +36,7 @@ declare class AssetLoader extends THREE.EventDispatcher<AssetLoaderEventMap> {
|
|
|
36
36
|
private gltfLoader;
|
|
37
37
|
private fbxLoader;
|
|
38
38
|
private objLoader;
|
|
39
|
+
private usdLoader;
|
|
39
40
|
private placeholder;
|
|
40
41
|
private loadedAsset;
|
|
41
42
|
private lowResAsset;
|
|
@@ -19,7 +19,7 @@ interface AssetLoaderEventMap {
|
|
|
19
19
|
lowRes: THREE.Object3D;
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
-
type AssetType = 'gltf' | 'fbx' | 'obj';
|
|
22
|
+
type AssetType = 'gltf' | 'fbx' | 'obj' | 'usd' | 'usdz';
|
|
23
23
|
interface AssetLoaderOptions {
|
|
24
24
|
type: AssetType;
|
|
25
25
|
url: string;
|
|
@@ -36,6 +36,7 @@ declare class AssetLoader extends THREE.EventDispatcher<AssetLoaderEventMap> {
|
|
|
36
36
|
private gltfLoader;
|
|
37
37
|
private fbxLoader;
|
|
38
38
|
private objLoader;
|
|
39
|
+
private usdLoader;
|
|
39
40
|
private placeholder;
|
|
40
41
|
private loadedAsset;
|
|
41
42
|
private lowResAsset;
|
package/dist/camera/index.cjs
CHANGED
|
@@ -100,6 +100,7 @@ var DualCameraControls = class extends import_camera_controls.default {
|
|
|
100
100
|
const initialCamera = initialMode === "orthographic" ? orthographicCamera : perspectiveCamera;
|
|
101
101
|
super(initialCamera, domElement);
|
|
102
102
|
this.updateClock = new THREE.Clock();
|
|
103
|
+
this.externalCamera = null;
|
|
103
104
|
const initialTarget = toVector3(
|
|
104
105
|
options.initialTarget,
|
|
105
106
|
[0, 0, 0],
|
|
@@ -135,9 +136,10 @@ var DualCameraControls = class extends import_camera_controls.default {
|
|
|
135
136
|
* Switch to the perspective camera while keeping the current framing.
|
|
136
137
|
*/
|
|
137
138
|
switchToPerspective(enableTransition = false) {
|
|
138
|
-
if (this.activeMode === "perspective") {
|
|
139
|
+
if (this.activeMode === "perspective" && !this.externalCamera) {
|
|
139
140
|
return;
|
|
140
141
|
}
|
|
142
|
+
this.externalCamera = null;
|
|
141
143
|
const target = this.getTarget(tempVec3A);
|
|
142
144
|
const position = this.getPosition(tempVec3B);
|
|
143
145
|
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
@@ -169,9 +171,10 @@ var DualCameraControls = class extends import_camera_controls.default {
|
|
|
169
171
|
* Switch to the orthographic camera while keeping the current framing.
|
|
170
172
|
*/
|
|
171
173
|
switchToOrthographic(enableTransition = false) {
|
|
172
|
-
if (this.activeMode === "orthographic") {
|
|
174
|
+
if (this.activeMode === "orthographic" && !this.externalCamera) {
|
|
173
175
|
return;
|
|
174
176
|
}
|
|
177
|
+
this.externalCamera = null;
|
|
175
178
|
const target = this.getTarget(tempVec3A);
|
|
176
179
|
const position = this.getPosition(tempVec3B);
|
|
177
180
|
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
@@ -209,6 +212,92 @@ var DualCameraControls = class extends import_camera_controls.default {
|
|
|
209
212
|
this.switchToPerspective(enableTransition);
|
|
210
213
|
}
|
|
211
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Returns true if currently using an external camera.
|
|
217
|
+
*/
|
|
218
|
+
get isUsingExternalCamera() {
|
|
219
|
+
return this.externalCamera !== null;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Sets an external camera to use with the controls.
|
|
223
|
+
* This allows using a camera created outside of DualCameraControls.
|
|
224
|
+
* Call `clearExternalCamera()` to return to the internal cameras.
|
|
225
|
+
*/
|
|
226
|
+
setCamera(camera, target, enableTransition = false) {
|
|
227
|
+
const previousCamera = this.camera;
|
|
228
|
+
this.externalCamera = camera;
|
|
229
|
+
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
230
|
+
if (camera.type === "PerspectiveCamera") {
|
|
231
|
+
;
|
|
232
|
+
camera.aspect = aspect;
|
|
233
|
+
camera.updateProjectionMatrix();
|
|
234
|
+
} else if (camera.type === "OrthographicCamera") {
|
|
235
|
+
const ortho = camera;
|
|
236
|
+
const currentHeight = (ortho.top - ortho.bottom) * 0.5;
|
|
237
|
+
const newHalfWidth = currentHeight * aspect;
|
|
238
|
+
ortho.left = -newHalfWidth;
|
|
239
|
+
ortho.right = newHalfWidth;
|
|
240
|
+
ortho.updateProjectionMatrix();
|
|
241
|
+
}
|
|
242
|
+
this.camera = camera;
|
|
243
|
+
const mode = camera.type === "PerspectiveCamera" ? "perspective" : "orthographic";
|
|
244
|
+
this.activeMode = mode;
|
|
245
|
+
this.updateInputBindingsForMode(mode);
|
|
246
|
+
const targetVec = toVector3(target, [0, 0, 0], tempVec3A);
|
|
247
|
+
void this.setLookAt(
|
|
248
|
+
camera.position.x,
|
|
249
|
+
camera.position.y,
|
|
250
|
+
camera.position.z,
|
|
251
|
+
targetVec.x,
|
|
252
|
+
targetVec.y,
|
|
253
|
+
targetVec.z,
|
|
254
|
+
enableTransition
|
|
255
|
+
);
|
|
256
|
+
this.dispatchEvent({
|
|
257
|
+
type: "externalcamerachange",
|
|
258
|
+
camera,
|
|
259
|
+
previousCamera
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Clears the external camera and returns to using the internal cameras.
|
|
264
|
+
* Will switch to the camera matching the current mode.
|
|
265
|
+
*/
|
|
266
|
+
clearExternalCamera(enableTransition = false) {
|
|
267
|
+
if (!this.externalCamera) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const target = this.getTarget(tempVec3A);
|
|
271
|
+
const position = this.getPosition(tempVec3B);
|
|
272
|
+
this.externalCamera = null;
|
|
273
|
+
const internalCamera = this.activeMode === "orthographic" ? this.orthographicCamera : this.perspectiveCamera;
|
|
274
|
+
internalCamera.position.copy(position);
|
|
275
|
+
internalCamera.quaternion.copy(this.camera.quaternion);
|
|
276
|
+
internalCamera.up.copy(this.camera.up);
|
|
277
|
+
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
278
|
+
if (this.activeMode === "orthographic") {
|
|
279
|
+
this.updateOrthographicFrustum(position, target, aspect);
|
|
280
|
+
} else {
|
|
281
|
+
this.perspectiveCamera.aspect = aspect;
|
|
282
|
+
this.perspectiveCamera.updateProjectionMatrix();
|
|
283
|
+
}
|
|
284
|
+
this.camera = internalCamera;
|
|
285
|
+
void this.setLookAt(
|
|
286
|
+
position.x,
|
|
287
|
+
position.y,
|
|
288
|
+
position.z,
|
|
289
|
+
target.x,
|
|
290
|
+
target.y,
|
|
291
|
+
target.z,
|
|
292
|
+
enableTransition
|
|
293
|
+
);
|
|
294
|
+
this.dispatchEvent({
|
|
295
|
+
type: "modechange",
|
|
296
|
+
mode: this.activeMode,
|
|
297
|
+
previousMode: this.activeMode,
|
|
298
|
+
camera: internalCamera
|
|
299
|
+
});
|
|
300
|
+
}
|
|
212
301
|
/**
|
|
213
302
|
* Update camera projection parameters when the viewport size changes.
|
|
214
303
|
*/
|
|
@@ -302,4 +391,3 @@ function resolveAspect(renderer, domElement) {
|
|
|
302
391
|
0 && (module.exports = {
|
|
303
392
|
DualCameraControls
|
|
304
393
|
});
|
|
305
|
-
//# sourceMappingURL=index.cjs.map
|
package/dist/camera/index.d.mts
CHANGED
|
@@ -31,6 +31,11 @@ interface ModeChangedEvent {
|
|
|
31
31
|
previousMode: CameraMode;
|
|
32
32
|
camera: THREE.PerspectiveCamera | THREE.OrthographicCamera;
|
|
33
33
|
}
|
|
34
|
+
interface ExternalCameraChangedEvent {
|
|
35
|
+
type: 'externalcamerachange';
|
|
36
|
+
camera: THREE.PerspectiveCamera | THREE.OrthographicCamera;
|
|
37
|
+
previousCamera: THREE.PerspectiveCamera | THREE.OrthographicCamera;
|
|
38
|
+
}
|
|
34
39
|
/**
|
|
35
40
|
* Camera controls that manage both perspective and orthographic cameras while
|
|
36
41
|
* extending {@link CameraControls}. Provides helpers to toggle between the
|
|
@@ -44,6 +49,7 @@ declare class DualCameraControls extends CameraControls {
|
|
|
44
49
|
private activeMode;
|
|
45
50
|
private readonly minOrthoHalfHeight;
|
|
46
51
|
private readonly updateClock;
|
|
52
|
+
private externalCamera;
|
|
47
53
|
constructor(renderer: THREE.WebGLRenderer, options?: DualCameraControlsOptions);
|
|
48
54
|
get mode(): CameraMode;
|
|
49
55
|
/**
|
|
@@ -62,6 +68,21 @@ declare class DualCameraControls extends CameraControls {
|
|
|
62
68
|
* Toggles between perspective and orthographic camera modes.
|
|
63
69
|
*/
|
|
64
70
|
toggleCameraMode(enableTransition?: boolean): void;
|
|
71
|
+
/**
|
|
72
|
+
* Returns true if currently using an external camera.
|
|
73
|
+
*/
|
|
74
|
+
get isUsingExternalCamera(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Sets an external camera to use with the controls.
|
|
77
|
+
* This allows using a camera created outside of DualCameraControls.
|
|
78
|
+
* Call `clearExternalCamera()` to return to the internal cameras.
|
|
79
|
+
*/
|
|
80
|
+
setCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera, target?: Vector3Like, enableTransition?: boolean): void;
|
|
81
|
+
/**
|
|
82
|
+
* Clears the external camera and returns to using the internal cameras.
|
|
83
|
+
* Will switch to the camera matching the current mode.
|
|
84
|
+
*/
|
|
85
|
+
clearExternalCamera(enableTransition?: boolean): void;
|
|
65
86
|
/**
|
|
66
87
|
* Update camera projection parameters when the viewport size changes.
|
|
67
88
|
*/
|
|
@@ -79,4 +100,4 @@ declare class DualCameraControls extends CameraControls {
|
|
|
79
100
|
private updateOrthographicFrustum;
|
|
80
101
|
}
|
|
81
102
|
|
|
82
|
-
export { type CameraMode, DualCameraControls, type DualCameraControlsOptions, type ModeChangedEvent, type OrthographicCameraConfig, type PerspectiveCameraConfig };
|
|
103
|
+
export { type CameraMode, DualCameraControls, type DualCameraControlsOptions, type ExternalCameraChangedEvent, type ModeChangedEvent, type OrthographicCameraConfig, type PerspectiveCameraConfig };
|
package/dist/camera/index.d.ts
CHANGED
|
@@ -31,6 +31,11 @@ interface ModeChangedEvent {
|
|
|
31
31
|
previousMode: CameraMode;
|
|
32
32
|
camera: THREE.PerspectiveCamera | THREE.OrthographicCamera;
|
|
33
33
|
}
|
|
34
|
+
interface ExternalCameraChangedEvent {
|
|
35
|
+
type: 'externalcamerachange';
|
|
36
|
+
camera: THREE.PerspectiveCamera | THREE.OrthographicCamera;
|
|
37
|
+
previousCamera: THREE.PerspectiveCamera | THREE.OrthographicCamera;
|
|
38
|
+
}
|
|
34
39
|
/**
|
|
35
40
|
* Camera controls that manage both perspective and orthographic cameras while
|
|
36
41
|
* extending {@link CameraControls}. Provides helpers to toggle between the
|
|
@@ -44,6 +49,7 @@ declare class DualCameraControls extends CameraControls {
|
|
|
44
49
|
private activeMode;
|
|
45
50
|
private readonly minOrthoHalfHeight;
|
|
46
51
|
private readonly updateClock;
|
|
52
|
+
private externalCamera;
|
|
47
53
|
constructor(renderer: THREE.WebGLRenderer, options?: DualCameraControlsOptions);
|
|
48
54
|
get mode(): CameraMode;
|
|
49
55
|
/**
|
|
@@ -62,6 +68,21 @@ declare class DualCameraControls extends CameraControls {
|
|
|
62
68
|
* Toggles between perspective and orthographic camera modes.
|
|
63
69
|
*/
|
|
64
70
|
toggleCameraMode(enableTransition?: boolean): void;
|
|
71
|
+
/**
|
|
72
|
+
* Returns true if currently using an external camera.
|
|
73
|
+
*/
|
|
74
|
+
get isUsingExternalCamera(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Sets an external camera to use with the controls.
|
|
77
|
+
* This allows using a camera created outside of DualCameraControls.
|
|
78
|
+
* Call `clearExternalCamera()` to return to the internal cameras.
|
|
79
|
+
*/
|
|
80
|
+
setCamera(camera: THREE.PerspectiveCamera | THREE.OrthographicCamera, target?: Vector3Like, enableTransition?: boolean): void;
|
|
81
|
+
/**
|
|
82
|
+
* Clears the external camera and returns to using the internal cameras.
|
|
83
|
+
* Will switch to the camera matching the current mode.
|
|
84
|
+
*/
|
|
85
|
+
clearExternalCamera(enableTransition?: boolean): void;
|
|
65
86
|
/**
|
|
66
87
|
* Update camera projection parameters when the viewport size changes.
|
|
67
88
|
*/
|
|
@@ -79,4 +100,4 @@ declare class DualCameraControls extends CameraControls {
|
|
|
79
100
|
private updateOrthographicFrustum;
|
|
80
101
|
}
|
|
81
102
|
|
|
82
|
-
export { type CameraMode, DualCameraControls, type DualCameraControlsOptions, type ModeChangedEvent, type OrthographicCameraConfig, type PerspectiveCameraConfig };
|
|
103
|
+
export { type CameraMode, DualCameraControls, type DualCameraControlsOptions, type ExternalCameraChangedEvent, type ModeChangedEvent, type OrthographicCameraConfig, type PerspectiveCameraConfig };
|
package/dist/camera/index.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import * as THREE from "three";
|
|
|
3
3
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
4
4
|
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
|
|
5
5
|
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader.js";
|
|
6
|
+
import { USDLoader } from "three/examples/jsm/loaders/USDLoader.js";
|
|
6
7
|
var AssetLoader = class extends THREE.EventDispatcher {
|
|
7
8
|
constructor() {
|
|
8
9
|
super();
|
|
@@ -15,6 +16,7 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
15
16
|
this.gltfLoader = new GLTFLoader();
|
|
16
17
|
this.fbxLoader = new FBXLoader();
|
|
17
18
|
this.objLoader = new OBJLoader();
|
|
19
|
+
this.usdLoader = new USDLoader();
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Create a placeholder cube with shader effect
|
|
@@ -32,7 +34,9 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
32
34
|
opacity: { value: opacity },
|
|
33
35
|
fillProgress: { value: 0 },
|
|
34
36
|
time: { value: 0 },
|
|
35
|
-
isError: { value: 0 }
|
|
37
|
+
isError: { value: 0 },
|
|
38
|
+
yMin: { value: -height / 2 },
|
|
39
|
+
yMax: { value: height / 2 }
|
|
36
40
|
},
|
|
37
41
|
vertexShader: `
|
|
38
42
|
varying vec3 vPosition;
|
|
@@ -47,15 +51,17 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
47
51
|
uniform float fillProgress;
|
|
48
52
|
uniform float time;
|
|
49
53
|
uniform float isError;
|
|
54
|
+
uniform float yMin;
|
|
55
|
+
uniform float yMax;
|
|
50
56
|
varying vec3 vPosition;
|
|
51
57
|
|
|
52
58
|
void main() {
|
|
53
|
-
float normalizedY = (vPosition.y
|
|
59
|
+
float normalizedY = (vPosition.y - yMin) / (yMax - yMin); // Normalize based on actual geometry bounds
|
|
54
60
|
float alpha = opacity;
|
|
55
61
|
|
|
56
62
|
// Create fill-up effect
|
|
57
63
|
if (normalizedY > fillProgress) {
|
|
58
|
-
alpha *= 0.
|
|
64
|
+
alpha *= 0.1; // Reduce opacity for unfilled parts
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
// Error state effects
|
|
@@ -181,7 +187,7 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
181
187
|
lowResUrl,
|
|
182
188
|
enableCaching = true,
|
|
183
189
|
placeholderColor = 5227511,
|
|
184
|
-
placeholderOpacity = 0.
|
|
190
|
+
placeholderOpacity = 0.4,
|
|
185
191
|
errorColor = 16729156,
|
|
186
192
|
errorOpacity = 0.5
|
|
187
193
|
} = options;
|
|
@@ -242,14 +248,17 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
242
248
|
loadModel(type, url, isLowRes) {
|
|
243
249
|
return new Promise((resolve, reject) => {
|
|
244
250
|
const onProgress = (event) => {
|
|
245
|
-
|
|
251
|
+
let percentage = -1;
|
|
252
|
+
if (event.lengthComputable && event.total > 0 && event.loaded <= event.total) {
|
|
253
|
+
percentage = event.loaded / event.total * 100;
|
|
254
|
+
}
|
|
246
255
|
this.dispatchEvent({
|
|
247
256
|
type: "progress",
|
|
248
257
|
loaded: event.loaded,
|
|
249
258
|
total: event.total,
|
|
250
259
|
percentage
|
|
251
260
|
});
|
|
252
|
-
if (!isLowRes) {
|
|
261
|
+
if (!isLowRes && percentage >= 0) {
|
|
253
262
|
this.updatePlaceholder(percentage / 100);
|
|
254
263
|
}
|
|
255
264
|
};
|
|
@@ -291,6 +300,18 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
291
300
|
onError
|
|
292
301
|
);
|
|
293
302
|
break;
|
|
303
|
+
case "usd":
|
|
304
|
+
case "usdz":
|
|
305
|
+
this.usdLoader.load(
|
|
306
|
+
url,
|
|
307
|
+
(usd) => {
|
|
308
|
+
this.positionAssetAtBottomCenter(usd);
|
|
309
|
+
resolve(usd);
|
|
310
|
+
},
|
|
311
|
+
onProgress,
|
|
312
|
+
onError
|
|
313
|
+
);
|
|
314
|
+
break;
|
|
294
315
|
default:
|
|
295
316
|
reject(new Error(`Unsupported asset type: ${type}`));
|
|
296
317
|
}
|
|
@@ -337,4 +358,3 @@ var AssetLoader = class extends THREE.EventDispatcher {
|
|
|
337
358
|
export {
|
|
338
359
|
AssetLoader
|
|
339
360
|
};
|
|
340
|
-
//# sourceMappingURL=chunk-L4VIIJZD.mjs.map
|
|
@@ -64,6 +64,7 @@ var DualCameraControls = class extends CameraControls {
|
|
|
64
64
|
const initialCamera = initialMode === "orthographic" ? orthographicCamera : perspectiveCamera;
|
|
65
65
|
super(initialCamera, domElement);
|
|
66
66
|
this.updateClock = new THREE.Clock();
|
|
67
|
+
this.externalCamera = null;
|
|
67
68
|
const initialTarget = toVector3(
|
|
68
69
|
options.initialTarget,
|
|
69
70
|
[0, 0, 0],
|
|
@@ -99,9 +100,10 @@ var DualCameraControls = class extends CameraControls {
|
|
|
99
100
|
* Switch to the perspective camera while keeping the current framing.
|
|
100
101
|
*/
|
|
101
102
|
switchToPerspective(enableTransition = false) {
|
|
102
|
-
if (this.activeMode === "perspective") {
|
|
103
|
+
if (this.activeMode === "perspective" && !this.externalCamera) {
|
|
103
104
|
return;
|
|
104
105
|
}
|
|
106
|
+
this.externalCamera = null;
|
|
105
107
|
const target = this.getTarget(tempVec3A);
|
|
106
108
|
const position = this.getPosition(tempVec3B);
|
|
107
109
|
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
@@ -133,9 +135,10 @@ var DualCameraControls = class extends CameraControls {
|
|
|
133
135
|
* Switch to the orthographic camera while keeping the current framing.
|
|
134
136
|
*/
|
|
135
137
|
switchToOrthographic(enableTransition = false) {
|
|
136
|
-
if (this.activeMode === "orthographic") {
|
|
138
|
+
if (this.activeMode === "orthographic" && !this.externalCamera) {
|
|
137
139
|
return;
|
|
138
140
|
}
|
|
141
|
+
this.externalCamera = null;
|
|
139
142
|
const target = this.getTarget(tempVec3A);
|
|
140
143
|
const position = this.getPosition(tempVec3B);
|
|
141
144
|
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
@@ -173,6 +176,92 @@ var DualCameraControls = class extends CameraControls {
|
|
|
173
176
|
this.switchToPerspective(enableTransition);
|
|
174
177
|
}
|
|
175
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Returns true if currently using an external camera.
|
|
181
|
+
*/
|
|
182
|
+
get isUsingExternalCamera() {
|
|
183
|
+
return this.externalCamera !== null;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Sets an external camera to use with the controls.
|
|
187
|
+
* This allows using a camera created outside of DualCameraControls.
|
|
188
|
+
* Call `clearExternalCamera()` to return to the internal cameras.
|
|
189
|
+
*/
|
|
190
|
+
setCamera(camera, target, enableTransition = false) {
|
|
191
|
+
const previousCamera = this.camera;
|
|
192
|
+
this.externalCamera = camera;
|
|
193
|
+
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
194
|
+
if (camera.type === "PerspectiveCamera") {
|
|
195
|
+
;
|
|
196
|
+
camera.aspect = aspect;
|
|
197
|
+
camera.updateProjectionMatrix();
|
|
198
|
+
} else if (camera.type === "OrthographicCamera") {
|
|
199
|
+
const ortho = camera;
|
|
200
|
+
const currentHeight = (ortho.top - ortho.bottom) * 0.5;
|
|
201
|
+
const newHalfWidth = currentHeight * aspect;
|
|
202
|
+
ortho.left = -newHalfWidth;
|
|
203
|
+
ortho.right = newHalfWidth;
|
|
204
|
+
ortho.updateProjectionMatrix();
|
|
205
|
+
}
|
|
206
|
+
this.camera = camera;
|
|
207
|
+
const mode = camera.type === "PerspectiveCamera" ? "perspective" : "orthographic";
|
|
208
|
+
this.activeMode = mode;
|
|
209
|
+
this.updateInputBindingsForMode(mode);
|
|
210
|
+
const targetVec = toVector3(target, [0, 0, 0], tempVec3A);
|
|
211
|
+
void this.setLookAt(
|
|
212
|
+
camera.position.x,
|
|
213
|
+
camera.position.y,
|
|
214
|
+
camera.position.z,
|
|
215
|
+
targetVec.x,
|
|
216
|
+
targetVec.y,
|
|
217
|
+
targetVec.z,
|
|
218
|
+
enableTransition
|
|
219
|
+
);
|
|
220
|
+
this.dispatchEvent({
|
|
221
|
+
type: "externalcamerachange",
|
|
222
|
+
camera,
|
|
223
|
+
previousCamera
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Clears the external camera and returns to using the internal cameras.
|
|
228
|
+
* Will switch to the camera matching the current mode.
|
|
229
|
+
*/
|
|
230
|
+
clearExternalCamera(enableTransition = false) {
|
|
231
|
+
if (!this.externalCamera) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const target = this.getTarget(tempVec3A);
|
|
235
|
+
const position = this.getPosition(tempVec3B);
|
|
236
|
+
this.externalCamera = null;
|
|
237
|
+
const internalCamera = this.activeMode === "orthographic" ? this.orthographicCamera : this.perspectiveCamera;
|
|
238
|
+
internalCamera.position.copy(position);
|
|
239
|
+
internalCamera.quaternion.copy(this.camera.quaternion);
|
|
240
|
+
internalCamera.up.copy(this.camera.up);
|
|
241
|
+
const aspect = resolveAspect(this.renderer, this.domElementRef);
|
|
242
|
+
if (this.activeMode === "orthographic") {
|
|
243
|
+
this.updateOrthographicFrustum(position, target, aspect);
|
|
244
|
+
} else {
|
|
245
|
+
this.perspectiveCamera.aspect = aspect;
|
|
246
|
+
this.perspectiveCamera.updateProjectionMatrix();
|
|
247
|
+
}
|
|
248
|
+
this.camera = internalCamera;
|
|
249
|
+
void this.setLookAt(
|
|
250
|
+
position.x,
|
|
251
|
+
position.y,
|
|
252
|
+
position.z,
|
|
253
|
+
target.x,
|
|
254
|
+
target.y,
|
|
255
|
+
target.z,
|
|
256
|
+
enableTransition
|
|
257
|
+
);
|
|
258
|
+
this.dispatchEvent({
|
|
259
|
+
type: "modechange",
|
|
260
|
+
mode: this.activeMode,
|
|
261
|
+
previousMode: this.activeMode,
|
|
262
|
+
camera: internalCamera
|
|
263
|
+
});
|
|
264
|
+
}
|
|
176
265
|
/**
|
|
177
266
|
* Update camera projection parameters when the viewport size changes.
|
|
178
267
|
*/
|
|
@@ -266,4 +355,3 @@ function resolveAspect(renderer, domElement) {
|
|
|
266
355
|
export {
|
|
267
356
|
DualCameraControls
|
|
268
357
|
};
|
|
269
|
-
//# sourceMappingURL=chunk-WMHEIUXE.mjs.map
|