mujoco-react 8.1.0 → 8.1.1

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/index.js CHANGED
@@ -391,6 +391,18 @@ function sceneObjectToXml(obj) {
391
391
  const condim = obj.condim ? ` condim="${obj.condim}"` : "";
392
392
  return `<body name="${obj.name}" pos="${pos}">${joint}<geom type="${obj.type}" size="${size}" rgba="${rgba}" contype="1" conaffinity="1"${mass}${friction}${solref}${solimp}${condim}/></body>`;
393
393
  }
394
+ function ensureDir(mujoco, fname) {
395
+ const dirParts = fname.split("/");
396
+ dirParts.pop();
397
+ let currentPath = "/working";
398
+ for (const part of dirParts) {
399
+ currentPath += "/" + part;
400
+ try {
401
+ mujoco.FS.mkdir(currentPath);
402
+ } catch {
403
+ }
404
+ }
405
+ }
394
406
  async function loadScene(mujoco, config, onProgress) {
395
407
  try {
396
408
  mujoco.FS.unmount("/working");
@@ -402,66 +414,75 @@ async function loadScene(mujoco, config, onProgress) {
402
414
  }
403
415
  const baseUrl = config.src.endsWith("/") ? config.src : config.src + "/";
404
416
  const downloaded = /* @__PURE__ */ new Set();
405
- const queue = [config.sceneFile];
417
+ const xmlQueue = [config.sceneFile];
418
+ const assetFiles = [];
406
419
  const parser = new DOMParser();
407
- while (queue.length > 0) {
408
- const fname = queue.shift();
420
+ while (xmlQueue.length > 0) {
421
+ const fname = xmlQueue.shift();
409
422
  if (downloaded.has(fname)) continue;
410
423
  downloaded.add(fname);
424
+ if (!fname.endsWith(".xml")) {
425
+ assetFiles.push(fname);
426
+ continue;
427
+ }
411
428
  onProgress?.(`Downloading ${fname}...`);
412
429
  const res = await fetch(baseUrl + fname);
413
430
  if (!res.ok) {
414
431
  console.warn(`Failed to fetch ${fname}: ${res.status} ${res.statusText}`);
415
432
  continue;
416
433
  }
417
- const dirParts = fname.split("/");
418
- dirParts.pop();
419
- let currentPath = "/working";
420
- for (const part of dirParts) {
421
- currentPath += "/" + part;
422
- try {
423
- mujoco.FS.mkdir(currentPath);
424
- } catch {
425
- }
426
- }
427
- if (fname.endsWith(".xml")) {
428
- let text = await res.text();
429
- for (const patch of config.xmlPatches ?? []) {
430
- if (fname.endsWith(patch.target) || fname === patch.target) {
431
- if (patch.replace) {
432
- const [from, to] = patch.replace;
433
- if (text.includes(from)) {
434
- text = text.replace(from, to);
435
- } else {
436
- const preview = from.length > 80 ? `${from.slice(0, 80)}...` : from;
437
- console.warn(`XML patch replace pattern not found in ${fname}: "${preview}"`);
438
- }
434
+ let text = await res.text();
435
+ for (const patch of config.xmlPatches ?? []) {
436
+ if (fname.endsWith(patch.target) || fname === patch.target) {
437
+ if (patch.replace) {
438
+ const [from, to] = patch.replace;
439
+ if (text.includes(from)) {
440
+ text = text.replace(from, to);
441
+ } else {
442
+ const preview = from.length > 80 ? `${from.slice(0, 80)}...` : from;
443
+ console.warn(`XML patch replace pattern not found in ${fname}: "${preview}"`);
439
444
  }
440
- if (patch.inject && patch.injectAfter) {
441
- const idx = text.indexOf(patch.injectAfter);
442
- if (idx !== -1) {
443
- const tagEnd = text.indexOf(">", idx + patch.injectAfter.length);
444
- if (tagEnd !== -1) {
445
- text = text.slice(0, tagEnd + 1) + patch.inject + text.slice(tagEnd + 1);
446
- } else {
447
- console.warn(`XML patch inject failed in ${fname}: could not find tag end after "${patch.injectAfter}"`);
448
- }
445
+ }
446
+ if (patch.inject && patch.injectAfter) {
447
+ const idx = text.indexOf(patch.injectAfter);
448
+ if (idx !== -1) {
449
+ const tagEnd = text.indexOf(">", idx + patch.injectAfter.length);
450
+ if (tagEnd !== -1) {
451
+ text = text.slice(0, tagEnd + 1) + patch.inject + text.slice(tagEnd + 1);
449
452
  } else {
450
- const preview = patch.injectAfter.length > 80 ? `${patch.injectAfter.slice(0, 80)}...` : patch.injectAfter;
451
- console.warn(`XML patch inject anchor not found in ${fname}: "${preview}"`);
453
+ console.warn(`XML patch inject failed in ${fname}: could not find tag end after "${patch.injectAfter}"`);
452
454
  }
455
+ } else {
456
+ const preview = patch.injectAfter.length > 80 ? `${patch.injectAfter.slice(0, 80)}...` : patch.injectAfter;
457
+ console.warn(`XML patch inject anchor not found in ${fname}: "${preview}"`);
453
458
  }
454
459
  }
455
460
  }
456
- if (fname === config.sceneFile && config.sceneObjects?.length) {
457
- const xml = config.sceneObjects.map((obj) => sceneObjectToXml(obj)).join("");
458
- text = text.replace("</worldbody>", xml + "</worldbody>");
459
- }
460
- mujoco.FS.writeFile(`/working/${fname}`, text);
461
- scanDependencies(text, fname, parser, downloaded, queue);
462
- } else {
463
- const buffer = new Uint8Array(await res.arrayBuffer());
464
- mujoco.FS.writeFile(`/working/${fname}`, buffer);
461
+ }
462
+ if (fname === config.sceneFile && config.sceneObjects?.length) {
463
+ const xml = config.sceneObjects.map((obj) => sceneObjectToXml(obj)).join("");
464
+ text = text.replace("</worldbody>", xml + "</worldbody>");
465
+ }
466
+ ensureDir(mujoco, fname);
467
+ mujoco.FS.writeFile(`/working/${fname}`, text);
468
+ scanDependencies(text, fname, parser, downloaded, xmlQueue);
469
+ }
470
+ if (assetFiles.length > 0) {
471
+ onProgress?.(`Downloading ${assetFiles.length} assets...`);
472
+ const results = await Promise.all(
473
+ assetFiles.map(async (fname) => {
474
+ const res = await fetch(baseUrl + fname);
475
+ if (!res.ok) {
476
+ console.warn(`Failed to fetch ${fname}: ${res.status} ${res.statusText}`);
477
+ return null;
478
+ }
479
+ return { fname, buffer: new Uint8Array(await res.arrayBuffer()) };
480
+ })
481
+ );
482
+ for (const result of results) {
483
+ if (!result) continue;
484
+ ensureDir(mujoco, result.fname);
485
+ mujoco.FS.writeFile(`/working/${result.fname}`, result.buffer);
465
486
  }
466
487
  }
467
488
  onProgress?.("Loading model...");