mujoco-react 9.2.0 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -10
- package/dist/{chunk-33CV6HSV.js → chunk-T3GVZJ4F.js} +222 -8
- package/dist/chunk-T3GVZJ4F.js.map +1 -0
- package/dist/index.d.ts +158 -4
- package/dist/index.js +692 -130
- package/dist/index.js.map +1 -1
- package/dist/spark.d.ts +24 -2
- package/dist/spark.js +89 -3
- package/dist/spark.js.map +1 -1
- package/dist/{types-S8ggQY2n.d.ts → types-oxbxOkAx.d.ts} +120 -3
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +6 -3
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
- package/src/components/VisualScenario.tsx +178 -1
- package/src/core/MujocoSimProvider.tsx +373 -29
- package/src/core/SceneLoader.ts +13 -0
- package/src/hooks/useMountedCameraSequenceRecorder.ts +107 -0
- package/src/index.ts +49 -0
- package/src/rendering/cameraFrameCapture.ts +195 -26
- package/src/rendering/cameraFrameSource.ts +375 -0
- package/src/spark.tsx +144 -0
- package/src/types.ts +122 -2
- package/src/vite.ts +5 -2
- package/dist/chunk-33CV6HSV.js.map +0 -1
package/dist/vite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/vite.ts"],"names":[],"mappings":"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","file":"vite.js","sourcesContent":["/**\n * @license\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\ntype ViteConfig = { root: string };\ntype ViteServer = {\n watcher: {\n add(paths: string | string[]): void;\n on(event: 'add' | 'change' | 'unlink', listener: (file: string) => void): void;\n };\n};\n\nexport interface MujocoReactPluginOptions {\n /** Entry MJCF/URDF files to scan. Prefer a record for stable per-robot type names. */\n models: ModelInput;\n /** Generated resource module. Defaults to `src/mujoco-register.gen.ts`. */\n generatedRegister?: string;\n /** Module name to augment. Defaults to `mujoco-react`. */\n moduleName?: string;\n /** Disable console output. */\n disableLogging?: boolean;\n}\n\nexport interface MujocoRegisterCodegenOptions {\n models: ModelInput;\n out: string;\n moduleName?: string;\n root?: string;\n}\n\nexport interface MujocoRegisterCodegenResult {\n out: string;\n files: string[];\n counts: Record<RegisterKey, number>;\n}\n\ntype RegisterKey = 'actuators' | 'sensors' | 'bodies' | 'joints' | 'sites' | 'geoms' | 'keyframes';\nexport type ModelInput = string | readonly string[] | Record<string, string>;\n\ninterface ModelEntry {\n id: string;\n file: string;\n names: Record<RegisterKey, Set<string>>;\n}\n\nconst REGISTER_KEYS: RegisterKey[] = ['actuators', 'sensors', 'bodies', 'joints', 'sites', 'geoms', 'keyframes'];\nconst MODEL_EXTENSIONS = new Set(['.xml', '.mjcf', '.urdf']);\n\nfunction createEmptyNames(): Record<RegisterKey, Set<string>> {\n return {\n actuators: new Set(),\n sensors: new Set(),\n bodies: new Set(),\n joints: new Set(),\n sites: new Set(),\n geoms: new Set(),\n keyframes: new Set(),\n };\n}\n\nexport function mujocoReact(options: MujocoReactPluginOptions) {\n const models = normalizeModels(options.models);\n let root = process.cwd();\n let generatedRegister = options.generatedRegister ?? 'src/mujoco-register.gen.ts';\n let watchedFiles: string[] = [];\n\n async function generate() {\n const result = await generateMujocoRegister({\n models: options.models,\n out: generatedRegister,\n moduleName: options.moduleName,\n root,\n });\n watchedFiles = result.files;\n if (!options.disableLogging) {\n const total = Object.values(result.counts).reduce((sum, count) => sum + count, 0);\n console.log(`[mujoco-react] generated ${path.relative(root, result.out)} (${total} names)`);\n }\n return result;\n }\n\n return {\n name: 'mujoco-react',\n enforce: 'pre' as const,\n config(userConfig: { build?: { chunkSizeWarningLimit?: number } }) {\n // three + drei + MuJoCo WASM glue are inherently large; the large-chunk\n // warning is expected, not a failure. Raise the limit so consumers don't\n // see it. Vite merges plugin config on top of user config, so only set a\n // default when the consumer hasn't specified their own limit.\n if (userConfig.build?.chunkSizeWarningLimit !== undefined) return;\n return { build: { chunkSizeWarningLimit: 4000 } };\n },\n configResolved(config: ViteConfig) {\n root = config.root;\n generatedRegister = path.resolve(root, generatedRegister);\n },\n transform(code: string, id: string) {\n if (!shouldInjectRegisterImport(id, root, generatedRegister)) return;\n return `${renderGeneratedImport(id, generatedRegister)}\\n${code}`;\n },\n async buildStart(this: { addWatchFile?: (file: string) => void }) {\n const result = await generate();\n for (const file of result.files) this.addWatchFile?.(file);\n },\n configureServer(server: ViteServer) {\n generate().then((result) => server.watcher.add(result.files)).catch((error: unknown) => {\n console.error('[mujoco-react] register generation failed', error);\n });\n\n server.watcher.on('add', regenerateIfModelFile);\n server.watcher.on('change', regenerateIfModelFile);\n server.watcher.on('unlink', regenerateIfModelFile);\n\n function regenerateIfModelFile(file: string) {\n if (!shouldRegenerate(file, watchedFiles, models, root)) return;\n generate().then((result) => server.watcher.add(result.files)).catch((error: unknown) => {\n console.error('[mujoco-react] register generation failed', error);\n });\n }\n },\n };\n}\n\nexport async function generateMujocoRegister(\n options: MujocoRegisterCodegenOptions\n): Promise<MujocoRegisterCodegenResult> {\n const root = path.resolve(options.root ?? process.cwd());\n const out = path.resolve(root, options.out);\n const moduleName = options.moduleName ?? 'mujoco-react';\n const models = normalizeModels(options.models);\n const names = createEmptyNames();\n const seen = new Set<string>();\n const declarationsOnly = out.endsWith('.d.ts');\n\n for (const model of models) {\n await scanModel(path.resolve(root, model.file), root, seen, model.names);\n mergeNames(names, model.names);\n }\n\n await mkdir(path.dirname(out), { recursive: true });\n await writeFile(out, renderRegister(moduleName, names, models, declarationsOnly), 'utf8');\n\n return {\n out,\n files: [...seen].sort((a, b) => a.localeCompare(b)),\n counts: Object.fromEntries(REGISTER_KEYS.map((key) => [key, names[key].size])) as Record<RegisterKey, number>,\n };\n}\n\nasync function scanModel(\n filePath: string,\n root: string,\n seen: Set<string>,\n names: Record<RegisterKey, Set<string>>\n) {\n const normalized = path.normalize(filePath);\n if (seen.has(normalized)) return;\n seen.add(normalized);\n\n const xml = await readFile(normalized, 'utf8');\n collectSimpleTagNames(xml, 'body', names.bodies);\n collectSimpleTagNames(xml, 'joint', names.joints);\n collectSimpleTagNames(xml, 'site', names.sites);\n collectSimpleTagNames(xml, 'geom', names.geoms);\n collectSimpleTagNames(xml, 'key', names.keyframes);\n collectSectionNames(xml, 'actuator', names.actuators);\n collectSectionNames(xml, 'sensor', names.sensors);\n\n for (const includePath of collectIncludePaths(xml)) {\n const next = path.resolve(path.dirname(normalized), includePath);\n if (next.startsWith(root)) await scanModel(next, root, seen, names);\n }\n}\n\nfunction collectSimpleTagNames(xml: string, tag: string, target: Set<string>) {\n const pattern = new RegExp(`<\\\\s*${tag}\\\\b([^>]*)>`, 'gi');\n for (const match of xml.matchAll(pattern)) {\n const name = readAttr(match[1], 'name');\n if (name) target.add(name);\n }\n}\n\nfunction collectSectionNames(xml: string, section: string, target: Set<string>) {\n const sectionPattern = new RegExp(`<\\\\s*${section}\\\\b[^>]*>([\\\\s\\\\S]*?)<\\\\s*/\\\\s*${section}\\\\s*>`, 'gi');\n for (const sectionMatch of xml.matchAll(sectionPattern)) {\n const tagPattern = /<\\s*[a-zA-Z0-9_:-]+\\b([^>]*)>/g;\n for (const tagMatch of sectionMatch[1].matchAll(tagPattern)) {\n const name = readAttr(tagMatch[1], 'name');\n if (name) target.add(name);\n }\n }\n}\n\nfunction collectIncludePaths(xml: string): string[] {\n const result: string[] = [];\n const pattern = /<\\s*include\\b([^>]*)>/gi;\n for (const match of xml.matchAll(pattern)) {\n const file = readAttr(match[1], 'file');\n if (file && !file.includes('://') && !file.startsWith('/')) result.push(file);\n }\n return result;\n}\n\nfunction readAttr(attrs: string, attr: string): string | undefined {\n const pattern = new RegExp(`\\\\b${attr}\\\\s*=\\\\s*(['\"])(.*?)\\\\1`, 'i');\n return attrs.match(pattern)?.[2];\n}\n\nfunction renderRegister(\n moduleName: string,\n names: Record<RegisterKey, Set<string>>,\n models: readonly ModelEntry[],\n declarationsOnly: boolean\n): string {\n const fields = REGISTER_KEYS\n .filter((key) => names[key].size > 0)\n .map((key) => ` ${key}: ${renderUnion(names[key])};`);\n const robots = models\n .map((model) => ` ${quoteProperty(model.id)}: {\\n${renderRobotFields(model.names)}\\n };`);\n const namespaceAliases = renderNamespaceAliases(models);\n const registerImport = declarationsOnly ? '' : `import { registerRobotResources } from '${moduleName}';\\n`;\n const resources = declarationsOnly ? '' : `${renderResourceTypes(models)}\\n\\n${renderResourceConstants(models)}\\n\\nregisterRobotResources(generatedRobotResources);\\n\\n`;\n\n return `// Auto-generated by mujoco-react. Do not edit.\n// Regenerate by running Vite with the mujocoReact() plugin or \\`mujoco-react codegen\\`.\n\n${registerImport}import type { RobotResource } from '${moduleName}';\n\n${resources}declare module '${moduleName}' {\n interface Register {\n robots: {\n${robots.join('\\n')}\n };\n${fields.join('\\n')}\n }\n\n${namespaceAliases}\n}\n`;\n}\n\nfunction renderResourceTypes(models: readonly ModelEntry[]): string {\n const modelTypes = models\n .map((model) => ` readonly ${quoteProperty(model.id)}: {\\n${renderResourceTypeFields(model.names)}\\n };`)\n .join('\\n');\n return `type GeneratedRobotResources = {\\n${modelTypes}\\n};`;\n}\n\nfunction renderResourceTypeFields(names: Record<RegisterKey, Set<string>>): string {\n return REGISTER_KEYS\n .map((key) => ` readonly ${key}: ${renderResourceObjectType(names[key])};`)\n .join('\\n');\n}\n\nfunction renderResourceObjectType(values: Set<string>): string {\n const entries = sortedValues(values)\n .map((value) => ` readonly ${quoteProperty(value)}: '${escapeTs(value)}';`);\n return entries.length > 0 ? `{\\n${entries.join('\\n')}\\n }` : '{}';\n}\n\nfunction renderResourceConstants(models: readonly ModelEntry[]): string {\n const entries = models\n .map((model) => ` ${quoteProperty(model.id)}: {\\n${renderResourceConstantFields(model.names)}\\n },`)\n .join('\\n');\n return `const generatedRobotResources: GeneratedRobotResources = {\\n${entries}\\n};`;\n}\n\nfunction renderResourceConstantFields(names: Record<RegisterKey, Set<string>>): string {\n return REGISTER_KEYS\n .map((key) => ` ${key}: ${renderResourceObject(names[key])},`)\n .join('\\n');\n}\n\nfunction renderResourceObject(values: Set<string>): string {\n const entries = sortedValues(values)\n .map((value) => ` ${quoteProperty(value)}: '${escapeTs(value)}',`);\n return entries.length > 0 ? `{\\n${entries.join('\\n')}\\n }` : '{}';\n}\n\nfunction renderRobotFields(names: Record<RegisterKey, Set<string>>): string {\n return REGISTER_KEYS\n .map((key) => ` ${key}: ${names[key].size > 0 ? renderUnion(names[key]) : 'never'};`)\n .join('\\n');\n}\n\nfunction renderUnion(values: Set<string>): string {\n return sortedValues(values).map((value) => `'${escapeTs(value)}'`).join(' | ');\n}\n\nfunction renderNamespaceAliases(models: readonly ModelEntry[]): string {\n const namespaces: Record<RegisterKey, string> = {\n actuators: 'RobotActuators',\n sensors: 'RobotSensors',\n bodies: 'RobotBodies',\n joints: 'RobotJoints',\n sites: 'RobotSites',\n geoms: 'RobotGeoms',\n keyframes: 'RobotKeyframes',\n };\n\n const blocks = REGISTER_KEYS\n .map((key) => {\n const aliases = models\n .filter((model) => isIdentifier(model.id))\n .map((model) => ` export type ${model.id} = RobotResource<'${escapeTs(model.id)}', '${key}'>;`);\n if (aliases.length === 0) return '';\n return ` export namespace ${namespaces[key]} {\\n${aliases.join('\\n')}\\n }`;\n })\n .filter(Boolean)\n .join('\\n\\n');\n\n return blocks ? `${blocks}\\n` : '';\n}\n\nfunction escapeTs(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nfunction sortedValues(values: Set<string>): string[] {\n return [...values].sort((a, b) => a.localeCompare(b));\n}\n\nfunction quoteProperty(value: string): string {\n return isIdentifier(value) ? value : `'${escapeTs(value)}'`;\n}\n\nfunction isIdentifier(value: string): boolean {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value);\n}\n\nfunction toPosixPath(value: string): string {\n return value.split(path.sep).join('/');\n}\n\nfunction shouldInjectRegisterImport(id: string, root: string, generatedRegister: string): boolean {\n if (generatedRegister.endsWith('.d.ts')) return false;\n const file = stripQuery(id);\n if (!/\\.[cm]?[jt]sx?$/.test(file)) return false;\n if (file.includes(`${path.sep}node_modules${path.sep}`)) return false;\n const absolute = path.resolve(file);\n if (absolute === generatedRegister) return false;\n return absolute.startsWith(root);\n}\n\nfunction renderGeneratedImport(id: string, generatedRegister: string): string {\n const fromDir = path.dirname(stripQuery(id));\n let relative = toPosixPath(path.relative(fromDir, generatedRegister));\n if (!relative.startsWith('.')) relative = `./${relative}`;\n return `import '${relative}';`;\n}\n\nfunction stripQuery(id: string): string {\n return id.split('?')[0];\n}\n\nfunction normalizeModels(input: ModelInput): ModelEntry[] {\n if (typeof input === 'string') return [createModelEntry(deriveModelId(input), input)];\n if (Array.isArray(input)) return input.map((file) => createModelEntry(deriveModelId(file), file));\n return Object.entries(input).map(([id, file]) => createModelEntry(sanitizeModelId(id), file));\n}\n\nfunction createModelEntry(id: string, file: string): ModelEntry {\n return { id, file, names: createEmptyNames() };\n}\n\nfunction deriveModelId(file: string): string {\n const normalized = file.replace(/\\\\/g, '/');\n const parts = normalized.split('/').filter(Boolean);\n const filename = parts.at(-1) ?? 'model';\n const parent = parts.length > 1 ? parts.at(-2) : undefined;\n const base = filename.replace(/\\.(xml|mjcf|urdf)$/i, '');\n return sanitizeModelId(parent && ['scene', 'model', 'robot'].includes(base.toLowerCase()) ? parent : base);\n}\n\nfunction sanitizeModelId(value: string): string {\n const sanitized = value.replace(/[^A-Za-z0-9_$]/g, '_').replace(/^[^A-Za-z_$]+/, '');\n return sanitized || 'model';\n}\n\nfunction mergeNames(target: Record<RegisterKey, Set<string>>, source: Record<RegisterKey, Set<string>>) {\n for (const key of REGISTER_KEYS) {\n for (const value of source[key]) target[key].add(value);\n }\n}\n\nfunction shouldRegenerate(file: string, watchedFiles: string[], models: readonly ModelEntry[], root: string): boolean {\n const absolute = path.resolve(file);\n if (watchedFiles.includes(absolute)) return true;\n if (!MODEL_EXTENSIONS.has(path.extname(absolute).toLowerCase())) return false;\n const modelDirs = models.map((model) => path.dirname(path.resolve(root, model.file)));\n return modelDirs.some((dir) => absolute.startsWith(dir));\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/vite.ts"],"names":[],"mappings":"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","file":"vite.js","sourcesContent":["/**\n * @license\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\n\ntype ViteConfig = { root: string };\ntype ViteServer = {\n watcher: {\n add(paths: string | string[]): void;\n on(event: 'add' | 'change' | 'unlink', listener: (file: string) => void): void;\n };\n};\n\nexport interface MujocoReactPluginOptions {\n /** Entry MJCF/URDF files to scan. Prefer a record for stable per-robot type names. */\n models: ModelInput;\n /** Generated resource module. Defaults to `src/mujoco-register.gen.ts`. */\n generatedRegister?: string;\n /** Module name to augment. Defaults to `mujoco-react`. */\n moduleName?: string;\n /** Disable console output. */\n disableLogging?: boolean;\n}\n\nexport interface MujocoRegisterCodegenOptions {\n models: ModelInput;\n out: string;\n moduleName?: string;\n root?: string;\n}\n\nexport interface MujocoRegisterCodegenResult {\n out: string;\n files: string[];\n counts: Record<RegisterKey, number>;\n}\n\ntype RegisterKey = 'actuators' | 'sensors' | 'bodies' | 'joints' | 'sites' | 'geoms' | 'keyframes' | 'cameras';\nexport type ModelInput = string | readonly string[] | Record<string, string>;\n\ninterface ModelEntry {\n id: string;\n file: string;\n names: Record<RegisterKey, Set<string>>;\n}\n\nconst REGISTER_KEYS: RegisterKey[] = ['actuators', 'sensors', 'bodies', 'joints', 'sites', 'geoms', 'keyframes', 'cameras'];\nconst MODEL_EXTENSIONS = new Set(['.xml', '.mjcf', '.urdf']);\n\nfunction createEmptyNames(): Record<RegisterKey, Set<string>> {\n return {\n actuators: new Set(),\n sensors: new Set(),\n bodies: new Set(),\n joints: new Set(),\n sites: new Set(),\n geoms: new Set(),\n keyframes: new Set(),\n cameras: new Set(),\n };\n}\n\nexport function mujocoReact(options: MujocoReactPluginOptions) {\n const models = normalizeModels(options.models);\n let root = process.cwd();\n let generatedRegister = options.generatedRegister ?? 'src/mujoco-register.gen.ts';\n let watchedFiles: string[] = [];\n\n async function generate() {\n const result = await generateMujocoRegister({\n models: options.models,\n out: generatedRegister,\n moduleName: options.moduleName,\n root,\n });\n watchedFiles = result.files;\n if (!options.disableLogging) {\n const total = Object.values(result.counts).reduce((sum, count) => sum + count, 0);\n console.log(`[mujoco-react] generated ${path.relative(root, result.out)} (${total} names)`);\n }\n return result;\n }\n\n return {\n name: 'mujoco-react',\n enforce: 'pre' as const,\n config(userConfig: { build?: { chunkSizeWarningLimit?: number } }) {\n // three + drei + MuJoCo WASM glue are inherently large; the large-chunk\n // warning is expected, not a failure. Raise the limit so consumers don't\n // see it. Vite merges plugin config on top of user config, so only set a\n // default when the consumer hasn't specified their own limit.\n if (userConfig.build?.chunkSizeWarningLimit !== undefined) return;\n return { build: { chunkSizeWarningLimit: 4000 } };\n },\n configResolved(config: ViteConfig) {\n root = config.root;\n generatedRegister = path.resolve(root, generatedRegister);\n },\n transform(code: string, id: string) {\n if (!shouldInjectRegisterImport(id, root, generatedRegister)) return;\n return `${renderGeneratedImport(id, generatedRegister)}\\n${code}`;\n },\n async buildStart(this: { addWatchFile?: (file: string) => void }) {\n const result = await generate();\n for (const file of result.files) this.addWatchFile?.(file);\n },\n configureServer(server: ViteServer) {\n generate().then((result) => server.watcher.add(result.files)).catch((error: unknown) => {\n console.error('[mujoco-react] register generation failed', error);\n });\n\n server.watcher.on('add', regenerateIfModelFile);\n server.watcher.on('change', regenerateIfModelFile);\n server.watcher.on('unlink', regenerateIfModelFile);\n\n function regenerateIfModelFile(file: string) {\n if (!shouldRegenerate(file, watchedFiles, models, root)) return;\n generate().then((result) => server.watcher.add(result.files)).catch((error: unknown) => {\n console.error('[mujoco-react] register generation failed', error);\n });\n }\n },\n };\n}\n\nexport async function generateMujocoRegister(\n options: MujocoRegisterCodegenOptions\n): Promise<MujocoRegisterCodegenResult> {\n const root = path.resolve(options.root ?? process.cwd());\n const out = path.resolve(root, options.out);\n const moduleName = options.moduleName ?? 'mujoco-react';\n const models = normalizeModels(options.models);\n const names = createEmptyNames();\n const seen = new Set<string>();\n const declarationsOnly = out.endsWith('.d.ts');\n\n for (const model of models) {\n await scanModel(path.resolve(root, model.file), root, seen, model.names);\n mergeNames(names, model.names);\n }\n\n await mkdir(path.dirname(out), { recursive: true });\n await writeFile(out, renderRegister(moduleName, names, models, declarationsOnly), 'utf8');\n\n return {\n out,\n files: [...seen].sort((a, b) => a.localeCompare(b)),\n counts: Object.fromEntries(REGISTER_KEYS.map((key) => [key, names[key].size])) as Record<RegisterKey, number>,\n };\n}\n\nasync function scanModel(\n filePath: string,\n root: string,\n seen: Set<string>,\n names: Record<RegisterKey, Set<string>>\n) {\n const normalized = path.normalize(filePath);\n if (seen.has(normalized)) return;\n seen.add(normalized);\n\n const xml = await readFile(normalized, 'utf8');\n collectSimpleTagNames(xml, 'body', names.bodies);\n collectSimpleTagNames(xml, 'joint', names.joints);\n collectSimpleTagNames(xml, 'site', names.sites);\n collectSimpleTagNames(xml, 'geom', names.geoms);\n collectSimpleTagNames(xml, 'camera', names.cameras);\n collectSimpleTagNames(xml, 'key', names.keyframes);\n collectSectionNames(xml, 'actuator', names.actuators);\n collectSectionNames(xml, 'sensor', names.sensors);\n\n for (const includePath of collectIncludePaths(xml)) {\n const next = path.resolve(path.dirname(normalized), includePath);\n if (next.startsWith(root)) await scanModel(next, root, seen, names);\n }\n}\n\nfunction collectSimpleTagNames(xml: string, tag: string, target: Set<string>) {\n const pattern = new RegExp(`<\\\\s*${tag}\\\\b([^>]*)>`, 'gi');\n for (const match of xml.matchAll(pattern)) {\n const name = readAttr(match[1], 'name');\n if (name) target.add(name);\n }\n}\n\nfunction collectSectionNames(xml: string, section: string, target: Set<string>) {\n const sectionPattern = new RegExp(`<\\\\s*${section}\\\\b[^>]*>([\\\\s\\\\S]*?)<\\\\s*/\\\\s*${section}\\\\s*>`, 'gi');\n for (const sectionMatch of xml.matchAll(sectionPattern)) {\n const tagPattern = /<\\s*[a-zA-Z0-9_:-]+\\b([^>]*)>/g;\n for (const tagMatch of sectionMatch[1].matchAll(tagPattern)) {\n const name = readAttr(tagMatch[1], 'name');\n if (name) target.add(name);\n }\n }\n}\n\nfunction collectIncludePaths(xml: string): string[] {\n const result: string[] = [];\n const pattern = /<\\s*include\\b([^>]*)>/gi;\n for (const match of xml.matchAll(pattern)) {\n const file = readAttr(match[1], 'file');\n if (file && !file.includes('://') && !file.startsWith('/')) result.push(file);\n }\n return result;\n}\n\nfunction readAttr(attrs: string, attr: string): string | undefined {\n const pattern = new RegExp(`\\\\b${attr}\\\\s*=\\\\s*(['\"])(.*?)\\\\1`, 'i');\n return attrs.match(pattern)?.[2];\n}\n\nfunction renderRegister(\n moduleName: string,\n names: Record<RegisterKey, Set<string>>,\n models: readonly ModelEntry[],\n declarationsOnly: boolean\n): string {\n const fields = REGISTER_KEYS\n .filter((key) => names[key].size > 0)\n .map((key) => ` ${key}: ${renderUnion(names[key])};`);\n const robots = models\n .map((model) => ` ${quoteProperty(model.id)}: {\\n${renderRobotFields(model.names)}\\n };`);\n const namespaceAliases = renderNamespaceAliases(models);\n const registerImport = declarationsOnly ? '' : `import { registerRobotResources } from '${moduleName}';\\n`;\n const resources = declarationsOnly ? '' : `${renderResourceTypes(models)}\\n\\n${renderResourceConstants(models)}\\n\\nregisterRobotResources(generatedRobotResources);\\n\\n`;\n\n return `// Auto-generated by mujoco-react. Do not edit.\n// Regenerate by running Vite with the mujocoReact() plugin or \\`mujoco-react codegen\\`.\n\n${registerImport}import type { RobotResource } from '${moduleName}';\n\n${resources}declare module '${moduleName}' {\n interface Register {\n robots: {\n${robots.join('\\n')}\n };\n${fields.join('\\n')}\n }\n\n${namespaceAliases}\n}\n`;\n}\n\nfunction renderResourceTypes(models: readonly ModelEntry[]): string {\n const modelTypes = models\n .map((model) => ` readonly ${quoteProperty(model.id)}: {\\n${renderResourceTypeFields(model.names)}\\n };`)\n .join('\\n');\n return `type GeneratedRobotResources = {\\n${modelTypes}\\n};`;\n}\n\nfunction renderResourceTypeFields(names: Record<RegisterKey, Set<string>>): string {\n return REGISTER_KEYS\n .map((key) => ` readonly ${key}: ${renderResourceObjectType(names[key])};`)\n .join('\\n');\n}\n\nfunction renderResourceObjectType(values: Set<string>): string {\n const entries = sortedValues(values)\n .map((value) => ` readonly ${quoteProperty(value)}: '${escapeTs(value)}';`);\n return entries.length > 0 ? `{\\n${entries.join('\\n')}\\n }` : '{}';\n}\n\nfunction renderResourceConstants(models: readonly ModelEntry[]): string {\n const entries = models\n .map((model) => ` ${quoteProperty(model.id)}: {\\n${renderResourceConstantFields(model.names)}\\n },`)\n .join('\\n');\n return `const generatedRobotResources: GeneratedRobotResources = {\\n${entries}\\n};`;\n}\n\nfunction renderResourceConstantFields(names: Record<RegisterKey, Set<string>>): string {\n return REGISTER_KEYS\n .map((key) => ` ${key}: ${renderResourceObject(names[key])},`)\n .join('\\n');\n}\n\nfunction renderResourceObject(values: Set<string>): string {\n const entries = sortedValues(values)\n .map((value) => ` ${quoteProperty(value)}: '${escapeTs(value)}',`);\n return entries.length > 0 ? `{\\n${entries.join('\\n')}\\n }` : '{}';\n}\n\nfunction renderRobotFields(names: Record<RegisterKey, Set<string>>): string {\n return REGISTER_KEYS\n .map((key) => ` ${key}: ${names[key].size > 0 ? renderUnion(names[key]) : 'never'};`)\n .join('\\n');\n}\n\nfunction renderUnion(values: Set<string>): string {\n return sortedValues(values).map((value) => `'${escapeTs(value)}'`).join(' | ');\n}\n\nfunction renderNamespaceAliases(models: readonly ModelEntry[]): string {\n const namespaces: Record<RegisterKey, string> = {\n actuators: 'RobotActuators',\n sensors: 'RobotSensors',\n bodies: 'RobotBodies',\n joints: 'RobotJoints',\n sites: 'RobotSites',\n geoms: 'RobotGeoms',\n keyframes: 'RobotKeyframes',\n cameras: 'RobotCameras',\n };\n\n const blocks = REGISTER_KEYS\n .map((key) => {\n const aliases = models\n .filter((model) => isIdentifier(model.id))\n .map((model) => ` export type ${model.id} = RobotResource<'${escapeTs(model.id)}', '${key}'>;`);\n if (aliases.length === 0) return '';\n return ` export namespace ${namespaces[key]} {\\n${aliases.join('\\n')}\\n }`;\n })\n .filter(Boolean)\n .join('\\n\\n');\n\n return blocks ? `${blocks}\\n` : '';\n}\n\nfunction escapeTs(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nfunction sortedValues(values: Set<string>): string[] {\n return [...values].sort((a, b) => a.localeCompare(b));\n}\n\nfunction quoteProperty(value: string): string {\n return isIdentifier(value) ? value : `'${escapeTs(value)}'`;\n}\n\nfunction isIdentifier(value: string): boolean {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value);\n}\n\nfunction toPosixPath(value: string): string {\n return value.split(path.sep).join('/');\n}\n\nfunction shouldInjectRegisterImport(id: string, root: string, generatedRegister: string): boolean {\n if (generatedRegister.endsWith('.d.ts')) return false;\n const file = stripQuery(id);\n if (!/\\.[cm]?[jt]sx?$/.test(file)) return false;\n if (file.includes(`${path.sep}node_modules${path.sep}`)) return false;\n const absolute = path.resolve(file);\n if (absolute === generatedRegister) return false;\n return absolute.startsWith(root);\n}\n\nfunction renderGeneratedImport(id: string, generatedRegister: string): string {\n const fromDir = path.dirname(stripQuery(id));\n let relative = toPosixPath(path.relative(fromDir, generatedRegister));\n if (!relative.startsWith('.')) relative = `./${relative}`;\n return `import '${relative}';`;\n}\n\nfunction stripQuery(id: string): string {\n return id.split('?')[0];\n}\n\nfunction normalizeModels(input: ModelInput): ModelEntry[] {\n if (typeof input === 'string') return [createModelEntry(deriveModelId(input), input)];\n if (Array.isArray(input)) return input.map((file) => createModelEntry(deriveModelId(file), file));\n return Object.entries(input).map(([id, file]) => createModelEntry(sanitizeModelId(id), file));\n}\n\nfunction createModelEntry(id: string, file: string): ModelEntry {\n return { id, file, names: createEmptyNames() };\n}\n\nfunction deriveModelId(file: string): string {\n const normalized = file.replace(/\\\\/g, '/');\n const parts = normalized.split('/').filter(Boolean);\n const filename = parts.at(-1) ?? 'model';\n const parent = parts.length > 1 ? parts.at(-2) : undefined;\n const base = filename.replace(/\\.(xml|mjcf|urdf)$/i, '');\n return sanitizeModelId(parent && ['scene', 'model', 'robot'].includes(base.toLowerCase()) ? parent : base);\n}\n\nfunction sanitizeModelId(value: string): string {\n const sanitized = value.replace(/[^A-Za-z0-9_$]/g, '_').replace(/^[^A-Za-z_$]+/, '');\n return sanitized || 'model';\n}\n\nfunction mergeNames(target: Record<RegisterKey, Set<string>>, source: Record<RegisterKey, Set<string>>) {\n for (const key of REGISTER_KEYS) {\n for (const value of source[key]) target[key].add(value);\n }\n}\n\nfunction shouldRegenerate(file: string, watchedFiles: string[], models: readonly ModelEntry[], root: string): boolean {\n const absolute = path.resolve(file);\n if (watchedFiles.includes(absolute)) return true;\n if (!MODEL_EXTENSIONS.has(path.extname(absolute).toLowerCase())) return false;\n const modelDirs = models.map((model) => path.dirname(path.resolve(root, model.file)));\n return modelDirs.some((dir) => absolute.startsWith(dir));\n}\n"]}
|
package/package.json
CHANGED
|
@@ -8,15 +8,19 @@ import type { ThreeElements } from '@react-three/fiber';
|
|
|
8
8
|
import type { ReactNode } from 'react';
|
|
9
9
|
import { useEffect, useMemo } from 'react';
|
|
10
10
|
import * as THREE from 'three';
|
|
11
|
+
import { SplatEnvironmentReadinessStatus } from '../types';
|
|
11
12
|
import type {
|
|
12
13
|
PairedSplatEnvironmentConfig,
|
|
13
14
|
ScenarioMaterialConfig,
|
|
14
15
|
SceneConfig,
|
|
15
16
|
SplatCollisionProxyConfig,
|
|
17
|
+
SplatEnvironmentReadiness,
|
|
16
18
|
SplatEnvironmentMetadata,
|
|
17
19
|
SplatEnvironmentMetadataInput,
|
|
18
20
|
SplatFormat,
|
|
19
21
|
SplatRendererKind,
|
|
22
|
+
SplatSceneConfigInput,
|
|
23
|
+
SplatSceneConfigState,
|
|
20
24
|
SplatSceneInput,
|
|
21
25
|
ScenarioLightingPreset,
|
|
22
26
|
ScenarioLightingProps,
|
|
@@ -277,23 +281,192 @@ export function useSplatEnvironment({
|
|
|
277
281
|
scenarioEnvironment?.collisionProxy ??
|
|
278
282
|
scenario?.splat?.collisionProxy ??
|
|
279
283
|
undefined;
|
|
284
|
+
const readiness = useMemo(
|
|
285
|
+
() =>
|
|
286
|
+
getSplatEnvironmentReadiness({
|
|
287
|
+
environment: scenarioEnvironment,
|
|
288
|
+
scenario,
|
|
289
|
+
renderer,
|
|
290
|
+
src: resolvedSrc,
|
|
291
|
+
format: resolvedFormat,
|
|
292
|
+
collisionProxy: resolvedCollisionProxy,
|
|
293
|
+
}),
|
|
294
|
+
[
|
|
295
|
+
collisionProxy,
|
|
296
|
+
renderer,
|
|
297
|
+
resolvedCollisionProxy,
|
|
298
|
+
resolvedFormat,
|
|
299
|
+
resolvedSrc,
|
|
300
|
+
scenario,
|
|
301
|
+
scenarioEnvironment,
|
|
302
|
+
]
|
|
303
|
+
);
|
|
280
304
|
|
|
281
305
|
return useMemo(
|
|
282
306
|
() => ({
|
|
283
307
|
src: resolvedSrc,
|
|
284
308
|
format: resolvedFormat,
|
|
285
309
|
collisionProxy: resolvedCollisionProxy,
|
|
310
|
+
readiness,
|
|
286
311
|
userData: createSplatEnvironmentUserData({
|
|
287
312
|
environment: scenarioEnvironment,
|
|
288
313
|
src: resolvedSrc,
|
|
289
314
|
format: resolvedFormat,
|
|
290
315
|
collisionProxy: resolvedCollisionProxy,
|
|
316
|
+
readiness,
|
|
291
317
|
}),
|
|
292
318
|
}),
|
|
293
|
-
[
|
|
319
|
+
[
|
|
320
|
+
scenarioEnvironment,
|
|
321
|
+
resolvedSrc,
|
|
322
|
+
resolvedFormat,
|
|
323
|
+
resolvedCollisionProxy,
|
|
324
|
+
readiness,
|
|
325
|
+
]
|
|
294
326
|
);
|
|
295
327
|
}
|
|
296
328
|
|
|
329
|
+
/**
|
|
330
|
+
* Resolve a visual scenario's paired splat environment and compose its MJCF
|
|
331
|
+
* collision proxy into a MuJoCo scene config.
|
|
332
|
+
*
|
|
333
|
+
* This hook is renderer-agnostic: apps can use it with Spark, another 3DGS
|
|
334
|
+
* renderer, or their own Three scene objects while keeping physics collision
|
|
335
|
+
* files paired with the visual splat metadata.
|
|
336
|
+
*/
|
|
337
|
+
export function useSplatSceneConfig({
|
|
338
|
+
sceneConfig,
|
|
339
|
+
scenario,
|
|
340
|
+
environment,
|
|
341
|
+
enabled = true,
|
|
342
|
+
renderer,
|
|
343
|
+
}: SplatSceneConfigInput): SplatSceneConfigState {
|
|
344
|
+
const resolvedEnvironment = useMemo(
|
|
345
|
+
() =>
|
|
346
|
+
enabled
|
|
347
|
+
? environment ??
|
|
348
|
+
(scenario
|
|
349
|
+
? createPairedSplatEnvironment(scenario, { renderer })
|
|
350
|
+
: undefined)
|
|
351
|
+
: undefined,
|
|
352
|
+
[enabled, environment, renderer, scenario]
|
|
353
|
+
);
|
|
354
|
+
const readiness = useMemo(
|
|
355
|
+
() =>
|
|
356
|
+
getSplatEnvironmentReadiness({
|
|
357
|
+
environment: resolvedEnvironment,
|
|
358
|
+
scenario,
|
|
359
|
+
renderer,
|
|
360
|
+
enabled,
|
|
361
|
+
}),
|
|
362
|
+
[enabled, renderer, resolvedEnvironment, scenario]
|
|
363
|
+
);
|
|
364
|
+
const resolvedSceneConfig = useMemo(
|
|
365
|
+
() =>
|
|
366
|
+
resolvedEnvironment
|
|
367
|
+
? withSplatEnvironment(sceneConfig, resolvedEnvironment)
|
|
368
|
+
: sceneConfig,
|
|
369
|
+
[resolvedEnvironment, sceneConfig]
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
return useMemo(
|
|
373
|
+
() => ({
|
|
374
|
+
environment: resolvedEnvironment,
|
|
375
|
+
sceneConfig: resolvedSceneConfig,
|
|
376
|
+
enabled: enabled && readiness.status !== SplatEnvironmentReadinessStatus.Disabled,
|
|
377
|
+
readiness,
|
|
378
|
+
}),
|
|
379
|
+
[enabled, readiness, resolvedEnvironment, resolvedSceneConfig]
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export function getSplatEnvironmentReadiness({
|
|
384
|
+
environment,
|
|
385
|
+
scenario,
|
|
386
|
+
renderer,
|
|
387
|
+
src,
|
|
388
|
+
format,
|
|
389
|
+
collisionProxy,
|
|
390
|
+
enabled = true,
|
|
391
|
+
}: {
|
|
392
|
+
environment?: PairedSplatEnvironmentConfig;
|
|
393
|
+
scenario?: Pick<VisualScenarioConfig, 'splat'>;
|
|
394
|
+
renderer?: SplatRendererKind;
|
|
395
|
+
src?: string;
|
|
396
|
+
format?: SplatFormat;
|
|
397
|
+
collisionProxy?: SplatCollisionProxyConfig;
|
|
398
|
+
enabled?: boolean;
|
|
399
|
+
}): SplatEnvironmentReadiness {
|
|
400
|
+
const splat = scenario?.splat;
|
|
401
|
+
const resolvedSrc = src ?? environment?.splat.src ?? splat?.src;
|
|
402
|
+
const resolvedFormat =
|
|
403
|
+
format ?? environment?.splat.format ?? splat?.format ?? 'spz';
|
|
404
|
+
const resolvedRenderer = renderer ?? environment?.splat.renderer;
|
|
405
|
+
const resolvedCollisionProxy =
|
|
406
|
+
collisionProxy ?? environment?.collisionProxy ?? splat?.collisionProxy ?? undefined;
|
|
407
|
+
const requiresCollisionProxy = splat?.requiresCollisionProxy ?? true;
|
|
408
|
+
|
|
409
|
+
if (!enabled || (splat && splat.enabled === false && !environment)) {
|
|
410
|
+
return {
|
|
411
|
+
status: SplatEnvironmentReadinessStatus.Disabled,
|
|
412
|
+
ready: false,
|
|
413
|
+
requiresCollisionProxy,
|
|
414
|
+
missing: [],
|
|
415
|
+
format: resolvedFormat,
|
|
416
|
+
renderer: resolvedRenderer,
|
|
417
|
+
message: 'Splat environment is disabled.',
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (!resolvedSrc) {
|
|
422
|
+
return {
|
|
423
|
+
status: SplatEnvironmentReadinessStatus.MissingSplat,
|
|
424
|
+
ready: false,
|
|
425
|
+
requiresCollisionProxy,
|
|
426
|
+
missing: ['splat'],
|
|
427
|
+
format: resolvedFormat,
|
|
428
|
+
renderer: resolvedRenderer,
|
|
429
|
+
message: 'Splat environment is missing a visual asset source.',
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (resolvedRenderer === 'spark' && resolvedFormat !== 'spz') {
|
|
434
|
+
return {
|
|
435
|
+
status: SplatEnvironmentReadinessStatus.UnsupportedFormat,
|
|
436
|
+
ready: false,
|
|
437
|
+
requiresCollisionProxy,
|
|
438
|
+
missing: [],
|
|
439
|
+
format: resolvedFormat,
|
|
440
|
+
renderer: resolvedRenderer,
|
|
441
|
+
message: `Spark splat rendering requires .spz assets; received ${resolvedFormat}.`,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (requiresCollisionProxy && !resolvedCollisionProxy?.xmlPath) {
|
|
446
|
+
return {
|
|
447
|
+
status: SplatEnvironmentReadinessStatus.MissingCollisionProxy,
|
|
448
|
+
ready: false,
|
|
449
|
+
requiresCollisionProxy,
|
|
450
|
+
missing: ['collisionProxy'],
|
|
451
|
+
format: resolvedFormat,
|
|
452
|
+
renderer: resolvedRenderer,
|
|
453
|
+
message: 'Splat environment is missing paired MJCF collision proxy XML.',
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return {
|
|
458
|
+
status: SplatEnvironmentReadinessStatus.Ready,
|
|
459
|
+
ready: true,
|
|
460
|
+
requiresCollisionProxy,
|
|
461
|
+
missing: [],
|
|
462
|
+
format: resolvedFormat,
|
|
463
|
+
renderer: resolvedRenderer,
|
|
464
|
+
message: requiresCollisionProxy
|
|
465
|
+
? 'Splat environment has visual asset and collision proxy metadata.'
|
|
466
|
+
: 'Splat environment has a visual asset and does not require collision proxy metadata.',
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
297
470
|
/**
|
|
298
471
|
* Convert a generic visual scenario splat block into a paired visual/physics
|
|
299
472
|
* environment config. Returns undefined until both the splat asset and MJCF
|
|
@@ -393,11 +566,13 @@ export function createSplatEnvironmentUserData({
|
|
|
393
566
|
src,
|
|
394
567
|
format = 'spz',
|
|
395
568
|
collisionProxy,
|
|
569
|
+
readiness,
|
|
396
570
|
}: {
|
|
397
571
|
environment?: PairedSplatEnvironmentConfig;
|
|
398
572
|
src?: string;
|
|
399
573
|
format?: SplatFormat;
|
|
400
574
|
collisionProxy?: SplatCollisionProxyConfig;
|
|
575
|
+
readiness?: SplatEnvironmentReadiness;
|
|
401
576
|
}) {
|
|
402
577
|
return {
|
|
403
578
|
role: 'splat-environment',
|
|
@@ -409,6 +584,8 @@ export function createSplatEnvironmentUserData({
|
|
|
409
584
|
collisionProxyStatus: collisionProxy?.status ?? 'missing',
|
|
410
585
|
collisionProxyXmlPath: collisionProxy?.xmlPath,
|
|
411
586
|
collisionProxyPrimitives: collisionProxy?.primitives ?? [],
|
|
587
|
+
readinessStatus: readiness?.status,
|
|
588
|
+
readinessMessage: readiness?.message,
|
|
412
589
|
};
|
|
413
590
|
}
|
|
414
591
|
|