@nebula-spatial/viewer 0.4.3 → 0.4.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.
@@ -1,7 +1,7 @@
1
1
  import { DataTexture as N, LinearMipmapLinearFilter as oe, LinearFilter as ae, LoadingManager as ie, Loader as le, Texture as X, TextureLoader as ce, LinearSRGBColorSpace as G, SRGBColorSpace as ue, RGBAFormat as K, UnsignedByteType as J, NoColorSpace as fe, Mesh as pe, MeshPhysicalMaterial as Q, MeshPhongMaterial as k, MeshLambertMaterial as de, Color as _, Quaternion as Z, Vector3 as ee, Group as he, Box3 as me } from "three";
2
2
  import { DRACOLoader as ge } from "three/examples/jsm/loaders/DRACOLoader.js";
3
3
  import { GLTFLoader as ye } from "three/examples/jsm/loaders/GLTFLoader.js";
4
- import { S as we, d as Y } from "./stage-BKqg5vNe.js";
4
+ import { S as we, d as Y } from "./stage-D113SHD8.js";
5
5
  import { TGALoader as be } from "three/examples/jsm/loaders/TGALoader.js";
6
6
  import { FBXLoader as xe } from "three/examples/jsm/loaders/FBXLoader.js";
7
7
  import { unzlibSync as Ee } from "three/examples/jsm/libs/fflate.module.js";
@@ -177,7 +177,7 @@ async function Ae(e, t, n) {
177
177
  return l = new xe(m).parse(e, ""), await Promise.all(p), t.signal.throwIfAborted(), { root: l, textures: d };
178
178
  } catch (u) {
179
179
  if (s.abort(u), await Promise.allSettled(p), l) {
180
- const { disposeModelResources: w } = await import("./stage-BKqg5vNe.js").then((f) => f.r);
180
+ const { disposeModelResources: w } = await import("./stage-D113SHD8.js").then((f) => f.r);
181
181
  w(l, d);
182
182
  } else for (const w of d) w.dispose();
183
183
  throw u;
@@ -1,9 +1,9 @@
1
1
  var y = Object.defineProperty;
2
- var b = (u, t, e) => t in u ? y(u, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : u[t] = e;
3
- var a = (u, t, e) => b(u, typeof t != "symbol" ? t + "" : t, e);
4
- import * as o from "three";
5
- import { V as p } from "./index-BDo6voB2.js";
6
- const v = 1, M = (
2
+ var b = (u, e, t) => e in u ? y(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
3
+ var a = (u, e, t) => b(u, typeof e != "symbol" ? e + "" : e, t);
4
+ import * as r from "three";
5
+ import { V as g } from "./index-D-o1ODOX.js";
6
+ const m = 1, M = (
7
7
  /* glsl */
8
8
  `
9
9
  uniform mat4 textureMatrix;
@@ -86,29 +86,29 @@ const v = 1, M = (
86
86
  }
87
87
  `
88
88
  );
89
- class P extends o.Mesh {
90
- constructor({ size: e = 20, textureWidth: i = 512, textureHeight: r = 512 } = {}) {
91
- const s = new o.Matrix4(), l = new o.WebGLRenderTarget(i, r, {
92
- type: o.HalfFloatType,
93
- minFilter: o.LinearFilter,
94
- magFilter: o.LinearFilter,
95
- format: o.RGBAFormat,
89
+ class P extends r.Mesh {
90
+ constructor({ size: t = 20, textureWidth: i = 512, textureHeight: o = 512 } = {}) {
91
+ const s = new r.Matrix4(), l = new r.WebGLRenderTarget(i, o, {
92
+ type: r.HalfFloatType,
93
+ minFilter: r.LinearFilter,
94
+ magFilter: r.LinearFilter,
95
+ format: r.RGBAFormat,
96
96
  depthBuffer: !0,
97
97
  samples: 0
98
- }), n = new o.ShaderMaterial({
98
+ }), n = new r.ShaderMaterial({
99
99
  uniforms: {
100
100
  tDiffuse: { value: l.texture },
101
101
  textureMatrix: { value: s },
102
- resolution: { value: new o.Vector2(i, r) },
103
- fineGridColor: { value: new o.Color(2502702) },
104
- coarseGridColor: { value: new o.Color(7897726) },
102
+ resolution: { value: new r.Vector2(i, o) },
103
+ fineGridColor: { value: new r.Color(2502702) },
104
+ coarseGridColor: { value: new r.Color(7897726) },
105
105
  blurIntensity: { value: 1.7 },
106
106
  reflectionMix: { value: 0.07 },
107
107
  gridOpacity: { value: 1 },
108
108
  gridScale: { value: 0.2 },
109
- groundCenter: { value: new o.Vector2() },
110
- maxRadius: { value: e * 0.5 },
111
- fadeSoftness: { value: e * 0.325 }
109
+ groundCenter: { value: new r.Vector2() },
110
+ maxRadius: { value: t * 0.5 },
111
+ fadeSoftness: { value: t * 0.325 }
112
112
  },
113
113
  vertexShader: M,
114
114
  fragmentShader: w,
@@ -117,7 +117,7 @@ class P extends o.Mesh {
117
117
  toneMapped: !0,
118
118
  fog: !1
119
119
  });
120
- super(new o.PlaneGeometry(e, e), n);
120
+ super(new r.PlaneGeometry(t, t), n);
121
121
  a(this, "renderTarget");
122
122
  a(this, "textureMatrix");
123
123
  a(this, "virtualCamera");
@@ -132,11 +132,11 @@ class P extends o.Mesh {
132
132
  a(this, "view");
133
133
  a(this, "target");
134
134
  a(this, "q");
135
- this.renderTarget = l, this.textureMatrix = s, this.virtualCamera = new o.PerspectiveCamera(), this.virtualCamera.layers.set(v), this.clipBias = 3e-3, this.frustumCulled = !1, this.renderOrder = 1, this.position.z = 2e-3, this.reflectorPlane = new o.Plane(), this.normal = new o.Vector3(), this.reflectorWorldPosition = new o.Vector3(), this.cameraWorldPosition = new o.Vector3(), this.rotationMatrix = new o.Matrix4(), this.lookAtPosition = new o.Vector3(0, 0, -1), this.clipPlane = new o.Vector4(), this.view = new o.Vector3(), this.target = new o.Vector3(), this.q = new o.Vector4();
135
+ this.renderTarget = l, this.textureMatrix = s, this.virtualCamera = new r.PerspectiveCamera(), this.virtualCamera.layers.set(m), this.clipBias = 3e-3, this.frustumCulled = !1, this.renderOrder = 1, this.position.z = 2e-3, this.reflectorPlane = new r.Plane(), this.normal = new r.Vector3(), this.reflectorWorldPosition = new r.Vector3(), this.cameraWorldPosition = new r.Vector3(), this.rotationMatrix = new r.Matrix4(), this.lookAtPosition = new r.Vector3(0, 0, -1), this.clipPlane = new r.Vector4(), this.view = new r.Vector3(), this.target = new r.Vector3(), this.q = new r.Vector4();
136
136
  }
137
- renderReflection(e, i, r) {
138
- if (this.reflectorWorldPosition.setFromMatrixPosition(this.matrixWorld), this.cameraWorldPosition.setFromMatrixPosition(r.matrixWorld), this.rotationMatrix.extractRotation(this.matrixWorld), this.normal.set(0, 0, 1).applyMatrix4(this.rotationMatrix), this.view.subVectors(this.reflectorWorldPosition, this.cameraWorldPosition), this.view.dot(this.normal) > 0) return;
139
- this.view.reflect(this.normal).negate().add(this.reflectorWorldPosition), this.rotationMatrix.extractRotation(r.matrixWorld), this.lookAtPosition.set(0, 0, -1).applyMatrix4(this.rotationMatrix).add(this.cameraWorldPosition), this.target.subVectors(this.reflectorWorldPosition, this.lookAtPosition).reflect(this.normal).negate().add(this.reflectorWorldPosition), this.virtualCamera.position.copy(this.view), this.virtualCamera.up.set(0, 1, 0).applyMatrix4(this.rotationMatrix).reflect(this.normal), this.virtualCamera.lookAt(this.target), this.virtualCamera.near = r.near, this.virtualCamera.far = r.far, this.virtualCamera.updateMatrixWorld(), this.virtualCamera.projectionMatrix.copy(r.projectionMatrix), this.textureMatrix.set(
137
+ renderReflection(t, i, o) {
138
+ if (this.reflectorWorldPosition.setFromMatrixPosition(this.matrixWorld), this.cameraWorldPosition.setFromMatrixPosition(o.matrixWorld), this.rotationMatrix.extractRotation(this.matrixWorld), this.normal.set(0, 0, 1).applyMatrix4(this.rotationMatrix), this.view.subVectors(this.reflectorWorldPosition, this.cameraWorldPosition), this.view.dot(this.normal) > 0) return;
139
+ this.view.reflect(this.normal).negate().add(this.reflectorWorldPosition), this.rotationMatrix.extractRotation(o.matrixWorld), this.lookAtPosition.set(0, 0, -1).applyMatrix4(this.rotationMatrix).add(this.cameraWorldPosition), this.target.subVectors(this.reflectorWorldPosition, this.lookAtPosition).reflect(this.normal).negate().add(this.reflectorWorldPosition), this.virtualCamera.position.copy(this.view), this.virtualCamera.up.set(0, 1, 0).applyMatrix4(this.rotationMatrix).reflect(this.normal), this.virtualCamera.lookAt(this.target), this.virtualCamera.near = o.near, this.virtualCamera.far = o.far, this.virtualCamera.updateMatrixWorld(), this.virtualCamera.projectionMatrix.copy(o.projectionMatrix), this.textureMatrix.set(
140
140
  0.5,
141
141
  0,
142
142
  0,
@@ -166,31 +166,31 @@ class P extends o.Mesh {
166
166
  -1,
167
167
  (1 + s.elements[10]) / s.elements[14]
168
168
  ), this.clipPlane.multiplyScalar(2 / this.clipPlane.dot(this.q)), s.elements[2] = this.clipPlane.x, s.elements[6] = this.clipPlane.y, s.elements[10] = this.clipPlane.z + 1 - this.clipBias, s.elements[14] = this.clipPlane.w, this.virtualCamera.projectionMatrixInverse.copy(s).invert();
169
- const l = e.getRenderTarget(), n = e.xr.enabled, c = e.shadowMap.autoUpdate, d = e.shadowMap.enabled;
169
+ const l = t.getRenderTarget(), n = t.xr.enabled, c = t.shadowMap.autoUpdate, d = t.shadowMap.enabled;
170
170
  try {
171
- e.xr.enabled = !1, e.shadowMap.enabled = !1, e.shadowMap.autoUpdate = !1, e.setRenderTarget(this.renderTarget), e.state.buffers.depth.setMask(!0), e.clear(), e.render(i, this.virtualCamera);
171
+ t.xr.enabled = !1, t.shadowMap.enabled = !1, t.shadowMap.autoUpdate = !1, t.setRenderTarget(this.renderTarget), t.state.buffers.depth.setMask(!0), t.clear(), t.render(i, this.virtualCamera);
172
172
  } finally {
173
- e.setRenderTarget(l), e.xr.enabled = n, e.shadowMap.enabled = d, e.shadowMap.autoUpdate = c;
173
+ t.setRenderTarget(l), t.xr.enabled = n, t.shadowMap.enabled = d, t.shadowMap.autoUpdate = c;
174
174
  }
175
175
  }
176
- setRenderSize(e, i) {
177
- this.renderTarget.setSize(e, i), this.material.uniforms.resolution.value.set(e, i);
176
+ setRenderSize(t, i) {
177
+ this.renderTarget.setSize(t, i), this.material.uniforms.resolution.value.set(t, i);
178
178
  }
179
179
  // Radius is in world units; the outer 65% fades before the square mesh edge.
180
- setRadius(e, i, r = this.material.uniforms.groundCenter.value) {
181
- this.scale.setScalar(e * 2 / this.geometry.parameters.width), this.position.x = r.x, this.position.y = r.y, this.material.uniforms.groundCenter.value.set(r.x, r.y), this.material.uniforms.gridScale.value = i, this.material.uniforms.maxRadius.value = e, this.material.uniforms.fadeSoftness.value = e * 0.65;
180
+ setRadius(t, i, o = this.material.uniforms.groundCenter.value) {
181
+ this.scale.setScalar(t * 2 / this.geometry.parameters.width), this.position.x = o.x, this.position.y = o.y, this.material.uniforms.groundCenter.value.set(o.x, o.y), this.material.uniforms.gridScale.value = i, this.material.uniforms.maxRadius.value = t, this.material.uniforms.fadeSoftness.value = t * 0.65;
182
182
  }
183
183
  }
184
- const g = {
184
+ const v = {
185
185
  light: {
186
- background: p.light,
186
+ background: g.light,
187
187
  fineGrid: 5859168,
188
188
  coarseGrid: 3427136,
189
189
  gridOpacity: 0.85,
190
190
  reflectionMix: 0.06
191
191
  },
192
192
  dark: {
193
- background: p.dark,
193
+ background: g.dark,
194
194
  fineGrid: 7375236,
195
195
  coarseGrid: 5552554,
196
196
  gridOpacity: 0.9,
@@ -200,22 +200,22 @@ const g = {
200
200
  simulation: 0.68,
201
201
  model: 1.4
202
202
  };
203
- function x(u, t = []) {
203
+ function x(u, e = []) {
204
204
  var l;
205
- const e = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), r = new Set(t), s = /* @__PURE__ */ new Set();
205
+ const t = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), o = new Set(e), s = /* @__PURE__ */ new Set();
206
206
  u.traverse((n) => {
207
207
  const c = n;
208
- c.geometry && e.add(c.geometry);
208
+ c.geometry && t.add(c.geometry);
209
209
  for (const d of Array.isArray(c.material) ? c.material : [c.material])
210
210
  if (d) {
211
211
  i.add(d);
212
212
  for (const h of Object.values(d))
213
- S(h) && r.add(h);
213
+ S(h) && o.add(h);
214
214
  }
215
215
  });
216
- for (const n of e) n.dispose();
216
+ for (const n of t) n.dispose();
217
217
  for (const n of i) n.dispose();
218
- for (const n of r) {
218
+ for (const n of o) {
219
219
  const c = (l = n.source) == null ? void 0 : l.data;
220
220
  c && typeof c.close == "function" && s.add(c), n.dispose();
221
221
  }
@@ -224,27 +224,27 @@ function x(u, t = []) {
224
224
  function S(u) {
225
225
  return !!(u && typeof u == "object" && u.isTexture);
226
226
  }
227
- const F = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
227
+ const V = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
228
228
  __proto__: null,
229
229
  disposeModelResources: x
230
230
  }, Symbol.toStringTag, { value: "Module" })), f = 2213822, G = 6000111, R = 6;
231
- function T(u, t, e) {
232
- t.updateMatrixWorld();
233
- const i = new o.Vector3();
234
- return t.getWorldDirection(i).normalize(), u.setFromNormalAndCoplanarPoint(i, e);
231
+ function T(u, e, t) {
232
+ e.updateMatrixWorld();
233
+ const i = new r.Vector3();
234
+ return e.getWorldDirection(i).normalize(), u.setFromNormalAndCoplanarPoint(i, t);
235
235
  }
236
236
  class W {
237
- constructor(t, e = "dark", i, r = "simulation") {
238
- a(this, "root", new o.Group());
237
+ constructor(e, t = "dark", i, o = "simulation") {
238
+ a(this, "root", new r.Group());
239
239
  a(this, "reflector", new P({ size: 100, textureWidth: 256, textureHeight: 256 }));
240
240
  a(this, "values");
241
241
  a(this, "fog");
242
- a(this, "raycaster", new o.Raycaster());
243
- a(this, "pointer", new o.Vector2());
244
- a(this, "dragPlane", new o.Plane());
245
- a(this, "dragTarget", new o.Vector3());
246
- a(this, "dragIntersection", new o.Vector3());
247
- a(this, "dragOffset", new o.Vector3());
242
+ a(this, "raycaster", new r.Raycaster());
243
+ a(this, "pointer", new r.Vector2());
244
+ a(this, "dragPlane", new r.Plane());
245
+ a(this, "dragTarget", new r.Vector3());
246
+ a(this, "dragIntersection", new r.Vector3());
247
+ a(this, "dragOffset", new r.Vector3());
248
248
  a(this, "bodyGroups", /* @__PURE__ */ new Map());
249
249
  a(this, "auxiliaries", /* @__PURE__ */ new Set());
250
250
  a(this, "forceLine");
@@ -254,24 +254,36 @@ class W {
254
254
  a(this, "size", "");
255
255
  a(this, "groundVisible");
256
256
  a(this, "disposed", !1);
257
- this.model = t, this.runtime = i, this.presentation = r, this.values = g[e];
258
- const s = this.values, l = new o.Box3().setFromObject(t), n = Math.max(...l.getSize(new o.Vector3()).toArray());
257
+ this.model = e, this.runtime = i, this.presentation = o, this.values = v[t];
258
+ const s = this.values, l = new r.Box3().setFromObject(e), n = Math.max(...l.getSize(new r.Vector3()).toArray());
259
259
  if (!Number.isFinite(n) || n <= 0) throw new Error("Empty simulation geometry.");
260
- this.root.add(t), this.forceLine = this.createForceLine(), this.root.add(this.forceLine), t.traverse((m) => {
261
- m instanceof o.Mesh && m.layers.enable(v);
260
+ this.root.add(e), this.forceLine = this.createForceLine(), this.root.add(this.forceLine), e.traverse((p) => {
261
+ p instanceof r.Mesh && p.layers.enable(m);
262
262
  }), this.root.add(this.reflector);
263
- const c = Math.max(l.getSize(new o.Vector3()).length() * 0.5, 0.02), d = this.reflector.material.uniforms;
264
- d.fineGridColor.value.setHex(s.fineGrid), d.coarseGridColor.value.setHex(s.coarseGrid), d.gridOpacity.value = s.gridOpacity, d.reflectionMix.value = s.reflectionMix, this.layoutGround(l, c), this.groundVisible = r === "simulation", this.setGroundVisible(this.groundVisible);
265
- const h = c / Math.sin(o.MathUtils.degToRad(38) / 2) * 1.25;
266
- this.fog = new o.Fog(s.background, h * 2.5, h * 8);
263
+ const c = Math.max(l.getSize(new r.Vector3()).length() * 0.5, 0.02), d = this.reflector.material.uniforms;
264
+ d.fineGridColor.value.setHex(s.fineGrid), d.coarseGridColor.value.setHex(s.coarseGrid), d.gridOpacity.value = s.gridOpacity, d.reflectionMix.value = s.reflectionMix, this.layoutGround(l, c), this.groundVisible = o === "simulation", this.setGroundVisible(this.groundVisible);
265
+ const h = c / Math.sin(r.MathUtils.degToRad(38) / 2) * 1.25;
266
+ this.fog = new r.Fog(s.background, h * 2.5, h * 8);
267
267
  }
268
- setTheme(t) {
268
+ setRuntime(e) {
269
+ this.disposed || this.runtime === e || (this.endGrab(), this.runtime = e, this.bodyGroups.clear());
270
+ }
271
+ replaceModel(e, t = !0) {
272
+ this.disposed || e === this.model || (this.endGrab(), this.bodyGroups.clear(), this.model.removeFromParent(), this.model = e, this.root.add(e), e.traverse((i) => {
273
+ i instanceof r.Mesh && i.layers.enable(m);
274
+ }), t && this.reseatGround());
275
+ }
276
+ resetGround() {
277
+ var e;
278
+ this.disposed || (this.reflector.position.z = (((e = this.runtime) == null ? void 0 : e.defaultGroundHeight) ?? 0) + 2e-3);
279
+ }
280
+ setTheme(e) {
269
281
  if (this.disposed) return;
270
- const e = this.values = g[t], i = this.reflector.material.uniforms;
271
- i.fineGridColor.value.setHex(e.fineGrid), i.coarseGridColor.value.setHex(e.coarseGrid), i.gridOpacity.value = e.gridOpacity, i.reflectionMix.value = e.reflectionMix, this.fog.color.setHex(e.background);
282
+ const t = this.values = v[e], i = this.reflector.material.uniforms;
283
+ i.fineGridColor.value.setHex(t.fineGrid), i.coarseGridColor.value.setHex(t.coarseGrid), i.gridOpacity.value = t.gridOpacity, i.reflectionMix.value = t.reflectionMix, this.fog.color.setHex(t.background);
272
284
  }
273
- layoutGround(t, e) {
274
- this.reflector.setRadius(e * 8, Math.pow(10, Math.floor(Math.log10(Math.max(e, 0.01)))), t.getCenter(new o.Vector3()));
285
+ layoutGround(e, t) {
286
+ this.reflector.setRadius(t * 8, Math.pow(10, Math.floor(Math.log10(Math.max(t, 0.01)))), e.getCenter(new r.Vector3()));
275
287
  }
276
288
  /**
277
289
  * Re-fits the ground disc and reflection to the model's current world bounds.
@@ -282,113 +294,115 @@ class W {
282
294
  reseatGround() {
283
295
  if (this.disposed) return;
284
296
  this.root.updateMatrixWorld(!0);
285
- const t = new o.Box3().setFromObject(this.model);
286
- t.isEmpty() || this.layoutGround(t, Math.max(t.getSize(new o.Vector3()).length() * 0.5, 0.02));
297
+ const e = new r.Box3().setFromObject(this.model);
298
+ e.isEmpty() || this.layoutGround(e, Math.max(e.getSize(new r.Vector3()).length() * 0.5, 0.02));
287
299
  }
288
300
  createForceLine() {
289
- const t = new o.BufferGeometry().setFromPoints([
290
- new o.Vector3(),
291
- new o.Vector3()
292
- ]), e = new o.LineBasicMaterial({
301
+ const e = new r.BufferGeometry().setFromPoints([
302
+ new r.Vector3(),
303
+ new r.Vector3()
304
+ ]), t = new r.LineBasicMaterial({
293
305
  color: f,
294
306
  depthTest: !1,
295
307
  transparent: !0
296
- }), i = new o.Line(t, e);
308
+ }), i = new r.Line(e, t);
297
309
  return i.renderOrder = 1e3, i.visible = !1, i;
298
310
  }
299
- findBodyGroup(t) {
311
+ findBodyGroup(e) {
300
312
  var i;
301
- let e = t;
302
- for (; e && e !== this.model && e !== this.root; ) {
303
- if (typeof ((i = e.userData) == null ? void 0 : i.bodyId) == "number") return e;
304
- e = e.parent;
313
+ let t = e;
314
+ for (; t && t !== this.model && t !== this.root; ) {
315
+ if (typeof ((i = t.userData) == null ? void 0 : i.bodyId) == "number") return t;
316
+ t = t.parent;
305
317
  }
306
318
  return null;
307
319
  }
308
- getBodyGroup(t) {
309
- let e = this.bodyGroups.get(t);
310
- return e || this.model.traverse((i) => {
311
- var r;
312
- ((r = i.userData) == null ? void 0 : r.bodyId) === t && (e = i, this.bodyGroups.set(t, i));
313
- }), e;
320
+ getBodyGroup(e) {
321
+ let t = this.bodyGroups.get(e);
322
+ return t || this.model.traverse((i) => {
323
+ var o;
324
+ ((o = i.userData) == null ? void 0 : o.bodyId) === e && (t = i, this.bodyGroups.set(e, i));
325
+ }), t;
314
326
  }
315
- pointerRay(t, e, i) {
316
- const r = i.getBoundingClientRect();
327
+ pointerRay(e, t, i) {
328
+ const o = i.getBoundingClientRect();
317
329
  this.pointer.set(
318
- (t.clientX - r.left) / r.width * 2 - 1,
319
- -((t.clientY - r.top) / r.height) * 2 + 1
320
- ), this.raycaster.setFromCamera(this.pointer, e);
330
+ (e.clientX - o.left) / o.width * 2 - 1,
331
+ -((e.clientY - o.top) / o.height) * 2 + 1
332
+ ), this.raycaster.setFromCamera(this.pointer, t);
321
333
  }
322
- setForceBoost(t) {
323
- var e;
324
- !((e = this.runtime) != null && e.grab) || t === this.forceBoosted || (this.forceBoosted = t, this.runtime.updateGrabStrength(t ? R : 1), this.forceLine.material.color.setHex(t ? G : f));
334
+ setForceBoost(e) {
335
+ var t;
336
+ !((t = this.runtime) != null && t.grab) || e === this.forceBoosted || (this.forceBoosted = e, this.runtime.updateGrabStrength(e ? R : 1), this.forceLine.material.color.setHex(e ? G : f));
325
337
  }
326
- beginGrab(t, e, i) {
338
+ beginGrab(e, t, i) {
327
339
  if (!this.runtime || this.disposed) return !1;
328
- this.pointerRay(t, e, i);
329
- const r = this.raycaster.intersectObject(this.model, !0).find((c) => c.object.isMesh);
330
- if (!r) return !1;
331
- const s = this.findBodyGroup(r.object);
340
+ this.pointerRay(e, t, i);
341
+ const o = this.raycaster.intersectObject(this.model, !0).find((c) => c.object.isMesh);
342
+ if (!o) return !1;
343
+ const s = this.findBodyGroup(o.object);
332
344
  if (!s) return !1;
333
- const l = s.worldToLocal(r.point.clone());
334
- this.dragTarget.copy(r.point), T(this.dragPlane, e, r.point), this.dragOffset.set(0, 0, 0);
335
- const n = this.root.worldToLocal(r.point.clone());
345
+ const l = s.worldToLocal(o.point.clone());
346
+ this.dragTarget.copy(o.point), T(this.dragPlane, t, o.point), this.dragOffset.set(0, 0, 0);
347
+ const n = this.root.worldToLocal(o.point.clone());
336
348
  return this.bodyGroups.set(s.userData.bodyId, s), this.runtime.beginGrab({
337
349
  bodyId: s.userData.bodyId,
338
350
  localPoint: [l.x, l.y, l.z],
339
351
  target: [n.x, n.y, n.z]
340
- }), this.forceBoosted = !1, this.setForceBoost(t.shiftKey), this.forceLine.visible = !0, this.updateForceLine(), this.grabCanvas = i, i != null && i.style && (this.previousCursor = i.style.cursor, i.style.cursor = "grabbing"), !0;
352
+ }), this.forceBoosted = !1, this.setForceBoost(e.shiftKey), this.forceLine.visible = !0, this.updateForceLine(), this.grabCanvas = i, i != null && i.style && (this.previousCursor = i.style.cursor, i.style.cursor = "grabbing"), !0;
341
353
  }
342
- moveGrab(t, e, i) {
354
+ moveGrab(e, t, i) {
343
355
  var s;
344
356
  if (!((s = this.runtime) != null && s.grab)) return;
345
- if (this.pointerRay(t, e, i), this.setForceBoost(t.shiftKey), i != null && i.style && i.style.cursor !== "grabbing" && (i.style.cursor = "grabbing"), this.raycaster.ray.intersectPlane(this.dragPlane, this.dragIntersection))
357
+ if (this.pointerRay(e, t, i), this.setForceBoost(e.shiftKey), i != null && i.style && i.style.cursor !== "grabbing" && (i.style.cursor = "grabbing"), this.raycaster.ray.intersectPlane(this.dragPlane, this.dragIntersection))
346
358
  this.dragTarget.copy(this.dragIntersection).add(this.dragOffset);
347
359
  else
348
360
  return;
349
- const r = this.root.worldToLocal(this.dragTarget.clone());
350
- this.runtime.updateGrabTarget([r.x, r.y, r.z]), this.updateForceLine();
361
+ const o = this.root.worldToLocal(this.dragTarget.clone());
362
+ this.runtime.updateGrabTarget([o.x, o.y, o.z]), this.updateForceLine();
351
363
  }
352
364
  endGrab() {
353
- var t;
354
- this.runtime && (this.runtime.endGrab(), this.forceBoosted = !1, this.forceLine.visible = !1, this.forceLine.material.color.setHex(f), (t = this.grabCanvas) != null && t.style && (this.grabCanvas.style.cursor = this.previousCursor), this.grabCanvas = null);
365
+ var e;
366
+ this.runtime && (this.runtime.endGrab(), this.forceBoosted = !1, this.forceLine.visible = !1, this.forceLine.material.color.setHex(f), (e = this.grabCanvas) != null && e.style && (this.grabCanvas.style.cursor = this.previousCursor), this.grabCanvas = null);
355
367
  }
356
368
  updateForceLine() {
357
369
  var n;
358
- const t = (n = this.runtime) == null ? void 0 : n.grab;
359
- if (!t) return;
360
- const e = this.getBodyGroup(t.bodyId);
370
+ const e = (n = this.runtime) == null ? void 0 : n.grab;
361
371
  if (!e) return;
362
- const i = new o.Vector3().fromArray(t.localPoint), r = e.localToWorld(i), s = this.root.worldToLocal(r), l = this.forceLine.geometry.attributes.position;
363
- l.setXYZ(0, s.x, s.y, s.z), l.setXYZ(1, t.target[0], t.target[1], t.target[2]), l.needsUpdate = !0;
364
- }
365
- beforeRender(t, e, i) {
366
- var l;
367
- const r = {
368
- tone: t.toneMapping,
369
- exposure: t.toneMappingExposure,
370
- color: t.outputColorSpace,
371
- environment: e.environment,
372
- fog: e.fog,
373
- background: e.background
372
+ const t = this.getBodyGroup(e.bodyId);
373
+ if (!t) return;
374
+ const i = new r.Vector3().fromArray(e.localPoint), o = t.localToWorld(i), s = this.root.worldToLocal(o), l = this.forceLine.geometry.attributes.position;
375
+ l.setXYZ(0, s.x, s.y, s.z), l.setXYZ(1, e.target[0], e.target[1], e.target[2]), l.needsUpdate = !0;
376
+ }
377
+ beforeRender(e, t, i) {
378
+ var l, n;
379
+ const o = {
380
+ tone: e.toneMapping,
381
+ exposure: e.toneMappingExposure,
382
+ color: e.outputColorSpace,
383
+ environment: t.environment,
384
+ fog: t.fog,
385
+ background: t.background
374
386
  }, s = () => {
375
- t.toneMapping = r.tone, t.toneMappingExposure = r.exposure, t.outputColorSpace = r.color, e.environment = r.environment, e.fog = r.fog, e.background = r.background;
387
+ e.toneMapping = o.tone, e.toneMappingExposure = o.exposure, e.outputColorSpace = o.color, t.environment = o.environment, t.fog = o.fog, t.background = o.background;
376
388
  };
377
389
  if (this.disposed) return s;
378
390
  try {
379
- (l = this.runtime) != null && l.grab && this.updateForceLine(), t.toneMapping = o.ACESFilmicToneMapping, t.toneMappingExposure = C[this.presentation], t.outputColorSpace = o.SRGBColorSpace, e.background = new o.Color(this.values.background), e.fog = this.fog;
380
- const n = t.getSize(new o.Vector2()), c = `${n.x}:${n.y}`;
381
- return c !== this.size && (this.size = c, this.reflector.setRenderSize(Math.max(1, Math.floor(n.x * 0.35)), Math.max(1, Math.floor(n.y * 0.35)))), e.updateMatrixWorld(!0), i.updateMatrixWorld(!0), this.groundVisible && i instanceof o.PerspectiveCamera && this.reflector.renderReflection(t, e, i), s;
382
- } catch (n) {
383
- throw s(), n;
391
+ (l = this.runtime) != null && l.grab && this.updateForceLine();
392
+ const c = (n = this.runtime) == null ? void 0 : n.defaultGroundHeight;
393
+ c !== void 0 && (this.reflector.position.z = c + 2e-3), e.toneMapping = r.ACESFilmicToneMapping, e.toneMappingExposure = C[this.presentation], e.outputColorSpace = r.SRGBColorSpace, t.background = new r.Color(this.values.background), t.fog = this.fog;
394
+ const d = e.getSize(new r.Vector2()), h = `${d.x}:${d.y}`;
395
+ return h !== this.size && (this.size = h, this.reflector.setRenderSize(Math.max(1, Math.floor(d.x * 0.35)), Math.max(1, Math.floor(d.y * 0.35)))), t.updateMatrixWorld(!0), i.updateMatrixWorld(!0), this.groundVisible && i instanceof r.PerspectiveCamera && this.reflector.renderReflection(e, t, i), s;
396
+ } catch (c) {
397
+ throw s(), c;
384
398
  }
385
399
  }
386
400
  /**
387
401
  * The reflector mesh carries both the grid lines and the reflection. Hiding
388
402
  * it also skips the reflection render pass, which only feeds its shader.
389
403
  */
390
- setGroundVisible(t) {
391
- this.groundVisible = t, this.reflector.visible = t;
404
+ setGroundVisible(e) {
405
+ this.groundVisible = e, this.reflector.visible = e;
392
406
  }
393
407
  getGroundVisible() {
394
408
  return this.groundVisible;
@@ -399,20 +413,23 @@ class W {
399
413
  * so nesting hidden aids (collision meshes, which are far larger than the
400
414
  * visual shell) would inflate both the reflection extent and the camera fit.
401
415
  */
402
- attachAuxiliary(t) {
403
- this.auxiliaries.add(t), this.root.add(t);
416
+ attachAuxiliary(e) {
417
+ this.auxiliaries.add(e), this.root.add(e);
418
+ }
419
+ detachAuxiliary(e) {
420
+ this.auxiliaries.delete(e) && e.removeFromParent();
404
421
  }
405
422
  getModelBounds() {
406
423
  this.root.updateMatrixWorld(!0);
407
- const t = new o.Box3().setFromObject(this.model);
408
- if (!t.isEmpty()) return t;
409
- const e = new o.Box3();
410
- return e.min.set(-5e3, -5e3, -5e3), e.max.set(5e3, 5e3, 5e3), e;
424
+ const e = new r.Box3().setFromObject(this.model);
425
+ if (!e.isEmpty()) return e;
426
+ const t = new r.Box3();
427
+ return t.min.set(-5e3, -5e3, -5e3), t.max.set(5e3, 5e3, 5e3), t;
411
428
  }
412
429
  dispose() {
413
430
  if (!this.disposed) {
414
431
  this.disposed = !0, this.endGrab(), this.model.removeFromParent();
415
- for (const t of this.auxiliaries) t.removeFromParent();
432
+ for (const e of this.auxiliaries) e.removeFromParent();
416
433
  this.auxiliaries.clear(), this.root.removeFromParent(), this.reflector.renderTarget.dispose(), x(this.root);
417
434
  }
418
435
  }
@@ -420,5 +437,5 @@ class W {
420
437
  export {
421
438
  W as S,
422
439
  x as d,
423
- F as r
440
+ V as r
424
441
  };
package/dist/types.d.ts CHANGED
@@ -88,6 +88,8 @@ export interface ViewerFitViewOptions {
88
88
  viewMode?: ViewerViewMode;
89
89
  }
90
90
  export interface ViewerPickOptions {
91
+ /** Stop at the nearest intersection when accelerated picking is available. */
92
+ firstHitOnly?: boolean;
91
93
  roots?: readonly Object3D[];
92
94
  recursive?: boolean;
93
95
  includeInvisible?: boolean;
@@ -33,6 +33,8 @@ export interface ViewerUiOptions {
33
33
  cad?: ViewerCadUiOptions;
34
34
  /** Shared scene controls for model and simulation assets, gated by capabilities. */
35
35
  scene?: ViewerSceneUiOptions;
36
+ /** Built-in URDF review workbench. Defaults to true for preset 'auto'. */
37
+ urdf?: boolean;
36
38
  }
37
39
  export interface ViewerUiTokens {
38
40
  accent?: string;