mujoco-react 9.6.0 → 10.0.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/README.md +60 -62
- package/dist/{chunk-4JHALVB2.js → chunk-QTCAVQS6.js} +29 -29
- package/dist/{chunk-4JHALVB2.js.map → chunk-QTCAVQS6.js.map} +1 -1
- package/dist/index.d.ts +14 -8
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/spark.d.ts +1 -1
- package/dist/spark.js +1 -1
- package/dist/{types-C1rwH74Y.d.ts → types-BaSMqJHT.d.ts} +53 -34
- package/dist/vite.js +21 -21
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
- package/src/core/GenericIK.ts +12 -1
- package/src/core/SceneLoader.ts +1 -1
- package/src/core/createController.tsx +2 -2
- package/src/hooks/useJointState.ts +18 -7
- package/src/index.ts +17 -13
- package/src/rendering/Reflector.ts +7 -5
- package/src/types.ts +79 -56
- package/src/vite.ts +22 -22
package/src/types.ts
CHANGED
|
@@ -17,7 +17,7 @@ import * as THREE from 'three';
|
|
|
17
17
|
* ```ts
|
|
18
18
|
* declare module 'mujoco-react' {
|
|
19
19
|
* interface Register {
|
|
20
|
-
*
|
|
20
|
+
* models: {
|
|
21
21
|
* panda: {
|
|
22
22
|
* actuators: 'joint1' | 'joint2' | 'gripper';
|
|
23
23
|
* sensors: 'force_sensor' | 'torque_sensor';
|
|
@@ -35,45 +35,45 @@ import * as THREE from 'three';
|
|
|
35
35
|
*/
|
|
36
36
|
export interface Register {}
|
|
37
37
|
|
|
38
|
-
export type
|
|
38
|
+
export type RegisteredModelMap = Register extends { models: infer T extends Record<string, Record<string, string>> }
|
|
39
39
|
? T
|
|
40
40
|
: never;
|
|
41
|
-
export type
|
|
42
|
-
export type
|
|
43
|
-
[
|
|
41
|
+
export type Models = [RegisteredModelMap] extends [never] ? string : Extract<keyof RegisteredModelMap, string>;
|
|
42
|
+
export type ModelResource<TModel extends string, TKey extends string> =
|
|
43
|
+
[RegisteredModelMap] extends [never]
|
|
44
44
|
? string
|
|
45
|
-
:
|
|
46
|
-
? TKey extends keyof
|
|
47
|
-
?
|
|
45
|
+
: TModel extends keyof RegisteredModelMap
|
|
46
|
+
? TKey extends keyof RegisteredModelMap[TModel]
|
|
47
|
+
? RegisteredModelMap[TModel][TKey]
|
|
48
48
|
: string
|
|
49
49
|
: never;
|
|
50
|
-
export type
|
|
51
|
-
export type
|
|
52
|
-
export type
|
|
53
|
-
export type
|
|
54
|
-
export type
|
|
55
|
-
export type
|
|
56
|
-
export type
|
|
57
|
-
export type
|
|
50
|
+
export type ModelActuators<TModel extends string> = ModelResource<TModel, 'actuators'>;
|
|
51
|
+
export type ModelSensors<TModel extends string> = ModelResource<TModel, 'sensors'>;
|
|
52
|
+
export type ModelBodies<TModel extends string> = ModelResource<TModel, 'bodies'>;
|
|
53
|
+
export type ModelJoints<TModel extends string> = ModelResource<TModel, 'joints'>;
|
|
54
|
+
export type ModelSites<TModel extends string> = ModelResource<TModel, 'sites'>;
|
|
55
|
+
export type ModelGeoms<TModel extends string> = ModelResource<TModel, 'geoms'>;
|
|
56
|
+
export type ModelKeyframes<TModel extends string> = ModelResource<TModel, 'keyframes'>;
|
|
57
|
+
export type ModelCameras<TModel extends string> = ModelResource<TModel, 'cameras'>;
|
|
58
58
|
|
|
59
59
|
export type RegisterResourceKey = 'actuators' | 'sensors' | 'bodies' | 'joints' | 'sites' | 'geoms' | 'keyframes' | 'cameras';
|
|
60
|
-
export type
|
|
61
|
-
string extends
|
|
60
|
+
export type ModelResourceObject<TModel extends string, TKey extends RegisterResourceKey> =
|
|
61
|
+
string extends ModelResource<TModel, TKey>
|
|
62
62
|
? Record<string, string>
|
|
63
|
-
: { readonly [K in
|
|
64
|
-
export type
|
|
65
|
-
string extends
|
|
63
|
+
: { readonly [K in ModelResource<TModel, TKey>]: K };
|
|
64
|
+
export type ModelResourceCategory<TKey extends RegisterResourceKey> =
|
|
65
|
+
string extends Models
|
|
66
66
|
? Record<string, Record<string, string>>
|
|
67
|
-
: { readonly [
|
|
68
|
-
export type
|
|
69
|
-
string extends
|
|
67
|
+
: { readonly [TModel in Models]: ModelResourceObject<TModel, TKey> };
|
|
68
|
+
export type ModelResourceRegistry =
|
|
69
|
+
string extends Models
|
|
70
70
|
? Record<string, Record<RegisterResourceKey, Record<string, string>>>
|
|
71
|
-
: { readonly [
|
|
71
|
+
: { readonly [TModel in Models]: { readonly [TKey in RegisterResourceKey]: ModelResourceObject<TModel, TKey> } };
|
|
72
72
|
|
|
73
|
-
type
|
|
74
|
-
type
|
|
73
|
+
type RuntimeModelResources = Record<string, Record<RegisterResourceKey, Record<string, string>>>;
|
|
74
|
+
type RuntimeModelResourceRegistration = Readonly<Record<string, Readonly<Record<RegisterResourceKey, Readonly<Record<string, string>>>>>>;
|
|
75
75
|
|
|
76
|
-
const
|
|
76
|
+
const runtimeModelResources: RuntimeModelResources = {};
|
|
77
77
|
const REGISTER_RESOURCE_KEYS: RegisterResourceKey[] = ['actuators', 'sensors', 'bodies', 'joints', 'sites', 'geoms', 'keyframes', 'cameras'];
|
|
78
78
|
|
|
79
79
|
function createEmptyRuntimeResources(): Record<RegisterResourceKey, Record<string, string>> {
|
|
@@ -89,54 +89,54 @@ function createEmptyRuntimeResources(): Record<RegisterResourceKey, Record<strin
|
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
export function
|
|
93
|
-
for (const [
|
|
94
|
-
const existing =
|
|
92
|
+
export function registerModelResources(resources: RuntimeModelResourceRegistration): void {
|
|
93
|
+
for (const [model, modelResources] of Object.entries(resources)) {
|
|
94
|
+
const existing = runtimeModelResources[model] ?? createEmptyRuntimeResources();
|
|
95
95
|
for (const key of REGISTER_RESOURCE_KEYS) {
|
|
96
|
-
existing[key] = { ...existing[key], ...(
|
|
96
|
+
existing[key] = { ...existing[key], ...(modelResources[key] ?? {}) };
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
runtimeModelResources[model] = existing;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
function createResourceCategory<TKey extends RegisterResourceKey>(key: TKey):
|
|
102
|
+
function createResourceCategory<TKey extends RegisterResourceKey>(key: TKey): ModelResourceCategory<TKey> {
|
|
103
103
|
return new Proxy({}, {
|
|
104
|
-
get(_target,
|
|
105
|
-
if (typeof
|
|
106
|
-
return
|
|
104
|
+
get(_target, model) {
|
|
105
|
+
if (typeof model !== 'string') return undefined;
|
|
106
|
+
return runtimeModelResources[model]?.[key] ?? {};
|
|
107
107
|
},
|
|
108
108
|
ownKeys() {
|
|
109
|
-
return Reflect.ownKeys(
|
|
109
|
+
return Reflect.ownKeys(runtimeModelResources);
|
|
110
110
|
},
|
|
111
|
-
getOwnPropertyDescriptor(_target,
|
|
112
|
-
if (typeof
|
|
111
|
+
getOwnPropertyDescriptor(_target, model) {
|
|
112
|
+
if (typeof model !== 'string' || !(model in runtimeModelResources)) return undefined;
|
|
113
113
|
return { enumerable: true, configurable: true };
|
|
114
114
|
},
|
|
115
|
-
}) as
|
|
115
|
+
}) as ModelResourceCategory<TKey>;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
export const
|
|
119
|
-
get(target,
|
|
120
|
-
if (typeof
|
|
121
|
-
return target[
|
|
118
|
+
export const ModelResources: ModelResourceRegistry = new Proxy(runtimeModelResources, {
|
|
119
|
+
get(target, model) {
|
|
120
|
+
if (typeof model !== 'string') return undefined;
|
|
121
|
+
return target[model] ?? createEmptyRuntimeResources();
|
|
122
122
|
},
|
|
123
123
|
ownKeys(target) {
|
|
124
124
|
return Reflect.ownKeys(target);
|
|
125
125
|
},
|
|
126
|
-
getOwnPropertyDescriptor(target,
|
|
127
|
-
if (typeof
|
|
126
|
+
getOwnPropertyDescriptor(target, model) {
|
|
127
|
+
if (typeof model !== 'string' || !(model in target)) return undefined;
|
|
128
128
|
return { enumerable: true, configurable: true };
|
|
129
129
|
},
|
|
130
|
-
}) as
|
|
130
|
+
}) as ModelResourceRegistry;
|
|
131
131
|
|
|
132
|
-
export const
|
|
133
|
-
export const
|
|
134
|
-
export const
|
|
135
|
-
export const
|
|
136
|
-
export const
|
|
137
|
-
export const
|
|
138
|
-
export const
|
|
139
|
-
export const
|
|
132
|
+
export const ModelActuators: ModelResourceCategory<'actuators'> = createResourceCategory('actuators');
|
|
133
|
+
export const ModelSensors: ModelResourceCategory<'sensors'> = createResourceCategory('sensors');
|
|
134
|
+
export const ModelBodies: ModelResourceCategory<'bodies'> = createResourceCategory('bodies');
|
|
135
|
+
export const ModelJoints: ModelResourceCategory<'joints'> = createResourceCategory('joints');
|
|
136
|
+
export const ModelSites: ModelResourceCategory<'sites'> = createResourceCategory('sites');
|
|
137
|
+
export const ModelGeoms: ModelResourceCategory<'geoms'> = createResourceCategory('geoms');
|
|
138
|
+
export const ModelKeyframes: ModelResourceCategory<'keyframes'> = createResourceCategory('keyframes');
|
|
139
|
+
export const ModelCameras: ModelResourceCategory<'cameras'> = createResourceCategory('cameras');
|
|
140
140
|
|
|
141
141
|
export type Actuators = Register extends { actuators: infer T extends string } ? T : string;
|
|
142
142
|
export type Sensors = Register extends { sensors: infer T extends string } ? T : string;
|
|
@@ -1532,7 +1532,30 @@ export interface BodyStateResult {
|
|
|
1532
1532
|
angularVelocity: React.RefObject<THREE.Vector3>;
|
|
1533
1533
|
}
|
|
1534
1534
|
|
|
1535
|
+
export type JointStateKind = 'auto' | 'scalar' | 'array';
|
|
1536
|
+
|
|
1537
|
+
export interface JointStateOptions {
|
|
1538
|
+
/**
|
|
1539
|
+
* Expected joint value shape.
|
|
1540
|
+
*
|
|
1541
|
+
* - `auto`: scalar joints return numbers, ball/free joints return Float64Array.
|
|
1542
|
+
* - `scalar`: return numeric refs for hinge/slide joints.
|
|
1543
|
+
* - `array`: return Float64Array refs for ball/free joints.
|
|
1544
|
+
*/
|
|
1545
|
+
kind?: JointStateKind;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1535
1548
|
export interface JointStateResult {
|
|
1536
1549
|
position: React.RefObject<number | Float64Array>;
|
|
1537
1550
|
velocity: React.RefObject<number | Float64Array>;
|
|
1538
1551
|
}
|
|
1552
|
+
|
|
1553
|
+
export interface ScalarJointStateResult {
|
|
1554
|
+
position: React.RefObject<number>;
|
|
1555
|
+
velocity: React.RefObject<number>;
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
export interface ArrayJointStateResult {
|
|
1559
|
+
position: React.RefObject<Float64Array>;
|
|
1560
|
+
velocity: React.RefObject<Float64Array>;
|
|
1561
|
+
}
|
package/src/vite.ts
CHANGED
|
@@ -221,21 +221,21 @@ function renderRegister(
|
|
|
221
221
|
const fields = REGISTER_KEYS
|
|
222
222
|
.filter((key) => names[key].size > 0)
|
|
223
223
|
.map((key) => ` ${key}: ${renderUnion(names[key])};`);
|
|
224
|
-
const
|
|
225
|
-
.map((model) => ` ${quoteProperty(model.id)}: {\n${
|
|
224
|
+
const modelFields = models
|
|
225
|
+
.map((model) => ` ${quoteProperty(model.id)}: {\n${renderModelFields(model.names)}\n };`);
|
|
226
226
|
const namespaceAliases = renderNamespaceAliases(models);
|
|
227
|
-
const registerImport = declarationsOnly ? '' : `import {
|
|
228
|
-
const resources = declarationsOnly ? '' : `${renderResourceTypes(models)}\n\n${renderResourceConstants(models)}\n\
|
|
227
|
+
const registerImport = declarationsOnly ? '' : `import { registerModelResources } from '${moduleName}';\n`;
|
|
228
|
+
const resources = declarationsOnly ? '' : `${renderResourceTypes(models)}\n\n${renderResourceConstants(models)}\n\nregisterModelResources(generatedModelResources);\n\n`;
|
|
229
229
|
|
|
230
230
|
return `// Auto-generated by mujoco-react. Do not edit.
|
|
231
231
|
// Regenerate by running Vite with the mujocoReact() plugin or \`mujoco-react codegen\`.
|
|
232
232
|
|
|
233
|
-
${registerImport}import type {
|
|
233
|
+
${registerImport}import type { ModelResource } from '${moduleName}';
|
|
234
234
|
|
|
235
235
|
${resources}declare module '${moduleName}' {
|
|
236
236
|
interface Register {
|
|
237
|
-
|
|
238
|
-
${
|
|
237
|
+
models: {
|
|
238
|
+
${modelFields.join('\n')}
|
|
239
239
|
};
|
|
240
240
|
${fields.join('\n')}
|
|
241
241
|
}
|
|
@@ -249,7 +249,7 @@ function renderResourceTypes(models: readonly ModelEntry[]): string {
|
|
|
249
249
|
const modelTypes = models
|
|
250
250
|
.map((model) => ` readonly ${quoteProperty(model.id)}: {\n${renderResourceTypeFields(model.names)}\n };`)
|
|
251
251
|
.join('\n');
|
|
252
|
-
return `type
|
|
252
|
+
return `type GeneratedModelResources = {\n${modelTypes}\n};`;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
function renderResourceTypeFields(names: Record<RegisterKey, Set<string>>): string {
|
|
@@ -268,7 +268,7 @@ function renderResourceConstants(models: readonly ModelEntry[]): string {
|
|
|
268
268
|
const entries = models
|
|
269
269
|
.map((model) => ` ${quoteProperty(model.id)}: {\n${renderResourceConstantFields(model.names)}\n },`)
|
|
270
270
|
.join('\n');
|
|
271
|
-
return `const
|
|
271
|
+
return `const generatedModelResources: GeneratedModelResources = {\n${entries}\n};`;
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
function renderResourceConstantFields(names: Record<RegisterKey, Set<string>>): string {
|
|
@@ -283,7 +283,7 @@ function renderResourceObject(values: Set<string>): string {
|
|
|
283
283
|
return entries.length > 0 ? `{\n${entries.join('\n')}\n }` : '{}';
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
function
|
|
286
|
+
function renderModelFields(names: Record<RegisterKey, Set<string>>): string {
|
|
287
287
|
return REGISTER_KEYS
|
|
288
288
|
.map((key) => ` ${key}: ${names[key].size > 0 ? renderUnion(names[key]) : 'never'};`)
|
|
289
289
|
.join('\n');
|
|
@@ -295,23 +295,23 @@ function renderUnion(values: Set<string>): string {
|
|
|
295
295
|
|
|
296
296
|
function renderNamespaceAliases(models: readonly ModelEntry[]): string {
|
|
297
297
|
const namespaces: Record<RegisterKey, string> = {
|
|
298
|
-
actuators: '
|
|
299
|
-
sensors: '
|
|
300
|
-
bodies: '
|
|
301
|
-
joints: '
|
|
302
|
-
sites: '
|
|
303
|
-
geoms: '
|
|
304
|
-
keyframes: '
|
|
305
|
-
cameras: '
|
|
298
|
+
actuators: 'ModelActuators',
|
|
299
|
+
sensors: 'ModelSensors',
|
|
300
|
+
bodies: 'ModelBodies',
|
|
301
|
+
joints: 'ModelJoints',
|
|
302
|
+
sites: 'ModelSites',
|
|
303
|
+
geoms: 'ModelGeoms',
|
|
304
|
+
keyframes: 'ModelKeyframes',
|
|
305
|
+
cameras: 'ModelCameras',
|
|
306
306
|
};
|
|
307
307
|
|
|
308
308
|
const blocks = REGISTER_KEYS
|
|
309
309
|
.map((key) => {
|
|
310
|
-
const
|
|
310
|
+
const modelAliases = models
|
|
311
311
|
.filter((model) => isIdentifier(model.id))
|
|
312
|
-
.map((model) => ` export type ${model.id} =
|
|
313
|
-
if (
|
|
314
|
-
return ` export namespace ${namespaces[key]} {\n${
|
|
312
|
+
.map((model) => ` export type ${model.id} = ModelResource<'${escapeTs(model.id)}', '${key}'>;`);
|
|
313
|
+
if (modelAliases.length === 0) return '';
|
|
314
|
+
return ` export namespace ${namespaces[key]} {\n${modelAliases.join('\n')}\n }`;
|
|
315
315
|
})
|
|
316
316
|
.filter(Boolean)
|
|
317
317
|
.join('\n\n');
|