@nebula-spatial/viewer 0.4.3 → 0.4.5

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.
@@ -0,0 +1,795 @@
1
+ var je = Object.defineProperty;
2
+ var Se = (s, e, o) => e in s ? je(s, e, { enumerable: !0, configurable: !0, writable: !0, value: o }) : s[e] = o;
3
+ var N = (s, e, o) => Se(s, typeof e != "symbol" ? e + "" : e, o);
4
+ import { d as x, S as H } from "./stage-BPiGudYP.js";
5
+ import { LineBasicMaterial as Me, WireframeGeometry as ve, LineSegments as Oe, EdgesGeometry as W, Vector3 as ie, Color as Ae, LinearSRGBColorSpace as Ge, SRGBColorSpace as he, MeshPhysicalMaterial as Ce, Float32BufferAttribute as q, DataTexture as Pe, RGBAFormat as Re, UnsignedByteType as Le, NoColorSpace as Te, RepeatWrapping as Ue, LinearFilter as Fe, LinearMipmapLinearFilter as Ne, BufferGeometry as Q, Group as ae, Mesh as le, PlaneGeometry as _e, BoxGeometry as ge, SphereGeometry as X, Matrix4 as De, CylinderGeometry as ye, CapsuleGeometry as be, BufferAttribute as Y } from "three";
6
+ function ue(s, e, o) {
7
+ if (e.throwIfAborted(), s instanceof Error && (s.name === "AbortError" || ["E_ABORTED", "E_SUPERSEDED"].includes(String(s.code)))) throw s;
8
+ const t = s && typeof s == "object" && "code" in s && typeof s.code == "string" ? s.code : "E_PHYSICS_INITIALIZE", r = s instanceof Error ? s.message : String(s);
9
+ return { code: t, source: o, message: `无法启用物理仿真(${o}):${r}` };
10
+ }
11
+ class ce {
12
+ constructor(e, o) {
13
+ N(this, "root");
14
+ N(this, "bodies", /* @__PURE__ */ new Map());
15
+ N(this, "links", /* @__PURE__ */ new Map());
16
+ N(this, "disposed", !1);
17
+ this.runtime = e, this.root = o.root;
18
+ const t = e.mujoco, r = e.model;
19
+ for (const [l, n] of o.bindings) {
20
+ const u = t.mj_name2id(r, t.mjtObj.mjOBJ_BODY.value, l);
21
+ if (u < 0) throw fe(`Physics body missing for visual link: ${l}`, "E_SIMULATION_BIND");
22
+ this.links.set(l, n), n.userData.bodyId = u, this.bodies.set(u, n);
23
+ }
24
+ if (this.bodies.size !== o.expectedLinkCount) throw fe("Visual body binding count mismatch.", "E_SIMULATION_BIND");
25
+ this.sync();
26
+ }
27
+ objectForLink(e) {
28
+ return this.links.get(e) ?? null;
29
+ }
30
+ bodyPoses() {
31
+ return new Map([...this.bodies.values()].map((e) => [e.name, { position: e.position.clone(), quaternion: e.quaternion.clone() }]));
32
+ }
33
+ sync() {
34
+ if (this.disposed || !this.runtime.data) return;
35
+ const { xpos: e, xquat: o } = this.runtime.data;
36
+ for (const [t, r] of this.bodies) {
37
+ const l = t * 3, n = t * 4;
38
+ r.position.set(e[l], e[l + 1], e[l + 2]), r.quaternion.set(o[n + 1], o[n + 2], o[n + 3], o[n]);
39
+ }
40
+ this.root.updateMatrixWorld(!0);
41
+ }
42
+ dispose() {
43
+ this.disposed || (this.disposed = !0, this.bodies.clear(), this.links.clear(), x(this.root));
44
+ }
45
+ }
46
+ function fe(s, e) {
47
+ return Object.assign(new Error(s), { code: e });
48
+ }
49
+ class Ie {
50
+ constructor(e) {
51
+ N(this, "entries", /* @__PURE__ */ new Map());
52
+ N(this, "objectUrls", /* @__PURE__ */ new Map());
53
+ this.source = e;
54
+ const o = e.original;
55
+ if ($e(o))
56
+ for (const t of o.files) this.entries.set(R(t.path), t.file);
57
+ else typeof Blob < "u" && o instanceof Blob ? this.entries.set(e.entryPath ?? e.filename ?? "asset", o) : o instanceof ArrayBuffer ? this.entries.set(e.entryPath ?? e.filename ?? "asset", new Blob([o])) : typeof o == "object" && o !== null && "kind" in o && o.kind === "buffer" && this.entries.set(e.entryPath ?? e.filename ?? "asset", new Blob([o.buffer]));
58
+ }
59
+ paths() {
60
+ return [...this.entries.keys()];
61
+ }
62
+ hasLocalFiles() {
63
+ return this.entries.size > 0;
64
+ }
65
+ put(e, o) {
66
+ this.entries.set(R(e), o);
67
+ }
68
+ asSourceRecord(e = "") {
69
+ const o = R(e), t = o ? `${o}/` : "", r = {};
70
+ for (const [l, n] of this.entries)
71
+ (!t || l.startsWith(t)) && (r[t ? l.slice(t.length) : l] = n);
72
+ return r;
73
+ }
74
+ resolve(e, o = "") {
75
+ const t = this.find(e, o);
76
+ if (t) return t;
77
+ const r = R(o).split("/").slice(0, -1).join("/");
78
+ if (this.source.url) return R(`${r}/${e.replace(/^package:\/\//, "")}`);
79
+ throw D(`Simulation resource not found: ${e}`, "E_ASSET_RESOURCE_NOT_FOUND");
80
+ }
81
+ find(e, o = "") {
82
+ const t = R(e.replace(/^package:\/\//, "")), r = R(o).split("/").slice(0, -1).join("/");
83
+ for (const n of [R(`${r}/${e.replace(/^package:\/\//, "")}`), t])
84
+ if (this.entries.has(n)) return n;
85
+ const l = this.paths().filter(
86
+ (n) => n === t || n.endsWith(`/${t}`) || t.endsWith(`/${n}`)
87
+ );
88
+ return l.length === 1 ? l[0] : null;
89
+ }
90
+ async text(e) {
91
+ await this.ensure(e);
92
+ const o = this.entries.get(this.resolve(e));
93
+ if (!o) throw D(`Simulation resource not found: ${e}`, "E_ASSET_RESOURCE_NOT_FOUND");
94
+ return o.text();
95
+ }
96
+ async bytes(e) {
97
+ await this.ensure(e);
98
+ const o = this.entries.get(this.resolve(e));
99
+ if (!o) throw D(`Simulation resource not found: ${e}`, "E_ASSET_RESOURCE_NOT_FOUND");
100
+ return new Uint8Array(await o.arrayBuffer());
101
+ }
102
+ getBlob(e) {
103
+ const o = this.resolve(e), t = this.entries.get(o);
104
+ if (!t) throw D(`Simulation resource not found: ${e}`, "E_ASSET_RESOURCE_NOT_FOUND");
105
+ return t;
106
+ }
107
+ async ensure(e) {
108
+ const o = R(e);
109
+ if (this.entries.has(o)) return;
110
+ const t = await this.source.resolve(o);
111
+ if (!/^https?:\/\//i.test(t) && !/^blob:/i.test(t))
112
+ throw D(`Simulation resource not found: ${e}. Upload the complete asset folder or provide a resourceResolver/baseUrl.`, "E_ASSET_RESOURCE_NOT_FOUND");
113
+ const r = await fetch(t, { signal: this.source.signal });
114
+ if (!r.ok) throw D(`Simulation resource request failed (${r.status}): ${t}`, r.status === 401 || r.status === 403 ? "E_ASSET_AUTH" : "E_ASSET_FETCH");
115
+ const l = await r.blob();
116
+ this.source.signal.throwIfAborted(), this.entries.set(o, l);
117
+ }
118
+ objectUrl(e) {
119
+ const o = this.resolve(e);
120
+ let t = this.objectUrls.get(o);
121
+ return t || (t = URL.createObjectURL(this.getBlob(o)), this.objectUrls.set(o, t)), t;
122
+ }
123
+ objectUrlIfPresent(e, o = "") {
124
+ const t = R(o), r = t ? `${t}/` : "", l = R(e), n = r ? this.paths().filter((i) => {
125
+ if (!i.startsWith(r)) return !1;
126
+ const a = i.slice(r.length);
127
+ return a === l || l.endsWith(`/${a}`);
128
+ }) : [], u = n.length === 1 ? n[0] : this.find(e);
129
+ return u ? this.objectUrl(u) : null;
130
+ }
131
+ dispose() {
132
+ for (const e of this.objectUrls.values()) URL.revokeObjectURL(e);
133
+ this.objectUrls.clear(), this.entries.clear();
134
+ }
135
+ }
136
+ async function Be(s, e) {
137
+ if (e.hasLocalFiles()) return e.text(s.entryPath ?? s.filename ?? e.paths()[0]);
138
+ const o = await fetch(s.url ?? await s.resolve(s.entryPath ?? ""), { signal: s.signal });
139
+ if (!o.ok) throw D(`Simulation asset request failed: ${o.status}`, "E_ASSET_FETCH");
140
+ return o.text();
141
+ }
142
+ function wt(s) {
143
+ return R(s);
144
+ }
145
+ function R(s) {
146
+ const e = [];
147
+ for (const o of s.replaceAll("\\", "/").split("/"))
148
+ !o || o === "." || (o === ".." && e.length && e.at(-1) !== ".." ? e.pop() : e.push(o));
149
+ return e.join("/");
150
+ }
151
+ function $e(s) {
152
+ return typeof s == "object" && s !== null && "kind" in s && s.kind === "files";
153
+ }
154
+ function D(s, e) {
155
+ return Object.assign(new Error(s), { code: e });
156
+ }
157
+ function ke() {
158
+ return { errors: [], warnings: [], approximations: [], droppedFeatures: [] };
159
+ }
160
+ function ze(s, e = {}) {
161
+ const o = Object.freeze({ schemaVersion: 1, ...s });
162
+ return qe(o, e), o;
163
+ }
164
+ function qe(s, e = {}) {
165
+ if (!s.id.trim() || !s.name.trim()) throw k("Asset IR id and name are required.", "E_ASSET_IR_INVALID");
166
+ if (s.source.format !== "usd" && s.links.length === 0) throw k("Asset IR requires at least one link.", "E_ASSET_IR_INVALID");
167
+ const o = /* @__PURE__ */ new Set();
168
+ for (const r of s.links) {
169
+ if (!r.id || o.has(r.id)) throw k(`Invalid or duplicate link: ${r.id}`, "E_ASSET_IR_INVALID");
170
+ o.add(r.id);
171
+ }
172
+ const t = /* @__PURE__ */ new Set();
173
+ for (const r of s.joints) {
174
+ if (!r.id || t.has(r.id) || !e.allowInvalidGraph && (!o.has(r.parent) || !o.has(r.child)))
175
+ throw k(`Invalid joint: ${r.id}`, "E_ASSET_IR_INVALID");
176
+ t.add(r.id);
177
+ }
178
+ }
179
+ function k(s, e) {
180
+ return Object.assign(new Error(s), { code: e });
181
+ }
182
+ async function xe(s, e, o) {
183
+ var i;
184
+ const t = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set(), n = async (a, c) => {
185
+ if (l.has(a)) throw Z(`MJCF include cycle: ${a}`, "E_MJCF_INCLUDE_CYCLE");
186
+ l.add(a);
187
+ const b = Xe(c, a);
188
+ t.set(a, b);
189
+ for (const O of b.querySelectorAll("worldbody body[name]")) r.add(O.getAttribute("name"));
190
+ for (const O of b.querySelectorAll("include[file]")) {
191
+ const E = o.resolve(O.getAttribute("file"), a);
192
+ await n(E, await o.text(E));
193
+ }
194
+ l.delete(a);
195
+ };
196
+ await n(e, s);
197
+ const u = (i = t.get(e)) == null ? void 0 : i.querySelector("mujoco");
198
+ if (!u || r.size === 0) throw Z("MJCF requires a mujoco root and at least one named body.", "E_MJCF_PARSE");
199
+ return ze({
200
+ id: u.getAttribute("model") || e,
201
+ name: u.getAttribute("model") || e,
202
+ source: { format: "mjcf", uri: e },
203
+ links: [...r].map((a) => ({ id: a, name: a, visuals: [], collisions: [] })),
204
+ joints: [],
205
+ diagnostics: ke(),
206
+ extension: { files: o, xml: s, documents: t }
207
+ });
208
+ }
209
+ async function Ve(s) {
210
+ const e = s.extension.files, o = s.source.uri, t = o.split("/").slice(0, -1).join("/"), r = /* @__PURE__ */ new Map(), l = s.extension.documents;
211
+ for (const [i, a] of l) {
212
+ const c = a.querySelector("compiler");
213
+ for (const b of a.querySelectorAll("asset [file]")) {
214
+ const O = (c == null ? void 0 : c.getAttribute(b.tagName === "texture" ? "texturedir" : "meshdir")) ?? (c == null ? void 0 : c.getAttribute("assetdir")) ?? "", E = e.resolve(`${O}/${b.getAttribute("file")}`, i);
215
+ await e.bytes(E);
216
+ }
217
+ }
218
+ for (const i of We(e.paths(), l)) {
219
+ if (i === o) continue;
220
+ const a = t && i.startsWith(`${t}/`) ? i.slice(t.length + 1) : i;
221
+ r.set(a, await e.bytes(i));
222
+ }
223
+ const n = s.extension.xml;
224
+ return { format: "mjcf", xml: Je(l) ? He(n) : n, files: r };
225
+ }
226
+ function Je(s) {
227
+ return s.size === 0 || ![...s.values()].some((o) => o.querySelector("freejoint, actuator") ? !0 : [...o.querySelectorAll("joint")].some(
228
+ (t) => (t.getAttribute("type") ?? "hinge").toLowerCase() !== "fixed"
229
+ )) ? !1 : ![...s.values()].some(
230
+ (o) => [...o.querySelectorAll("worldbody geom")].some((t) => {
231
+ var r;
232
+ return ((r = t.getAttribute("type")) == null ? void 0 : r.toLowerCase()) === "plane";
233
+ })
234
+ );
235
+ }
236
+ function He(s) {
237
+ const e = '<geom name="__viewer_default_ground__" type="plane" size="5 5 0.1" contype="1" conaffinity="1" friction="0.8 0.01 0.0002"/>';
238
+ return /<worldbody\b[^>]*>/i.test(s) ? s.replace(/(<worldbody\b[^>]*>)/i, `$1${e}`) : s.replace(/<\/mujoco\s*>/i, `<worldbody>${e}</worldbody></mujoco>`);
239
+ }
240
+ function We(s, e) {
241
+ const o = (u) => u.replaceAll("\\", "/").split("/").pop() ?? "", t = /* @__PURE__ */ new Map();
242
+ for (const u of s) {
243
+ const i = o(u), a = t.get(i) ?? [];
244
+ a.push(u), t.set(i, a);
245
+ }
246
+ const r = new Set(e.keys()), l = /* @__PURE__ */ new Set(["include", "mesh", "texture", "hfield", "skin"]), n = /* @__PURE__ */ new Set(["fileleft", "fileright", "fileup", "filedown", "filefront", "fileback"]);
247
+ for (const u of e.values()) {
248
+ if (u.querySelector("plugin, extension, model, attach")) return s;
249
+ for (const i of u.querySelectorAll("*"))
250
+ for (const a of i.attributes) {
251
+ if (!a.name.startsWith("file")) continue;
252
+ if (a.name === "file") {
253
+ if (!l.has(i.tagName)) return s;
254
+ } else if (!(i.tagName === "texture" && n.has(a.name)))
255
+ return s;
256
+ if (!a.value) continue;
257
+ const c = t.get(o(a.value));
258
+ if (!c) return s;
259
+ for (const b of c) r.add(b);
260
+ }
261
+ }
262
+ return s.filter((u) => r.has(u));
263
+ }
264
+ function Xe(s, e) {
265
+ const o = new DOMParser().parseFromString(s, "application/xml"), t = o.querySelector("parsererror");
266
+ if (t) throw Z(`MJCF XML parse failed (${e}): ${t.textContent ?? ""}`, "E_MJCF_PARSE");
267
+ return o;
268
+ }
269
+ function Z(s, e) {
270
+ return Object.assign(new Error(s), { code: e });
271
+ }
272
+ const Ye = 1476466, Ze = 0.72, Ke = 20, Qe = 1;
273
+ function et() {
274
+ return new Me({
275
+ color: Ye,
276
+ transparent: !0,
277
+ opacity: Ze,
278
+ depthTest: !1
279
+ });
280
+ }
281
+ function tt(s, e, o = "feature") {
282
+ const t = o === "mesh" ? new ve(s) : ot(s), r = new Oe(t, e);
283
+ return r.renderOrder = 9, r;
284
+ }
285
+ function ot(s) {
286
+ let e = new W(s, Ke);
287
+ return me(s, e) || (e.dispose(), e = new W(s, Qe)), me(s, e) || (e.dispose(), e = new W(s, 0)), e;
288
+ }
289
+ const st = 256, rt = 0.5;
290
+ function me(s, e) {
291
+ var u, i;
292
+ const o = e.getAttribute("position");
293
+ if (!o || o.count === 0) return !1;
294
+ const t = s.getAttribute("position");
295
+ if (!t || t.count < st) return !0;
296
+ s.computeBoundingBox(), e.computeBoundingBox();
297
+ const r = (u = s.boundingBox) == null ? void 0 : u.getSize(new ie()), l = (i = e.boundingBox) == null ? void 0 : i.getSize(new ie());
298
+ if (!r || !l) return !1;
299
+ const n = r.length();
300
+ return !Number.isFinite(n) || n <= 0 ? !0 : l.length() / n >= rt;
301
+ }
302
+ const V = 0.5, I = (s, e) => Number.isFinite(s) ? Math.min(1, Math.max(0, s)) : e;
303
+ function de(s, e) {
304
+ return s !== void 0 && Number.isFinite(s) && s >= 0 ? I(s, V) : e !== void 0 && Number.isFinite(e) && e >= 0 ? 1 - I(e, 0.5) : V;
305
+ }
306
+ function nt(s = {}) {
307
+ const e = s.color ?? [0.68, 0.72, 0.7, 1], o = new Ae().setRGB(e[0], e[1], e[2], s.colorSpace === "linear" ? Ge : he), t = I(e[3] ?? 1, 1), r = I(s.specular ?? 0.5, 0.5), l = Math.sqrt(0.08 * r);
308
+ return new Ce({
309
+ color: o,
310
+ opacity: t,
311
+ transparent: t < 1,
312
+ depthWrite: t === 1,
313
+ roughness: I(s.roughness ?? V, V),
314
+ metalness: I(s.metalness ?? 0, 0),
315
+ // Legacy specular 0.5 corresponds to the standard dielectric response.
316
+ specularIntensity: r <= 0.5 ? r * 2 : 1,
317
+ ior: r <= 0.5 ? 1.5 : (1 + l) / (1 - l),
318
+ emissive: o.clone().multiplyScalar(Math.max(0, s.emission ?? 0)),
319
+ map: s.map ?? null
320
+ });
321
+ }
322
+ function it(s, e) {
323
+ var O, E;
324
+ const o = [], t = [], r = [], l = s.mesh_vertadr[e], n = s.mesh_faceadr[e], u = s.mesh_normaladr[e], i = s.mesh_texcoordadr[e];
325
+ let a = u >= 0, c = i >= 0;
326
+ for (let g = 0; g < s.mesh_facenum[e]; g++) for (let S = 0; S < 3; S++) {
327
+ const f = (n + g) * 3 + S, _ = (l + s.mesh_face[f]) * 3;
328
+ o.push(...s.mesh_vert.slice(_, _ + 3));
329
+ const w = ((O = s.mesh_facenormal) == null ? void 0 : O[f]) ?? -1;
330
+ u >= 0 && w >= 0 ? t.push(...s.mesh_normal.slice((u + w) * 3, (u + w) * 3 + 3)) : a = !1;
331
+ const A = ((E = s.mesh_facetexcoord) == null ? void 0 : E[f]) ?? -1;
332
+ i >= 0 && A >= 0 ? r.push(...s.mesh_texcoord.slice((i + A) * 2, (i + A) * 2 + 2)) : c = !1;
333
+ }
334
+ const b = new Q();
335
+ return b.setAttribute("position", new q(o, 3)), a && t.length === o.length ? b.setAttribute("normal", new q(t, 3)) : b.computeVertexNormals(), c && r.length === o.length / 3 * 2 && b.setAttribute("uv", new q(r, 2)), b;
336
+ }
337
+ function at(s) {
338
+ const e = /* @__PURE__ */ new Map();
339
+ if (!s.model.ntex) return e;
340
+ const o = s.mujoco, t = s.model, r = new o.MjvScene(t, Math.max(1e3, t.ngeom * 2)), l = new o.MjvOption(), n = new o.MjvPerturb(), u = new o.MjvCamera();
341
+ try {
342
+ l.geomgroup.fill(1), o.mjv_updateScene(t, s.data, l, n, u, o.mjtCatBit.mjCAT_ALL.value, r);
343
+ for (let i = 0; i < r.ngeom; i++) {
344
+ const a = r.geoms.get(i);
345
+ try {
346
+ a.objtype === o.mjtObj.mjOBJ_GEOM.value && e.set(a.objid, a.texuniform !== 0);
347
+ } finally {
348
+ a.delete();
349
+ }
350
+ }
351
+ return e;
352
+ } finally {
353
+ r.delete(), l.delete(), n.delete(), u.delete();
354
+ }
355
+ }
356
+ function lt(s, e, o, t, r, l = /* @__PURE__ */ new Map()) {
357
+ var S;
358
+ const n = s.model, u = s.mujoco, i = n.geom_matid[e];
359
+ if (i < 0) return;
360
+ const a = (f, _) => {
361
+ r != null && r.droppedFeatures.some((w) => w.code === f && w.source === `material:${i}`) || r == null || r.droppedFeatures.push({ code: f, message: _, source: `material:${i}` });
362
+ };
363
+ n.mat_reflectance[i] > 0 && a("MJCF_REFLECTANCE_UNSUPPORTED", "Legacy planar reflection is not reproduced by the PBR material.");
364
+ const c = u.mjtTextureRole.mjNTEXROLE.value;
365
+ if (!Array.from(n.mat_texid.slice(i * c, (i + 1) * c)).some((f) => Number(f) >= 0)) return;
366
+ const E = !(n.geom_type[e] === u.mjtGeom.mjGEOM_MESH.value) || !o.getAttribute("uv"), g = l.get(e);
367
+ if (g === void 0) throw new Error(`Missing compiled texture projection for geom ${e}`);
368
+ if (E) {
369
+ const f = o.getAttribute("position"), _ = [], w = n.geom_size[e * 3] || 1, A = n.geom_size[e * 3 + 1] || w;
370
+ for (let y = 0; y < f.count; y++) _.push(f.getX(y) / (2 * (g ? 1 : w)), -f.getY(y) / (2 * (g ? 1 : A)));
371
+ o.setAttribute("uv", new q(_, 2));
372
+ }
373
+ for (let f = 0; f < c; f++) {
374
+ const _ = n.mat_texid[i * c + f];
375
+ if (_ < 0) continue;
376
+ if (n.tex_type[_] !== u.mjtTexture.mjTEXTURE_2D.value) {
377
+ a("MJCF_TEXTURE_PROJECTION_UNSUPPORTED", "Cube/skybox surface textures require a dedicated projection and are not substituted with a 2D map.");
378
+ continue;
379
+ }
380
+ if (f === 0) {
381
+ a("MJCF_USER_TEXTURE_UNSUPPORTED", "User texture role has no defined PBR material slot.");
382
+ continue;
383
+ }
384
+ const w = n.tex_width[_], A = n.tex_height[_], y = n.tex_nchannel[_];
385
+ if (![1, 2, 3, 4].includes(y)) {
386
+ a("MJCF_TEXTURE_CHANNELS_UNSUPPORTED", "Unsupported texture channel count.");
387
+ continue;
388
+ }
389
+ const m = Number(n.tex_adr[_]), d = new Uint8Array(w * A * 4);
390
+ for (let p = 0; p < w * A; p++) {
391
+ const j = m + p * y, v = p * 4, G = n.tex_data[j];
392
+ d[v] = G, d[v + 1] = y >= 3 ? n.tex_data[j + 1] : G, d[v + 2] = y >= 3 ? n.tex_data[j + 2] : G, d[v + 3] = y === 4 ? n.tex_data[j + 3] : y === 2 ? n.tex_data[j + 1] : 255, [2, 3, 4, 6].includes(f) && (d[v] = d[v + 1] = d[v + 2] = G);
393
+ }
394
+ const M = new Pe(d, w, A, Re, Le);
395
+ M.colorSpace = [1, 7, 8].includes(f) && n.tex_colorspace[_] === u.mjtColorSpace.mjCOLORSPACE_SRGB.value ? he : Te, M.wrapS = M.wrapT = Ue, M.magFilter = Fe, M.minFilter = Ne, M.generateMipmaps = !0;
396
+ const C = n.mat_texrepeat[i * 2], P = n.mat_texrepeat[i * 2 + 1];
397
+ if (M.repeat.set(C, P), E ? M.offset.set(-0.5, -0.5) : g && M.repeat.set(C * (n.geom_size[e * 3] || 1), P * (n.geom_size[e * 3 + 1] || 1)), M.needsUpdate = !0, f === 1 || f === 8)
398
+ (S = t.map) == null || S.dispose(), t.map = M, f === 8 && (t.transparent = !0, t.depthWrite = !1);
399
+ else if (f === 2) t.aoMap = M;
400
+ else if (f === 3)
401
+ t.roughnessMap = M, t.roughness = n.mat_roughness[i] >= 0 ? t.roughness : 1;
402
+ else if (f === 4)
403
+ t.metalnessMap = M, t.metalness = n.mat_metallic[i] >= 0 ? t.metalness : 1;
404
+ else if (f === 5) t.normalMap = M;
405
+ else if (f === 6)
406
+ t.alphaMap = M, t.transparent = !0, t.depthWrite = !1;
407
+ else if (f === 7)
408
+ t.emissiveMap = M, t.emissive.setRGB(1, 1, 1), y === 4 && a("MJCF_EMISSIVE_EXPOSURE_UNSUPPORTED", "Emissive RGB is preserved; per-pixel exposure weight is not supported.");
409
+ else if (f === 9) {
410
+ for (const p of /* @__PURE__ */ new Set([t.aoMap, t.roughnessMap, t.metalnessMap])) p == null || p.dispose();
411
+ t.aoMap = t.roughnessMap = t.metalnessMap = M, t.roughness = n.mat_roughness[i] >= 0 ? t.roughness : 1, t.metalness = n.mat_metallic[i] >= 0 ? t.metalness : 1;
412
+ }
413
+ }
414
+ }
415
+ function ut(s, e) {
416
+ return e < 0 ? de() : de(s.mat_roughness[e], s.mat_shininess[e]);
417
+ }
418
+ function ct(s, e) {
419
+ if (e < 0) return 0;
420
+ const o = s.mat_metallic[e];
421
+ return Number.isFinite(o) && o >= 0 ? o : 0;
422
+ }
423
+ function pe(s, e = !1, o) {
424
+ const t = s.model, r = s.mujoco, l = new ae();
425
+ l.name = "MuJoCo scene";
426
+ const n = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
427
+ for (let i = 1; i < t.nbody; i += 1) {
428
+ const a = r.mj_id2name(t, r.mjtObj.mjOBJ_BODY.value, i);
429
+ if (!a) continue;
430
+ const c = new ae();
431
+ c.name = a, c.userData.bodyId = i, n.set(i, c), u.set(a, c), l.add(c);
432
+ }
433
+ try {
434
+ if (n.set(0, l), e) {
435
+ const i = et();
436
+ let a = 0;
437
+ for (let c = 0; c < t.ngeom; c += 1) {
438
+ const b = r.mj_id2name(t, r.mjtObj.mjOBJ_GEOM.value, c);
439
+ if (b === "__viewer_default_ground__" || !dt(t, c)) continue;
440
+ const O = n.get(t.geom_bodyid[c]), E = ft(s, c);
441
+ if (!O) continue;
442
+ if (!E) {
443
+ o == null || o.droppedFeatures.push({
444
+ code: "E_MJCF_COLLISION_DEBUG_GEOMETRY_UNAVAILABLE",
445
+ message: `MJCF geom ${b ?? `#${c}`} 的 compiled type=${t.geom_type[c]} 无法准确还原为碰撞线框。`,
446
+ source: "mjcf-collision-debug"
447
+ });
448
+ continue;
449
+ }
450
+ const g = mt(s, c) ? "mesh" : "feature", S = tt(E, i, g);
451
+ E.dispose(), S.userData.geomId = c, a += 1;
452
+ const f = c * 3, _ = c * 4;
453
+ S.position.fromArray(t.geom_pos, f), S.quaternion.set(t.geom_quat[_ + 1], t.geom_quat[_ + 2], t.geom_quat[_ + 3], t.geom_quat[_]), O.add(S);
454
+ }
455
+ a === 0 && i.dispose();
456
+ } else {
457
+ const i = at(s);
458
+ for (let a = 0; a < t.ngeom; a += 1) {
459
+ if (t.geom_group[a] > 2 || r.mj_id2name(t, r.mjtObj.mjOBJ_GEOM.value, a) === "__viewer_default_ground__") continue;
460
+ const c = n.get(t.geom_bodyid[a]), b = _t(s, a);
461
+ if (!c || !b) continue;
462
+ const O = a * 4, E = t.geom_matid[a], g = Array.from(t.geom_rgba.slice(O, O + 4));
463
+ E >= 0 && [0.5, 0.5, 0.5, 1].every((A, y) => g[y] === A) && g.splice(0, 4, ...Array.from(t.mat_rgba.slice(E * 4, E * 4 + 4)));
464
+ const S = nt({
465
+ color: g,
466
+ roughness: ut(t, E),
467
+ metalness: ct(t, E),
468
+ specular: E >= 0 ? t.mat_specular[E] : void 0,
469
+ emission: E >= 0 ? t.mat_emission[E] : void 0
470
+ });
471
+ try {
472
+ lt(s, a, b, S, o, i);
473
+ } catch (A) {
474
+ throw x(new le(b, S)), A;
475
+ }
476
+ const f = new le(b, S), _ = a * 3, w = a * 4;
477
+ t.geom_bodyid[a] === 0 && t.geom_type[a] === r.mjtGeom.mjGEOM_PLANE.value && (f.userData.excludeFromSimulationFit = !0), f.position.fromArray(t.geom_pos, _), f.quaternion.set(t.geom_quat[w + 1], t.geom_quat[w + 2], t.geom_quat[w + 3], t.geom_quat[w]), c.add(f);
478
+ }
479
+ }
480
+ return { root: l, bindings: u, expectedLinkCount: u.size };
481
+ } catch (i) {
482
+ throw x(l), i;
483
+ }
484
+ }
485
+ function ft(s, e) {
486
+ const o = s.model, t = s.mujoco, r = e * 3, l = o.geom_size[r], n = o.geom_size[r + 1], u = o.geom_size[r + 2], i = o.geom_type[e];
487
+ if (i === t.mjtGeom.mjGEOM_PLANE.value) return new _e(Math.max(l * 2, 2), Math.max(n * 2, 2), 10, 10);
488
+ if (i === t.mjtGeom.mjGEOM_BOX.value) return new ge(l * 2, n * 2, u * 2);
489
+ if (i === t.mjtGeom.mjGEOM_SPHERE.value) return new X(l, 20, 12);
490
+ if (i === t.mjtGeom.mjGEOM_ELLIPSOID.value) {
491
+ const a = new X(1, 24, 16);
492
+ return a.applyMatrix4(new De().makeScale(l, n, u)), a;
493
+ }
494
+ if (i === t.mjtGeom.mjGEOM_CYLINDER.value) {
495
+ const a = new ye(l, l, n * 2, 24);
496
+ return a.rotateX(Math.PI / 2), a;
497
+ }
498
+ if (i === t.mjtGeom.mjGEOM_CAPSULE.value) {
499
+ const a = new be(l, n * 2, 6, 16);
500
+ return a.rotateX(Math.PI / 2), a;
501
+ }
502
+ return i === t.mjtGeom.mjGEOM_MESH.value ? pt(s, o.geom_dataid[e]) : i === t.mjtGeom.mjGEOM_HFIELD.value ? ht(s, o.geom_dataid[e]) : null;
503
+ }
504
+ function mt(s, e) {
505
+ const o = s.model.geom_type[e];
506
+ return o === s.mujoco.mjtGeom.mjGEOM_MESH.value || o === s.mujoco.mjtGeom.mjGEOM_HFIELD.value;
507
+ }
508
+ function dt(s, e) {
509
+ if (s.geom_contype[e] !== 0 || s.geom_conaffinity[e] !== 0) return !0;
510
+ for (let o = 0; o < s.npair; o += 1) if (s.pair_geom1[o] === e || s.pair_geom2[o] === e) return !0;
511
+ return !1;
512
+ }
513
+ function pt(s, e) {
514
+ const o = s.model, t = o.mesh_graphadr[e];
515
+ if (t < 0) return null;
516
+ const r = o.mesh_vertadr[e], l = o.mesh_vertnum[e], n = o.mesh_graph[t], u = o.mesh_graph[t + 1];
517
+ if (n < 4 || u < 4) return null;
518
+ const i = t + 2 + 3 * n + 3 * u, a = new Q();
519
+ return a.setAttribute("position", new Y(Float32Array.from(o.mesh_vert.subarray(r * 3, (r + l) * 3)), 3)), a.setIndex(new Y(Uint32Array.from(o.mesh_graph.subarray(i, i + u * 3)), 1)), a.computeVertexNormals(), a;
520
+ }
521
+ function ht(s, e) {
522
+ const o = s.model, t = o.hfield_nrow[e], r = o.hfield_ncol[e];
523
+ if (t < 2 || r < 2) return null;
524
+ const l = o.hfield_adr[e], n = e * 4, u = o.hfield_size[n], i = o.hfield_size[n + 1], a = o.hfield_size[n + 2], c = o.hfield_size[n + 3], b = t * r, O = [];
525
+ for (let C = 0; C < t; C += 1) for (let P = 0; P < r; P += 1)
526
+ O.push(
527
+ -u + 2 * u * P / (r - 1),
528
+ -i + 2 * i * C / (t - 1),
529
+ o.hfield_data[l + C * r + P] * a
530
+ );
531
+ const E = [
532
+ [-u, -i, -c],
533
+ [u, -i, -c],
534
+ [-u, i, -c],
535
+ [u, i, -c]
536
+ ];
537
+ for (const C of E) O.push(...C);
538
+ const g = [];
539
+ for (let C = 0; C < t - 1; C += 1) for (let P = 0; P < r - 1; P += 1) {
540
+ const p = C * r + P, j = p + 1, v = p + r, G = v + 1;
541
+ g.push(p, v, j, j, v, G);
542
+ }
543
+ const S = b, f = b + 1, _ = b + 2, w = b + 3;
544
+ g.push(S, f, _, f, w, _);
545
+ const A = 0, y = r - 1, m = (t - 1) * r, d = t * r - 1;
546
+ g.push(S, A, f, f, A, y), g.push(_, w, m, w, d, m), g.push(S, _, A, _, m, A), g.push(f, y, w, w, y, d);
547
+ const M = new Q();
548
+ return M.setAttribute("position", new Y(Float32Array.from(O), 3)), M.setIndex(g), M.computeVertexNormals(), M;
549
+ }
550
+ function _t(s, e) {
551
+ const o = s.model, t = s.mujoco, r = e * 3, l = o.geom_size[r], n = o.geom_size[r + 1], u = o.geom_size[r + 2], i = o.geom_type[e];
552
+ if (i === t.mjtGeom.mjGEOM_PLANE.value) return new _e((l || 5) * 2, (n || 5) * 2);
553
+ if (i === t.mjtGeom.mjGEOM_BOX.value) return new ge(l * 2, n * 2, u * 2);
554
+ if (i === t.mjtGeom.mjGEOM_SPHERE.value) return new X(l, 24, 16);
555
+ if (i === t.mjtGeom.mjGEOM_CYLINDER.value) {
556
+ const a = new ye(l, l, n * 2, 24);
557
+ return a.rotateX(Math.PI / 2), a;
558
+ }
559
+ if (i === t.mjtGeom.mjGEOM_CAPSULE.value) {
560
+ const a = new be(l, n * 2, 6, 16);
561
+ return a.rotateX(Math.PI / 2), a;
562
+ }
563
+ return i !== t.mjtGeom.mjGEOM_MESH.value ? null : it(o, o.geom_dataid[e]);
564
+ }
565
+ function gt(s, e) {
566
+ const o = new Ie(s);
567
+ let t = null, r = null, l = null, n = null, u = null, i = null, a = null, c = null, b = null, O = null, E = null, g = !1, S = !0, f = !1, _ = null, w = null, A, y = null, m = null, d = null;
568
+ const M = (p, j) => {
569
+ var G;
570
+ const v = ue(p, e.signal, `${e.format}:${j}`);
571
+ S = !1, f = !1, w = { ...v, stage: j };
572
+ try {
573
+ m == null || m.endGrab();
574
+ } catch {
575
+ }
576
+ (G = e.reportSessionState) == null || G.call(e), e.reportError(p, { fatal: !1, stage: j, code: v.code });
577
+ }, C = () => {
578
+ g = !0, S = !1;
579
+ }, P = (async () => {
580
+ var p, j, v, G, U, ee, te, oe, se;
581
+ try {
582
+ const L = e.format;
583
+ if (L === "usd" || L === "usda" || L === "usdc" || L === "usdz") {
584
+ (p = e.reportProgress) == null || p.call(e, "usd", "正在解析 USD 场景与物理刚体...");
585
+ const h = await (await import("./usd-session-JDfuDgWv.js")).loadUsdSimulation(s, e, o);
586
+ if (g || e.signal.aborted)
587
+ throw h.dispose(), K();
588
+ y = h.asset, r = h.binding, l = h.dispose, n = h.hasPhysics ? h.step : null, u = h.reset, S = h.hasPhysics, f = h.hasPhysics, _ = h.fallback ? { ...h.fallback, stage: "physics-fallback" } : h.visualWarning ? { ...h.visualWarning, stage: "visual-adaptation" } : null, (j = e.reportProgress) == null || j.call(e, "stage", "正在构建三维场景与环境光影..."), m = new H(r.root, e.options.simulationTheme, h.runtime), h.runtime && (t = h.runtime), d = h.collision ?? null, d && (d.root.visible = !1, m.attachAuxiliary(d.root));
589
+ return;
590
+ }
591
+ if (L === "urdf" || L === "xacro") {
592
+ (v = e.reportProgress) == null || v.call(e, "urdf", "正在解析 URDF 场景与运动学结构...");
593
+ const h = await (await import("./urdf-session-CuIZOiCF.js")).loadUrdfSimulation(s, e, o);
594
+ if (g || e.signal.aborted)
595
+ throw h.dispose(), K();
596
+ y = h.asset, m = h.stage, b = h.inspection, l = h.dispose, n = h.step, u = h.reset, i = h.play, a = h.pause, c = h.isPlaying, O = () => h.capabilities, E = () => h.physics, S = !1, f = !1, _ = h.warning ?? null;
597
+ return;
598
+ }
599
+ let B = s.entryPath ?? s.filename;
600
+ if (!B && L === "mjcf") {
601
+ const T = o.paths().filter((h) => h.toLowerCase().endsWith(".xml"));
602
+ for (const h of ["scene.xml", "model.xml", "main.xml"]) {
603
+ const $ = T.find((F) => F.toLowerCase().endsWith(`/${h}`) || F.toLowerCase() === h);
604
+ if ($) {
605
+ B = $;
606
+ break;
607
+ }
608
+ }
609
+ }
610
+ B ?? (B = "asset.xml"), (G = e.reportProgress) == null || G.call(e, "fetch", "正在读取模型描述与依赖资源...");
611
+ const Ee = await Be(s, o);
612
+ z(g, e.signal), (U = e.reportProgress) == null || U.call(e, "parse", "正在解析 MJCF 场景与连杆..."), y = await xe(Ee, B, o);
613
+ try {
614
+ (ee = e.reportProgress) == null || ee.call(e, "compile", "正在编译物理模型与参数...");
615
+ const T = await Ve(y);
616
+ z(g, e.signal), (te = e.reportProgress) == null || te.call(e, "runtime", "正在初始化物理内核...");
617
+ const { MujocoRuntime: h } = await import("./mujoco-runtime-C29PXDOl.js");
618
+ t = new h(), await t.initialize(T, e.options.mujocoBaseUrl);
619
+ } catch (T) {
620
+ const h = ue(T, e.signal, "mjcf-physics");
621
+ t == null || t.dispose(), t = null;
622
+ const { compileMjcfPreview: $ } = await import("./mjcf-visual-6_RqDf4z.js");
623
+ let F;
624
+ try {
625
+ F = $(y);
626
+ } catch (J) {
627
+ throw new Error(`${h.message};独立视觉预览也不可用:${J instanceof Error ? J.message : String(J)}`);
628
+ }
629
+ r = { root: F, sync() {
630
+ }, dispose() {
631
+ x(F);
632
+ } }, _ = { ...h, stage: "physics-fallback" }, m = new H(F, e.options.simulationTheme), S = !1;
633
+ return;
634
+ }
635
+ f = !0, z(g, e.signal), (oe = e.reportProgress) == null || oe.call(e, "visual", "正在构建视觉渲染网格...");
636
+ const we = pe(t, !1, y.diagnostics), re = y.diagnostics.droppedFeatures.find((T) => T.code.startsWith("MJCF_"));
637
+ re && (_ = { ...re, stage: "visual-material" }), z(g, e.signal), (se = e.reportProgress) == null || se.call(e, "stage", "正在构建三维场景与环境光影..."), r = new ce(t, we), m = new H(r.root, e.options.simulationTheme, t);
638
+ const ne = pe(t, !0, y.diagnostics);
639
+ ne.root.children.length > 0 ? (d = new ce(t, ne), d.root.visible = !1) : d = null, d && m.attachAuxiliary(d.root);
640
+ } catch (L) {
641
+ throw m == null || m.dispose(), m = null, l ? (l(), l = null) : (d == null || d.dispose(), r == null || r.dispose(), t == null || t.dispose()), d = null, r = null, t = null, o.dispose(), L;
642
+ }
643
+ })();
644
+ return P.catch(() => {
645
+ }), {
646
+ id: `simulation-${Math.random().toString(36).slice(2)}`,
647
+ get autoPlay() {
648
+ return e.format === "urdf" || e.format === "xacro" ? !1 : void 0;
649
+ },
650
+ get inspection() {
651
+ return b;
652
+ },
653
+ isPlaying() {
654
+ return (c == null ? void 0 : c()) ?? S;
655
+ },
656
+ opened: P,
657
+ get root() {
658
+ return (m == null ? void 0 : m.root) ?? null;
659
+ },
660
+ getFitBounds() {
661
+ return (m == null ? void 0 : m.getModelBounds()) ?? null;
662
+ },
663
+ beforeRender(p, j, v) {
664
+ return m == null ? void 0 : m.beforeRender(p, j, v);
665
+ },
666
+ get capabilities() {
667
+ return w ? { canPlay: !1, canPause: !1, canReset: !1, hasPhysics: !1, canToggleGround: !0, canToggleCollision: d !== null } : (O == null ? void 0 : O()) ?? { canPlay: f, canPause: f, canReset: f, hasPhysics: f, canToggleGround: !0, canToggleCollision: d !== null };
668
+ },
669
+ get warning() {
670
+ return _;
671
+ },
672
+ get physics() {
673
+ return w ? { status: "unavailable", issue: w } : E ? E() : f ? { status: "ready" } : (_ == null ? void 0 : _.stage) === "physics-fallback" ? { status: "unavailable", issue: _ } : { status: "not-authored" };
674
+ },
675
+ setTheme(p) {
676
+ m == null || m.setTheme(p);
677
+ },
678
+ setGroundVisible(p) {
679
+ m == null || m.setGroundVisible(p);
680
+ },
681
+ getGroundVisible() {
682
+ return (m == null ? void 0 : m.getGroundVisible()) ?? !0;
683
+ },
684
+ presentation: { preferredViewMode: "3d", interactionMode: "simulation", uiProfile: "simulation", fitPolicy: "fit-on-ready" },
685
+ beginDispose: C,
686
+ setCollisionVisible(p) {
687
+ if (!g) {
688
+ if (O) {
689
+ const j = b;
690
+ j == null || j.setOverlay("collision", p);
691
+ return;
692
+ }
693
+ if (!d) throw new Error("This asset has no collision display.");
694
+ d.root.visible = p;
695
+ }
696
+ },
697
+ getVisualDiagnostics() {
698
+ return g || !y || y.source.format !== "usd" ? null : structuredClone({ report: y.extension.visualAdaptation, diagnostics: y.diagnostics });
699
+ },
700
+ getPhysicsProperties() {
701
+ if (g || !f || !(t != null && t.model) || !t.mujoco) return null;
702
+ const p = t.model, j = t.mujoco;
703
+ return structuredClone({
704
+ units: { length: "m", mass: "kg", time: "s" },
705
+ timestep: p.opt.timestep,
706
+ gravity: Array.from(p.opt.gravity),
707
+ bodyCount: p.nbody - 1,
708
+ jointCount: p.njnt,
709
+ geomCount: p.ngeom,
710
+ bodies: Array.from({ length: p.nbody - 1 }, (v, G) => {
711
+ const U = G + 1;
712
+ return { id: U, name: j.mj_id2name(p, j.mjtObj.mjOBJ_BODY.value, U), mass: p.body_mass[U], inertia: Array.from(p.body_inertia.slice(U * 3, U * 3 + 3)) };
713
+ }),
714
+ diagnostics: y == null ? void 0 : y.diagnostics
715
+ });
716
+ },
717
+ get update() {
718
+ return t != null && t.model || n ? (p) => {
719
+ if (w || g || !((c == null ? void 0 : c()) ?? S) || !r && !n) return !1;
720
+ try {
721
+ if (n) {
722
+ const v = n(p);
723
+ return v && (d == null || d.sync()), v;
724
+ }
725
+ const j = t.step(p);
726
+ return j && (r.sync(), d == null || d.sync(), m == null || m.updateForceLine()), j;
727
+ } catch (j) {
728
+ return M(j, "step"), !1;
729
+ }
730
+ } : void 0;
731
+ },
732
+ play() {
733
+ g || w || (i ? (i(), S = (c == null ? void 0 : c()) ?? !1) : f && (S = !0));
734
+ },
735
+ pause() {
736
+ w || (a && a(), S = !1);
737
+ },
738
+ reset() {
739
+ if (!(w || g || !r && !u))
740
+ try {
741
+ u ? u() : (t == null || t.reset(), r.sync()), d == null || d.sync(), m == null || m.updateForceLine();
742
+ } catch (p) {
743
+ M(p, "reset");
744
+ }
745
+ },
746
+ beginGrab(p, j, v) {
747
+ if (g || !f && !E) return !1;
748
+ try {
749
+ return (m == null ? void 0 : m.beginGrab(p, j, v)) ?? !1;
750
+ } catch (G) {
751
+ return M(G, "grab"), !1;
752
+ }
753
+ },
754
+ moveGrab(p, j, v) {
755
+ if (!(g || !f && !E))
756
+ try {
757
+ m == null || m.moveGrab(p, j, v);
758
+ } catch (G) {
759
+ M(G, "grab");
760
+ }
761
+ },
762
+ endGrab() {
763
+ m == null || m.endGrab();
764
+ },
765
+ dispose() {
766
+ return C(), A ?? (A = P.catch(() => {
767
+ }).then(() => {
768
+ l ? (l(), l = null, m = null, r = null, d = null) : (m == null || m.dispose(), m = null, d == null || d.root.removeFromParent(), d == null || d.dispose(), d = null, r == null || r.dispose(), r = null, t == null || t.dispose()), o.dispose(), y = null, b = null, n = null, u = null, i = null, a = null, c = null, O = null, E = null, f = !1, _ = null;
769
+ })), A;
770
+ }
771
+ };
772
+ }
773
+ function z(s, e) {
774
+ if (s || e.aborted) throw K();
775
+ }
776
+ function K() {
777
+ return Object.assign(new Error("Simulation load aborted."), { name: "AbortError", code: "E_ABORTED" });
778
+ }
779
+ const jt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
780
+ __proto__: null,
781
+ createSimulationSession: gt
782
+ }, Symbol.toStringTag, { value: "Module" }));
783
+ export {
784
+ ce as S,
785
+ tt as a,
786
+ ke as b,
787
+ et as c,
788
+ ze as d,
789
+ nt as e,
790
+ jt as f,
791
+ wt as n,
792
+ ue as p,
793
+ Be as r,
794
+ de as s
795
+ };