mujoco-react 12.2.1 → 12.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 +24 -0
- package/dist/{chunk-OIMH4U5U.js → chunk-FVSVETBC.js} +8 -3
- package/dist/{chunk-OIMH4U5U.js.map → chunk-FVSVETBC.js.map} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +467 -214
- package/dist/index.js.map +1 -1
- package/dist/onnx.d.ts +1 -1
- package/dist/spark.d.ts +1 -1
- package/dist/spark.js +1 -1
- package/dist/{types-CF-BZXtW.d.ts → types-1ONW9gUW.d.ts} +10 -1
- package/package.json +2 -2
- package/src/components/SceneRenderer.tsx +38 -16
- package/src/index.ts +1 -0
- package/src/rendering/GeomBuilder.ts +34 -14
- package/src/rendering/cameraFrameCapture.ts +9 -3
- package/src/rendering/mujocoClassicMaterial.ts +203 -0
- package/src/types.ts +7 -0
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { displayFields } from './chunk-U2Y2BODT.js';
|
|
2
|
-
import { withContacts, getContact, captureCameraFrame, captureCameraFrameBlob, captureCameraRGBD, createCameraFrameCaptureSession, CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, createCaptureCamera, prepareCaptureCamera } from './chunk-
|
|
3
|
-
export { CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, ModelActuators, ModelBodies, ModelCameras, ModelGeoms, ModelJoints, ModelKeyframes, ModelResources, ModelSensors, ModelSites, ScenarioLighting, SplatEnvironment, SplatEnvironmentReadinessStatus, VisualScenarioEffects, captureCameraFrame, captureCameraFrameBlob, captureCameraFrameTensor, captureCameraRGBD, createCameraFrameCaptureSession, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, createSplatSceneConfig, createVisualScenarioExecutionContext, dataUrlToPolicyImageTensor, getContact, getScenarioBackground, getScenarioCameraPosition, getSplatEnvironmentReadiness, imageDataToPolicyImageTensor, pixelsToPolicyImageTensor, registerModelResources, renderCameraFrameToCanvas, useSplatEnvironment, useSplatSceneConfig, useVisualScenarioEffects, useVisualScenarioExecutionContext, withSplatEnvironment } from './chunk-
|
|
2
|
+
import { withContacts, getContact, captureCameraFrame, captureCameraFrameBlob, captureCameraRGBD, createCameraFrameCaptureSession, CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, createCaptureCamera, prepareCaptureCamera } from './chunk-FVSVETBC.js';
|
|
3
|
+
export { CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, ModelActuators, ModelBodies, ModelCameras, ModelGeoms, ModelJoints, ModelKeyframes, ModelResources, ModelSensors, ModelSites, ScenarioLighting, SplatEnvironment, SplatEnvironmentReadinessStatus, VisualScenarioEffects, captureCameraFrame, captureCameraFrameBlob, captureCameraFrameTensor, captureCameraRGBD, createCameraFrameCaptureSession, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, createSplatSceneConfig, createVisualScenarioExecutionContext, dataUrlToPolicyImageTensor, getContact, getScenarioBackground, getScenarioCameraPosition, getSplatEnvironmentReadiness, imageDataToPolicyImageTensor, pixelsToPolicyImageTensor, registerModelResources, renderCameraFrameToCanvas, useSplatEnvironment, useSplatSceneConfig, useVisualScenarioEffects, useVisualScenarioExecutionContext, withSplatEnvironment } from './chunk-FVSVETBC.js';
|
|
4
4
|
import loadMujoco from '@mujoco/mujoco';
|
|
5
5
|
import defaultMujocoWasmUrl from '@mujoco/mujoco/mujoco.wasm?url';
|
|
6
6
|
import { createContext, forwardRef, useRef, useEffect, useContext, useState, useCallback, useMemo, useLayoutEffect, useId } from 'react';
|
|
7
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
import { Canvas, useThree, useFrame } from '@react-three/fiber';
|
|
9
|
-
import * as
|
|
9
|
+
import * as THREE13 from 'three';
|
|
10
10
|
import { mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
|
11
11
|
import { PivotControls } from '@react-three/drei';
|
|
12
12
|
|
|
@@ -1766,16 +1766,227 @@ async function attachSimulationRuntime(module, api, waitForDisplay, invalidate,
|
|
|
1766
1766
|
throw error;
|
|
1767
1767
|
}
|
|
1768
1768
|
}
|
|
1769
|
-
var
|
|
1769
|
+
var MAX_LIGHTS = 8;
|
|
1770
|
+
var vertexShader = `
|
|
1771
|
+
uniform vec4 diffuse;
|
|
1772
|
+
uniform float emission, specular, shininess;
|
|
1773
|
+
uniform int lightCount;
|
|
1774
|
+
uniform float lightMode[8];
|
|
1775
|
+
uniform vec3 lightPos[8], lightDir[8], lightAmbient[8], lightDiffuse[8], lightSpecular[8], lightAttenuation[8];
|
|
1776
|
+
uniform float lightCutoff[8], lightExponent[8];
|
|
1777
|
+
uniform bool explicitUV;
|
|
1778
|
+
uniform vec2 repeatScale;
|
|
1779
|
+
uniform vec3 cubeScale;
|
|
1780
|
+
varying vec3 cubeCoord;
|
|
1781
|
+
varying vec4 litColor;
|
|
1782
|
+
varying vec2 texCoord;
|
|
1783
|
+
void main() {
|
|
1784
|
+
vec4 p = modelViewMatrix * vec4(position, 1.0);
|
|
1785
|
+
vec3 n = normalize(normalMatrix * normal);
|
|
1786
|
+
vec3 v = normalize(-p.xyz);
|
|
1787
|
+
vec3 rgb = diffuse.rgb * emission;
|
|
1788
|
+
if (lightCount == 0) rgb += diffuse.rgb * 0.3;
|
|
1789
|
+
for (int i=0; i<8; i++) {
|
|
1790
|
+
if (i>=lightCount) break;
|
|
1791
|
+
vec3 l;
|
|
1792
|
+
float attenuation = 1.0;
|
|
1793
|
+
if (lightMode[i] > 1.5) l = vec3(0.0, 0.0, 1.0);
|
|
1794
|
+
else if (lightMode[i] > 0.5) l = normalize(-(viewMatrix * vec4(lightDir[i],0.0)).xyz);
|
|
1795
|
+
else {
|
|
1796
|
+
vec3 delta = (viewMatrix * vec4(lightPos[i],1.0)).xyz - p.xyz;
|
|
1797
|
+
float distance = length(delta);
|
|
1798
|
+
l = normalize(delta);
|
|
1799
|
+
vec3 a = lightAttenuation[i];
|
|
1800
|
+
attenuation = 1.0 / max(1e-8, a.x+a.y*distance+a.z*distance*distance);
|
|
1801
|
+
vec3 direction = normalize((viewMatrix * vec4(lightDir[i],0.0)).xyz);
|
|
1802
|
+
float spot = dot(-l,direction);
|
|
1803
|
+
if(lightCutoff[i] >= -1.0) attenuation *= spot >= lightCutoff[i] ? (lightExponent[i] > 0.0 ? pow(max(0.0,spot),lightExponent[i]) : 1.0) : 0.0;
|
|
1804
|
+
}
|
|
1805
|
+
float lambert = max(0.0,dot(n,l));
|
|
1806
|
+
vec3 h = normalize(l+v);
|
|
1807
|
+
float shine = lambert > 0.0 && specular > 0.0 ? (shininess > 0.0 ? pow(max(0.0,dot(n,h)),shininess) : 1.0) : 0.0;
|
|
1808
|
+
rgb += attenuation*(diffuse.rgb*(lightAmbient[i]+lambert*lightDiffuse[i])+specular*shine*lightSpecular[i]);
|
|
1809
|
+
}
|
|
1810
|
+
litColor = vec4(clamp(rgb,0.0,1.0),diffuse.a);
|
|
1811
|
+
cubeCoord = position*cubeScale;
|
|
1812
|
+
texCoord = explicitUV ? vec2(uv.x,1.0-uv.y) : vec2(.5*repeatScale.x*position.x-.5,-.5*repeatScale.y*position.y-.5);
|
|
1813
|
+
gl_Position = projectionMatrix*p;
|
|
1814
|
+
}`;
|
|
1815
|
+
var fragmentShader = `
|
|
1816
|
+
uniform bool useMap;
|
|
1817
|
+
uniform sampler2D colorMap;
|
|
1818
|
+
uniform bool useCube;
|
|
1819
|
+
uniform samplerCube cubeMap;
|
|
1820
|
+
varying vec3 cubeCoord;
|
|
1821
|
+
varying vec4 litColor;
|
|
1822
|
+
varying vec2 texCoord;
|
|
1823
|
+
void main() {
|
|
1824
|
+
gl_FragColor = litColor * (useMap ? texture2D(colorMap,texCoord) : (useCube ? textureCube(cubeMap,cubeCoord) : vec4(1.0)));
|
|
1825
|
+
}`;
|
|
1826
|
+
var textureCache = /* @__PURE__ */ new WeakMap();
|
|
1827
|
+
function acquireTexture(model, id) {
|
|
1828
|
+
const m = model;
|
|
1829
|
+
let cache = textureCache.get(model);
|
|
1830
|
+
if (!cache) {
|
|
1831
|
+
cache = /* @__PURE__ */ new Map();
|
|
1832
|
+
textureCache.set(model, cache);
|
|
1833
|
+
}
|
|
1834
|
+
let entry = cache.get(id);
|
|
1835
|
+
if (!entry) {
|
|
1836
|
+
const width = model.tex_width[id], height = model.tex_height[id], channels = model.tex_nchannel[id];
|
|
1837
|
+
if (channels !== 3 && channels !== 4) throw new Error("Classic RGB textures require three or four channels");
|
|
1838
|
+
const bytes = model.tex_data.subarray(model.tex_adr[id], model.tex_adr[id] + width * height * channels);
|
|
1839
|
+
const rgba = new Uint8Array(width * height * 4);
|
|
1840
|
+
for (let i = 0; i < width * height; i++) {
|
|
1841
|
+
rgba.set(bytes.subarray(i * channels, i * channels + 3), i * 4);
|
|
1842
|
+
rgba[i * 4 + 3] = channels === 4 ? bytes[i * channels + 3] : 255;
|
|
1843
|
+
}
|
|
1844
|
+
let texture;
|
|
1845
|
+
if (m.tex_type[id] === 0) {
|
|
1846
|
+
texture = new THREE13.DataTexture(rgba, width, height, THREE13.RGBAFormat);
|
|
1847
|
+
texture.colorSpace = m.tex_colorspace[id] === 2 ? THREE13.SRGBColorSpace : THREE13.LinearSRGBColorSpace;
|
|
1848
|
+
texture.wrapS = texture.wrapT = THREE13.RepeatWrapping;
|
|
1849
|
+
texture.magFilter = THREE13.LinearFilter;
|
|
1850
|
+
texture.minFilter = THREE13.LinearMipmapLinearFilter;
|
|
1851
|
+
texture.generateMipmaps = true;
|
|
1852
|
+
} else if (m.tex_type[id] === 1) {
|
|
1853
|
+
if (height !== 6 * width) throw new Error("Classic cube texture must contain six square faces");
|
|
1854
|
+
const faces = Array.from({ length: 6 }, (_, i) => new THREE13.DataTexture(rgba.subarray(i * width * width * 4, (i + 1) * width * width * 4), width, width, THREE13.RGBAFormat));
|
|
1855
|
+
texture = new THREE13.CubeTexture(faces);
|
|
1856
|
+
texture.colorSpace = THREE13.LinearSRGBColorSpace;
|
|
1857
|
+
} else throw new Error("Classic materials require a 2D or cube RGB texture");
|
|
1858
|
+
texture.flipY = false;
|
|
1859
|
+
texture.needsUpdate = true;
|
|
1860
|
+
entry = { texture, references: 0 };
|
|
1861
|
+
cache.set(id, entry);
|
|
1862
|
+
}
|
|
1863
|
+
entry.references++;
|
|
1864
|
+
const retained = entry;
|
|
1865
|
+
return { texture: entry.texture, release() {
|
|
1866
|
+
if (--retained.references === 0) {
|
|
1867
|
+
retained.texture.dispose();
|
|
1868
|
+
cache.delete(id);
|
|
1869
|
+
}
|
|
1870
|
+
} };
|
|
1871
|
+
}
|
|
1872
|
+
function createClassicPlaneGeometry(model, geom) {
|
|
1873
|
+
const size = model.geom_size.subarray(geom * 3, geom * 3 + 3);
|
|
1874
|
+
if (size[0] <= 0 || size[1] <= 0) throw new Error("Classic appearance currently requires finite plane extents");
|
|
1875
|
+
const axis = (half) => {
|
|
1876
|
+
const step = Math.max(size[2], half / 98);
|
|
1877
|
+
let count = Math.floor(half / step);
|
|
1878
|
+
count -= count % 2;
|
|
1879
|
+
const pad = half - count * step;
|
|
1880
|
+
count += 2;
|
|
1881
|
+
const grid = [];
|
|
1882
|
+
for (let i = 0; i < count; i++) {
|
|
1883
|
+
const left = i === 0 ? -half : -half + pad + (i - 1) * 2 * step;
|
|
1884
|
+
const right = left + (i === 0 || i === count - 1 ? pad : 2 * step);
|
|
1885
|
+
grid[i] = left;
|
|
1886
|
+
grid[i + 1] = Math.max(left, right);
|
|
1887
|
+
}
|
|
1888
|
+
return grid;
|
|
1889
|
+
};
|
|
1890
|
+
const x = axis(size[0]), y = axis(size[1]), positions = [], normals = [], indices = [];
|
|
1891
|
+
for (const py of y) for (const px of x) {
|
|
1892
|
+
positions.push(px, py, 0);
|
|
1893
|
+
normals.push(0, 0, 1);
|
|
1894
|
+
}
|
|
1895
|
+
for (let row = 0; row < y.length - 1; row++) for (let col = 0; col < x.length - 1; col++) {
|
|
1896
|
+
const a = row * x.length + col, b = a + 1, c = a + x.length, d = c + 1;
|
|
1897
|
+
indices.push(a, b, d, a, d, c);
|
|
1898
|
+
}
|
|
1899
|
+
const geometry = new THREE13.BufferGeometry();
|
|
1900
|
+
geometry.setAttribute("position", new THREE13.Float32BufferAttribute(positions, 3));
|
|
1901
|
+
geometry.setAttribute("normal", new THREE13.Float32BufferAttribute(normals, 3));
|
|
1902
|
+
geometry.setIndex(indices);
|
|
1903
|
+
return geometry;
|
|
1904
|
+
}
|
|
1905
|
+
function createMujocoClassicMaterial(model, data, geom) {
|
|
1906
|
+
const m = model, d = data;
|
|
1907
|
+
for (const name of ["tex_type", "tex_colorspace", "mat_emission", "mat_specular", "mat_shininess", "light_ambient"]) {
|
|
1908
|
+
if (!m[name] || typeof m[name].length !== "number") throw new Error(`Classic appearance requires model.${name}`);
|
|
1909
|
+
}
|
|
1910
|
+
if (!m.vis?.headlight || !d.light_xpos || !d.light_xdir) throw new Error("Classic appearance requires MuJoCo visual/light state");
|
|
1911
|
+
const mat = model.geom_matid[geom], rgba = Array.from(model.geom_rgba.slice(4 * geom, 4 * geom + 4));
|
|
1912
|
+
if (mat >= 0 && rgba.every((v, i) => v === [0.5, 0.5, 0.5, 1][i])) rgba.splice(0, 4, ...model.mat_rgba.slice(4 * mat, 4 * mat + 4));
|
|
1913
|
+
const roles = model.mat_texid.length / Math.max(1, model.mat_rgba.length / 4);
|
|
1914
|
+
const textureId = mat >= 0 ? model.mat_texid[mat * roles + 1] : -1;
|
|
1915
|
+
const retained = textureId >= 0 ? acquireTexture(model, textureId) : void 0;
|
|
1916
|
+
const texture = retained?.texture ?? null;
|
|
1917
|
+
const vectors = () => Array.from({ length: MAX_LIGHTS }, () => new THREE13.Vector3());
|
|
1918
|
+
const uniforms = {
|
|
1919
|
+
diffuse: { value: new THREE13.Vector4(...rgba) },
|
|
1920
|
+
emission: { value: mat >= 0 ? m.mat_emission[mat] : 0 },
|
|
1921
|
+
specular: { value: mat >= 0 ? m.mat_specular[mat] : 0.5 },
|
|
1922
|
+
shininess: { value: 128 * (mat >= 0 ? m.mat_shininess[mat] : 0.5) },
|
|
1923
|
+
lightCount: { value: 0 },
|
|
1924
|
+
lightMode: { value: new Float32Array(MAX_LIGHTS) },
|
|
1925
|
+
lightPos: { value: vectors() },
|
|
1926
|
+
lightDir: { value: vectors() },
|
|
1927
|
+
lightAmbient: { value: vectors() },
|
|
1928
|
+
lightDiffuse: { value: vectors() },
|
|
1929
|
+
lightSpecular: { value: vectors() },
|
|
1930
|
+
lightAttenuation: { value: vectors() },
|
|
1931
|
+
lightCutoff: { value: new Float32Array(MAX_LIGHTS) },
|
|
1932
|
+
lightExponent: { value: new Float32Array(MAX_LIGHTS) },
|
|
1933
|
+
explicitUV: { value: Number(model.geom_type[geom]) === 7 && (model.mesh_texcoordadr?.[model.geom_dataid[geom]] ?? -1) >= 0 },
|
|
1934
|
+
repeatScale: { value: new THREE13.Vector2(mat >= 0 ? model.mat_texrepeat[mat * 2] : 1, mat >= 0 ? model.mat_texrepeat[mat * 2 + 1] : 1) },
|
|
1935
|
+
useMap: { value: !!texture && m.tex_type[textureId] === 0 },
|
|
1936
|
+
colorMap: { value: texture && m.tex_type[textureId] === 0 ? texture : null },
|
|
1937
|
+
useCube: { value: !!texture && m.tex_type[textureId] === 1 },
|
|
1938
|
+
cubeMap: { value: texture && m.tex_type[textureId] === 1 ? texture : null },
|
|
1939
|
+
cubeScale: { value: new THREE13.Vector3(1, 1, 1) }
|
|
1940
|
+
};
|
|
1941
|
+
if (mat >= 0 && !model.mat_texuniform[mat]) {
|
|
1942
|
+
const size = model.geom_size;
|
|
1943
|
+
uniforms.repeatScale.value.x /= size[geom * 3] || 1;
|
|
1944
|
+
uniforms.repeatScale.value.y /= size[geom * 3 + 1] || 1;
|
|
1945
|
+
}
|
|
1946
|
+
const isMeshOrPlane = Number(model.geom_type[geom]) === 7 || Number(model.geom_type[geom]) === 0;
|
|
1947
|
+
const uniform = mat >= 0 && model.mat_texuniform[mat];
|
|
1948
|
+
for (let i = 0; i < 3; i++) uniforms.cubeScale.value.setComponent(i, isMeshOrPlane ? uniform ? model.geom_size[geom * 3 + i] : 1 : uniform ? 1 : 1 / (model.geom_size[geom * 3 + i] || 1));
|
|
1949
|
+
const material = new THREE13.ShaderMaterial({ uniforms, vertexShader, fragmentShader, toneMapped: false, side: THREE13.DoubleSide, transparent: rgba[3] < 1, depthWrite: rgba[3] >= 1 });
|
|
1950
|
+
const head = m.vis.headlight;
|
|
1951
|
+
material.onBeforeRender = () => {
|
|
1952
|
+
let count = 0;
|
|
1953
|
+
const add = (mode, pos, dir, ambient, diffuse, specular, attenuation, cutoff, exponent) => {
|
|
1954
|
+
if (count >= MAX_LIGHTS) throw new Error("Classic appearance supports at most eight lights");
|
|
1955
|
+
uniforms.lightMode.value[count] = mode;
|
|
1956
|
+
for (const [uniform2, value] of [[uniforms.lightPos, pos], [uniforms.lightDir, dir], [uniforms.lightAmbient, ambient], [uniforms.lightDiffuse, diffuse], [uniforms.lightSpecular, specular], [uniforms.lightAttenuation, attenuation]]) uniform2.value[count].fromArray(value);
|
|
1957
|
+
uniforms.lightCutoff.value[count] = cutoff >= 180 ? -2 : Math.cos(cutoff * Math.PI / 180);
|
|
1958
|
+
uniforms.lightExponent.value[count] = exponent;
|
|
1959
|
+
count++;
|
|
1960
|
+
};
|
|
1961
|
+
if (head.active) add(2, [0, 0, 0], [0, 0, -1], head.ambient, head.diffuse, head.specular, [1, 0, 0], 180, 0);
|
|
1962
|
+
for (let i = 0; i < model.nlight; i++) if (m.light_active[i]) {
|
|
1963
|
+
const type = m.light_type[i];
|
|
1964
|
+
if (type !== 0 && type !== 1) throw new Error("Classic appearance requires spot or directional MJCF lights");
|
|
1965
|
+
const slice = (a) => [a[i * 3], a[i * 3 + 1], a[i * 3 + 2]];
|
|
1966
|
+
add(type, slice(d.light_xpos), slice(d.light_xdir), slice(m.light_ambient), slice(m.light_diffuse), slice(m.light_specular), slice(m.light_attenuation), m.light_cutoff[i], m.light_exponent[i]);
|
|
1967
|
+
}
|
|
1968
|
+
uniforms.lightCount.value = count;
|
|
1969
|
+
material.uniformsNeedUpdate = true;
|
|
1970
|
+
};
|
|
1971
|
+
let released = false;
|
|
1972
|
+
material.addEventListener("dispose", () => {
|
|
1973
|
+
if (!released) {
|
|
1974
|
+
retained?.release();
|
|
1975
|
+
released = true;
|
|
1976
|
+
}
|
|
1977
|
+
});
|
|
1978
|
+
return material;
|
|
1979
|
+
}
|
|
1980
|
+
var CapsuleGeometry = class extends THREE13.BufferGeometry {
|
|
1770
1981
|
parameters;
|
|
1771
1982
|
constructor(radius = 1, length = 1, capSegments = 4, radialSegments = 8) {
|
|
1772
1983
|
super();
|
|
1773
1984
|
this.type = "CapsuleGeometry";
|
|
1774
1985
|
this.parameters = { radius, length, capSegments, radialSegments };
|
|
1775
|
-
const path = new
|
|
1986
|
+
const path = new THREE13.Path();
|
|
1776
1987
|
path.absarc(0, -length / 2, radius, Math.PI * 1.5, 0, false);
|
|
1777
1988
|
path.absarc(0, length / 2, radius, 0, Math.PI * 0.5, false);
|
|
1778
|
-
const latheGeometry = new
|
|
1989
|
+
const latheGeometry = new THREE13.LatheGeometry(path.getPoints(capSegments), radialSegments);
|
|
1779
1990
|
const self = this;
|
|
1780
1991
|
self.setIndex(latheGeometry.getIndex());
|
|
1781
1992
|
self.setAttribute("position", latheGeometry.getAttribute("position"));
|
|
@@ -1833,10 +2044,10 @@ var GeomBuilder = class {
|
|
|
1833
2044
|
rgba[out + 2] = b;
|
|
1834
2045
|
rgba[out + 3] = a;
|
|
1835
2046
|
}
|
|
1836
|
-
const texture = new
|
|
1837
|
-
texture.colorSpace =
|
|
1838
|
-
texture.wrapS =
|
|
1839
|
-
texture.wrapT =
|
|
2047
|
+
const texture = new THREE13.DataTexture(rgba, width, height, THREE13.RGBAFormat);
|
|
2048
|
+
texture.colorSpace = THREE13.LinearSRGBColorSpace;
|
|
2049
|
+
texture.wrapS = THREE13.RepeatWrapping;
|
|
2050
|
+
texture.wrapT = THREE13.RepeatWrapping;
|
|
1840
2051
|
texture.flipY = true;
|
|
1841
2052
|
const repeatOffset = matId * 2;
|
|
1842
2053
|
const repeatS = mjModel.mat_texrepeat?.[repeatOffset] ?? 1;
|
|
@@ -1850,15 +2061,22 @@ var GeomBuilder = class {
|
|
|
1850
2061
|
* Creates a Three.js Object3D (usually a Mesh) for a specific geometry in the MuJoCo model.
|
|
1851
2062
|
* Returns null if the geometry shouldn't be rendered (e.g., invisible collision triggers).
|
|
1852
2063
|
*/
|
|
1853
|
-
|
|
2064
|
+
dispose() {
|
|
2065
|
+
for (const texture of this.textureCache.values()) texture.dispose();
|
|
2066
|
+
this.textureCache.clear();
|
|
2067
|
+
}
|
|
2068
|
+
create(mjModel, g, data) {
|
|
2069
|
+
const classic = this.renderOptions?.appearance === "mujoco-classic";
|
|
2070
|
+
if (classic && !data) throw new Error("Classic appearance requires live MuJoCo data");
|
|
2071
|
+
if (classic && this.renderOptions?.meshNormalSmoothing) throw new Error("Classic appearance uses MuJoCo mesh normals; meshNormalSmoothing is not supported");
|
|
1854
2072
|
if (mjModel.geom_group[g] === 3) return null;
|
|
1855
2073
|
const type = mjModel.geom_type[g];
|
|
1856
2074
|
const size = mjModel.geom_size.subarray(g * 3, g * 3 + 3);
|
|
1857
2075
|
const pos = mjModel.geom_pos.subarray(g * 3, g * 3 + 3);
|
|
1858
2076
|
const quat = mjModel.geom_quat.subarray(g * 4, g * 4 + 4);
|
|
1859
2077
|
const matId = mjModel.geom_matid[g];
|
|
1860
|
-
const color = new
|
|
1861
|
-
const map = this.getMaterialTexture(mjModel, matId);
|
|
2078
|
+
const color = new THREE13.Color(16777215);
|
|
2079
|
+
const map = classic ? null : this.getMaterialTexture(mjModel, matId);
|
|
1862
2080
|
let opacity = 1;
|
|
1863
2081
|
if (matId >= 0) {
|
|
1864
2082
|
const rgba = mjModel.mat_rgba.subarray(matId * 4, matId * 4 + 4);
|
|
@@ -1873,16 +2091,16 @@ var GeomBuilder = class {
|
|
|
1873
2091
|
let geo = null;
|
|
1874
2092
|
const getVal = (v) => v?.value ?? v;
|
|
1875
2093
|
if (type === getVal(MG.mjGEOM_PLANE)) {
|
|
1876
|
-
geo = new
|
|
2094
|
+
geo = classic ? createClassicPlaneGeometry(mjModel, g) : new THREE13.PlaneGeometry(size[0] * 2 || 5, size[1] * 2 || 5);
|
|
1877
2095
|
} else if (type === getVal(MG.mjGEOM_SPHERE)) {
|
|
1878
|
-
geo = new
|
|
2096
|
+
geo = new THREE13.SphereGeometry(size[0], 24, 24);
|
|
1879
2097
|
} else if (type === getVal(MG.mjGEOM_CAPSULE)) {
|
|
1880
2098
|
geo = new CapsuleGeometry(size[0], size[1] * 2, 24, 12);
|
|
1881
2099
|
geo.rotateX(Math.PI / 2);
|
|
1882
2100
|
} else if (type === getVal(MG.mjGEOM_BOX)) {
|
|
1883
|
-
geo = new
|
|
2101
|
+
geo = new THREE13.BoxGeometry(size[0] * 2, size[1] * 2, size[2] * 2);
|
|
1884
2102
|
} else if (type === getVal(MG.mjGEOM_CYLINDER)) {
|
|
1885
|
-
geo = new
|
|
2103
|
+
geo = new THREE13.CylinderGeometry(size[0], size[0], size[1] * 2, 24);
|
|
1886
2104
|
geo.rotateX(Math.PI / 2);
|
|
1887
2105
|
} else if (type === getVal(MG.mjGEOM_MESH)) {
|
|
1888
2106
|
const mId = mjModel.geom_dataid[g];
|
|
@@ -1891,26 +2109,37 @@ var GeomBuilder = class {
|
|
|
1891
2109
|
const fAdr = mjModel.mesh_faceadr[mId];
|
|
1892
2110
|
const fNum = mjModel.mesh_facenum[mId];
|
|
1893
2111
|
const tAdr = mjModel.mesh_texcoordadr?.[mId] ?? -1;
|
|
1894
|
-
if (map && tAdr >= 0 && mjModel.mesh_texcoord && mjModel.mesh_facetexcoord) {
|
|
2112
|
+
if (classic || map && tAdr >= 0 && mjModel.mesh_texcoord && mjModel.mesh_facetexcoord) {
|
|
1895
2113
|
const corners = fNum * 3;
|
|
1896
2114
|
const positions = new Float32Array(corners * 3);
|
|
1897
|
-
const
|
|
2115
|
+
const hasUV = tAdr >= 0 && mjModel.mesh_texcoord && mjModel.mesh_facetexcoord;
|
|
2116
|
+
const uvs = hasUV ? new Float32Array(corners * 2) : void 0;
|
|
2117
|
+
const normalModel = mjModel;
|
|
2118
|
+
const normals = classic ? new Float32Array(corners * 3) : void 0;
|
|
2119
|
+
if (classic && (!normalModel.mesh_normaladr || !normalModel.mesh_facenormal)) throw new Error("Classic appearance requires MuJoCo mesh face normals");
|
|
1898
2120
|
for (let c = 0; c < corners; c++) {
|
|
1899
2121
|
const v = vAdr + mjModel.mesh_face[fAdr * 3 + c];
|
|
1900
2122
|
positions[c * 3] = mjModel.mesh_vert[v * 3];
|
|
1901
2123
|
positions[c * 3 + 1] = mjModel.mesh_vert[v * 3 + 1];
|
|
1902
2124
|
positions[c * 3 + 2] = mjModel.mesh_vert[v * 3 + 2];
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
2125
|
+
if (uvs) {
|
|
2126
|
+
const t = tAdr + mjModel.mesh_facetexcoord[fAdr * 3 + c];
|
|
2127
|
+
uvs[c * 2] = mjModel.mesh_texcoord[t * 2];
|
|
2128
|
+
uvs[c * 2 + 1] = 1 - mjModel.mesh_texcoord[t * 2 + 1];
|
|
2129
|
+
}
|
|
2130
|
+
if (normals) {
|
|
2131
|
+
const n = normalModel.mesh_normaladr[mId] + normalModel.mesh_facenormal[fAdr * 3 + c];
|
|
2132
|
+
normals.set(mjModel.mesh_normal.subarray(n * 3, n * 3 + 3), c * 3);
|
|
2133
|
+
}
|
|
1906
2134
|
}
|
|
1907
|
-
geo = new
|
|
1908
|
-
geo.setAttribute("position", new
|
|
1909
|
-
geo.setAttribute("uv", new
|
|
1910
|
-
geo.
|
|
2135
|
+
geo = new THREE13.BufferGeometry();
|
|
2136
|
+
geo.setAttribute("position", new THREE13.Float32BufferAttribute(positions, 3));
|
|
2137
|
+
if (uvs) geo.setAttribute("uv", new THREE13.Float32BufferAttribute(uvs, 2));
|
|
2138
|
+
if (normals) geo.setAttribute("normal", new THREE13.Float32BufferAttribute(normals, 3));
|
|
2139
|
+
else geo.computeVertexNormals();
|
|
1911
2140
|
} else {
|
|
1912
|
-
geo = new
|
|
1913
|
-
geo.setAttribute("position", new
|
|
2141
|
+
geo = new THREE13.BufferGeometry();
|
|
2142
|
+
geo.setAttribute("position", new THREE13.Float32BufferAttribute(mjModel.mesh_vert.subarray(vAdr * 3, (vAdr + vNum) * 3), 3));
|
|
1914
2143
|
geo.setIndex(Array.from(mjModel.mesh_face.subarray(fAdr * 3, (fAdr + fNum) * 3)));
|
|
1915
2144
|
const smoothingTolerance = this.getMeshNormalSmoothingTolerance();
|
|
1916
2145
|
if (smoothingTolerance !== null) {
|
|
@@ -1921,12 +2150,12 @@ var GeomBuilder = class {
|
|
|
1921
2150
|
}
|
|
1922
2151
|
if (geo) {
|
|
1923
2152
|
const isPlane = type === getVal(MG.mjGEOM_PLANE);
|
|
1924
|
-
const materialMap = isPlane && map ? map.clone() : map;
|
|
2153
|
+
const materialMap = !classic && isPlane && map ? map.clone() : map;
|
|
1925
2154
|
if (isPlane && materialMap) {
|
|
1926
2155
|
materialMap.repeat.multiplyScalar(2.5);
|
|
1927
2156
|
materialMap.needsUpdate = true;
|
|
1928
2157
|
}
|
|
1929
|
-
const mesh = new
|
|
2158
|
+
const mesh = new THREE13.Mesh(geo, classic ? createMujocoClassicMaterial(mjModel, data, g) : new THREE13.MeshStandardMaterial({
|
|
1930
2159
|
color,
|
|
1931
2160
|
map: materialMap,
|
|
1932
2161
|
transparent: opacity < 1,
|
|
@@ -1934,6 +2163,7 @@ var GeomBuilder = class {
|
|
|
1934
2163
|
roughness: 0.6,
|
|
1935
2164
|
metalness: 0
|
|
1936
2165
|
}));
|
|
2166
|
+
if (materialMap && materialMap !== map) mesh.material.addEventListener("dispose", () => materialMap.dispose());
|
|
1937
2167
|
mesh.castShadow = type !== getVal(MG.mjGEOM_PLANE);
|
|
1938
2168
|
mesh.receiveShadow = true;
|
|
1939
2169
|
mesh.position.set(pos[0], pos[1], pos[2]);
|
|
@@ -1949,9 +2179,9 @@ var GeomBuilder = class {
|
|
|
1949
2179
|
};
|
|
1950
2180
|
function getRenderOptionsKey(renderOptions) {
|
|
1951
2181
|
const smoothing = renderOptions?.meshNormalSmoothing;
|
|
1952
|
-
if (!smoothing) return "
|
|
1953
|
-
if (smoothing === true) return "meshNormalSmoothing:true
|
|
1954
|
-
return
|
|
2182
|
+
if (!smoothing) return renderOptions?.appearance ?? "standard";
|
|
2183
|
+
if (smoothing === true) return `${renderOptions?.appearance ?? "standard"}:meshNormalSmoothing:true`;
|
|
2184
|
+
return `${renderOptions?.appearance ?? "standard"}:meshNormalSmoothing:${smoothing.tolerance ?? "default"}`;
|
|
1955
2185
|
}
|
|
1956
2186
|
function SceneRenderer({ renderOptions, ...props }) {
|
|
1957
2187
|
const {
|
|
@@ -1990,22 +2220,44 @@ function SceneRenderer({ renderOptions, ...props }) {
|
|
|
1990
2220
|
group.remove(group.children[0]);
|
|
1991
2221
|
}
|
|
1992
2222
|
const refs = [];
|
|
1993
|
-
|
|
1994
|
-
const
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2223
|
+
const dispose = () => {
|
|
2224
|
+
for (const body of refs) {
|
|
2225
|
+
body?.parent?.remove(body);
|
|
2226
|
+
body?.traverse((object) => {
|
|
2227
|
+
const mesh = object;
|
|
2228
|
+
if (!mesh.isMesh) return;
|
|
2229
|
+
mesh.geometry.dispose();
|
|
2230
|
+
for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) material.dispose();
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2233
|
+
geomBuilder.dispose();
|
|
2234
|
+
prevModelRef.current = null;
|
|
2235
|
+
prevRenderOptionsKeyRef.current = null;
|
|
2236
|
+
prevHiddenVersionRef.current = null;
|
|
2237
|
+
if (bodyRefs.current === refs) bodyRefs.current = [];
|
|
2238
|
+
};
|
|
2239
|
+
try {
|
|
2240
|
+
for (let i = 0; i < model.nbody; i++) {
|
|
2241
|
+
const bodyGroup = new THREE13.Group();
|
|
2242
|
+
refs.push(bodyGroup);
|
|
2243
|
+
bodyGroup.userData.bodyID = i;
|
|
2244
|
+
const bodyName = getName(model, model.name_bodyadr[i]);
|
|
2245
|
+
if (!hiddenBodiesRef.current.has(bodyName)) {
|
|
2246
|
+
for (let g = 0; g < model.ngeom; g++) {
|
|
2247
|
+
if (model.geom_bodyid[g] === i) {
|
|
2248
|
+
const mesh = geomBuilder.create(model, g, mjDataRef.current ?? void 0);
|
|
2249
|
+
if (mesh) bodyGroup.add(mesh);
|
|
2250
|
+
}
|
|
2002
2251
|
}
|
|
2003
2252
|
}
|
|
2253
|
+
group.add(bodyGroup);
|
|
2004
2254
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2255
|
+
} catch (error) {
|
|
2256
|
+
dispose();
|
|
2257
|
+
throw error;
|
|
2007
2258
|
}
|
|
2008
2259
|
bodyRefs.current = refs;
|
|
2260
|
+
return dispose;
|
|
2009
2261
|
}, [status, geomBuilder, mjModelRef, renderOptionsKey, hiddenBodiesRef, hiddenBodiesVersion]);
|
|
2010
2262
|
const syncBodiesToData = useCallback(() => {
|
|
2011
2263
|
const data = mjDataRef.current;
|
|
@@ -2020,9 +2272,9 @@ function SceneRenderer({ renderOptions, ...props }) {
|
|
|
2020
2272
|
const alpha = interpolation.alpha;
|
|
2021
2273
|
const i3 = i * 3;
|
|
2022
2274
|
ref.position.set(
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2275
|
+
THREE13.MathUtils.lerp(interpolation.previousXpos[i3], interpolation.currentXpos[i3], alpha),
|
|
2276
|
+
THREE13.MathUtils.lerp(interpolation.previousXpos[i3 + 1], interpolation.currentXpos[i3 + 1], alpha),
|
|
2277
|
+
THREE13.MathUtils.lerp(interpolation.previousXpos[i3 + 2], interpolation.currentXpos[i3 + 2], alpha)
|
|
2026
2278
|
);
|
|
2027
2279
|
const i4 = i * 4;
|
|
2028
2280
|
_previousQuat.set(
|
|
@@ -2082,8 +2334,8 @@ function SceneRenderer({ renderOptions, ...props }) {
|
|
|
2082
2334
|
}
|
|
2083
2335
|
);
|
|
2084
2336
|
}
|
|
2085
|
-
var _previousQuat = new
|
|
2086
|
-
var _currentQuat = new
|
|
2337
|
+
var _previousQuat = new THREE13.Quaternion();
|
|
2338
|
+
var _currentQuat = new THREE13.Quaternion();
|
|
2087
2339
|
var CameraViewportRegistryContext = createContext(null);
|
|
2088
2340
|
var nextViewportId = 0;
|
|
2089
2341
|
var VIEWPORT_RENDER_PRIORITY = 1;
|
|
@@ -2304,17 +2556,17 @@ function useFrameCapture(defaultOptions = {}) {
|
|
|
2304
2556
|
reset
|
|
2305
2557
|
};
|
|
2306
2558
|
}
|
|
2307
|
-
var _raycaster = new
|
|
2308
|
-
var _ndc = new
|
|
2559
|
+
var _raycaster = new THREE13.Raycaster();
|
|
2560
|
+
var _ndc = new THREE13.Vector2();
|
|
2309
2561
|
function toVector3(value, fallback) {
|
|
2310
2562
|
if (!value) return fallback.clone();
|
|
2311
|
-
return value instanceof
|
|
2563
|
+
return value instanceof THREE13.Vector3 ? value.clone() : new THREE13.Vector3(value[0], value[1], value[2]);
|
|
2312
2564
|
}
|
|
2313
2565
|
function applyCameraPose(camera, options, fallbackCamera) {
|
|
2314
2566
|
camera.position.copy(toVector3(options.position, fallbackCamera.position));
|
|
2315
2567
|
camera.up.copy(toVector3(options.up, fallbackCamera.up));
|
|
2316
2568
|
if (options.quaternion) {
|
|
2317
|
-
if (options.quaternion instanceof
|
|
2569
|
+
if (options.quaternion instanceof THREE13.Quaternion) {
|
|
2318
2570
|
camera.quaternion.copy(options.quaternion);
|
|
2319
2571
|
} else {
|
|
2320
2572
|
camera.quaternion.set(
|
|
@@ -2325,15 +2577,15 @@ function applyCameraPose(camera, options, fallbackCamera) {
|
|
|
2325
2577
|
);
|
|
2326
2578
|
}
|
|
2327
2579
|
} else if (options.lookAt) {
|
|
2328
|
-
camera.lookAt(toVector3(options.lookAt, new
|
|
2580
|
+
camera.lookAt(toVector3(options.lookAt, new THREE13.Vector3()));
|
|
2329
2581
|
} else {
|
|
2330
2582
|
camera.quaternion.copy(fallbackCamera.quaternion);
|
|
2331
2583
|
}
|
|
2332
2584
|
camera.updateMatrixWorld();
|
|
2333
2585
|
}
|
|
2334
2586
|
function createProjectionCamera(fallbackCamera, options, width, height) {
|
|
2335
|
-
const camera = options.camera ? options.camera.clone() : fallbackCamera instanceof
|
|
2336
|
-
if (camera instanceof
|
|
2587
|
+
const camera = options.camera ? options.camera.clone() : fallbackCamera instanceof THREE13.PerspectiveCamera ? fallbackCamera.clone() : new THREE13.PerspectiveCamera(45, width / height, 0.01, 100);
|
|
2588
|
+
if (camera instanceof THREE13.PerspectiveCamera) {
|
|
2337
2589
|
camera.aspect = width / height;
|
|
2338
2590
|
camera.fov = options.fov ?? camera.fov;
|
|
2339
2591
|
camera.near = options.near ?? camera.near;
|
|
@@ -2498,8 +2750,8 @@ var _applyPoint = new Float64Array(3);
|
|
|
2498
2750
|
var _rayPnt = new Float64Array(3);
|
|
2499
2751
|
var _rayVec = new Float64Array(3);
|
|
2500
2752
|
var _rayGeomId = new Int32Array(1);
|
|
2501
|
-
var _projRaycaster = new
|
|
2502
|
-
var _projNdc = new
|
|
2753
|
+
var _projRaycaster = new THREE13.Raycaster();
|
|
2754
|
+
var _projNdc = new THREE13.Vector2();
|
|
2503
2755
|
function waitForNextAnimationFrame2() {
|
|
2504
2756
|
return new Promise((resolve) => {
|
|
2505
2757
|
requestAnimationFrame(() => resolve());
|
|
@@ -2524,7 +2776,7 @@ function quaternionFromMujocoQuat(values, offset) {
|
|
|
2524
2776
|
];
|
|
2525
2777
|
}
|
|
2526
2778
|
function quaternionFromXmat(values, offset) {
|
|
2527
|
-
const matrix = new
|
|
2779
|
+
const matrix = new THREE13.Matrix4();
|
|
2528
2780
|
matrix.set(
|
|
2529
2781
|
values[offset],
|
|
2530
2782
|
values[offset + 1],
|
|
@@ -2543,7 +2795,7 @@ function quaternionFromXmat(values, offset) {
|
|
|
2543
2795
|
0,
|
|
2544
2796
|
1
|
|
2545
2797
|
);
|
|
2546
|
-
const quaternion = new
|
|
2798
|
+
const quaternion = new THREE13.Quaternion().setFromRotationMatrix(matrix);
|
|
2547
2799
|
return [quaternion.x, quaternion.y, quaternion.z, quaternion.w];
|
|
2548
2800
|
}
|
|
2549
2801
|
function omitResolvedCameraSelectors(options) {
|
|
@@ -2551,14 +2803,14 @@ function omitResolvedCameraSelectors(options) {
|
|
|
2551
2803
|
return rest;
|
|
2552
2804
|
}
|
|
2553
2805
|
function vector3FromCaptureValue(value) {
|
|
2554
|
-
return value instanceof
|
|
2806
|
+
return value instanceof THREE13.Vector3 ? value.clone() : new THREE13.Vector3(value[0], value[1], value[2]);
|
|
2555
2807
|
}
|
|
2556
2808
|
function quaternionFromCaptureValue(value) {
|
|
2557
|
-
return value instanceof
|
|
2809
|
+
return value instanceof THREE13.Quaternion ? value.clone() : new THREE13.Quaternion(value[0], value[1], value[2], value[3]);
|
|
2558
2810
|
}
|
|
2559
2811
|
function applyMountedCameraPoseOffsets(options, position, quaternion) {
|
|
2560
|
-
const resolvedPosition = new
|
|
2561
|
-
const resolvedQuaternion = new
|
|
2812
|
+
const resolvedPosition = new THREE13.Vector3(position[0], position[1], position[2]);
|
|
2813
|
+
const resolvedQuaternion = new THREE13.Quaternion(
|
|
2562
2814
|
quaternion[0],
|
|
2563
2815
|
quaternion[1],
|
|
2564
2816
|
quaternion[2],
|
|
@@ -2643,7 +2895,7 @@ function mujocoCameraProjectionMatrix(model, cameraId, width, height, near, far)
|
|
|
2643
2895
|
const cy = height * (0.5 + principalY / sensorHeight);
|
|
2644
2896
|
const znear = near ?? 0.01;
|
|
2645
2897
|
const zfar = far ?? 100;
|
|
2646
|
-
return new
|
|
2898
|
+
return new THREE13.Matrix4().set(
|
|
2647
2899
|
2 * fx / width,
|
|
2648
2900
|
0,
|
|
2649
2901
|
1 - 2 * cx / width,
|
|
@@ -3517,7 +3769,7 @@ function MujocoSimProvider({
|
|
|
3517
3769
|
const geomId = _rayGeomId[0];
|
|
3518
3770
|
const bodyId = geomId >= 0 ? model.geom_bodyid[geomId] : -1;
|
|
3519
3771
|
return {
|
|
3520
|
-
point: new
|
|
3772
|
+
point: new THREE13.Vector3(
|
|
3521
3773
|
origin.x + dir.x * dist,
|
|
3522
3774
|
origin.y + dir.y * dist,
|
|
3523
3775
|
origin.z + dir.z * dist
|
|
@@ -4442,7 +4694,7 @@ var GenericIK = class {
|
|
|
4442
4694
|
*/
|
|
4443
4695
|
solveJoints(model, data, siteId, jointIds, targetPos, targetQuat, currentQpos = data.qpos, opts) {
|
|
4444
4696
|
const o = resolveOptions(opts);
|
|
4445
|
-
const targetRotation = new
|
|
4697
|
+
const targetRotation = new THREE13.Quaternion(targetQuat.x, targetQuat.y, targetQuat.z, targetQuat.w);
|
|
4446
4698
|
if (!Number.isInteger(siteId) || siteId < 0 || siteId >= model.nsite)
|
|
4447
4699
|
throw new Error("Invalid IK site ID");
|
|
4448
4700
|
if (currentQpos.length !== model.nq || !Array.from(currentQpos).every(Number.isFinite))
|
|
@@ -4494,7 +4746,7 @@ var GenericIK = class {
|
|
|
4494
4746
|
q[adr] = Math.max(Math.min(...limits), Math.min(Math.max(...limits), q[adr]));
|
|
4495
4747
|
} else {
|
|
4496
4748
|
const offset = adr + (type === 0 ? 3 : 0);
|
|
4497
|
-
const quat = new
|
|
4749
|
+
const quat = new THREE13.Quaternion(
|
|
4498
4750
|
q[offset + 1],
|
|
4499
4751
|
q[offset + 2],
|
|
4500
4752
|
q[offset + 3],
|
|
@@ -4511,7 +4763,7 @@ var GenericIK = class {
|
|
|
4511
4763
|
const limit = model.jnt_range[2 * id + 1];
|
|
4512
4764
|
if (angle > limit)
|
|
4513
4765
|
quat.identity().slerp(
|
|
4514
|
-
new
|
|
4766
|
+
new THREE13.Quaternion(
|
|
4515
4767
|
q[offset + 1],
|
|
4516
4768
|
q[offset + 2],
|
|
4517
4769
|
q[offset + 3],
|
|
@@ -4611,7 +4863,7 @@ function orientationError(R_cur, R_tgt) {
|
|
|
4611
4863
|
return [0, 0, 0];
|
|
4612
4864
|
}
|
|
4613
4865
|
if (angle > Math.PI - 1e-4) {
|
|
4614
|
-
const matrix = new
|
|
4866
|
+
const matrix = new THREE13.Matrix4().set(
|
|
4615
4867
|
Re[0],
|
|
4616
4868
|
Re[1],
|
|
4617
4869
|
Re[2],
|
|
@@ -4629,7 +4881,7 @@ function orientationError(R_cur, R_tgt) {
|
|
|
4629
4881
|
0,
|
|
4630
4882
|
1
|
|
4631
4883
|
);
|
|
4632
|
-
const q = new
|
|
4884
|
+
const q = new THREE13.Quaternion().setFromRotationMatrix(matrix).normalize();
|
|
4633
4885
|
const scale = angle / Math.hypot(q.x, q.y, q.z) * (q.w < 0 ? -1 : 1);
|
|
4634
4886
|
return [q.x * scale, q.y * scale, q.z * scale];
|
|
4635
4887
|
}
|
|
@@ -4683,12 +4935,12 @@ function solve6x6(A, b, x) {
|
|
|
4683
4935
|
}
|
|
4684
4936
|
|
|
4685
4937
|
// src/hooks/useIkController.ts
|
|
4686
|
-
var _syncMat4 = new
|
|
4938
|
+
var _syncMat4 = new THREE13.Matrix4();
|
|
4687
4939
|
function toIkVector3(value) {
|
|
4688
|
-
return "x" in value ? new
|
|
4940
|
+
return "x" in value ? new THREE13.Vector3(value.x, value.y, value.z) : new THREE13.Vector3(value[0], value[1], value[2]);
|
|
4689
4941
|
}
|
|
4690
4942
|
function toIkQuaternion(value) {
|
|
4691
|
-
return "x" in value ? new
|
|
4943
|
+
return "x" in value ? new THREE13.Quaternion(value.x, value.y, value.z, value.w) : new THREE13.Quaternion(value[0], value[1], value[2], value[3]);
|
|
4692
4944
|
}
|
|
4693
4945
|
function syncGizmoToSite(data, siteId, target) {
|
|
4694
4946
|
if (siteId === -1) return;
|
|
@@ -4721,7 +4973,7 @@ var useIkController = createControllerHook(
|
|
|
4721
4973
|
const { mjModelRef, mjDataRef, mujocoRef, resetCallbacks, status } = useMujocoContext();
|
|
4722
4974
|
const ikEnabledRef = useRef(false);
|
|
4723
4975
|
const ikCalculatingRef = useRef(false);
|
|
4724
|
-
const ikTargetRef = useRef(new
|
|
4976
|
+
const ikTargetRef = useRef(new THREE13.Group());
|
|
4725
4977
|
const siteIdRef = useRef(-1);
|
|
4726
4978
|
const controlGroupRef = useRef(null);
|
|
4727
4979
|
const genericIkRef = useRef(null);
|
|
@@ -4738,10 +4990,10 @@ var useIkController = createControllerHook(
|
|
|
4738
4990
|
const needsInitialSync = useRef(true);
|
|
4739
4991
|
const gizmoAnimRef = useRef({
|
|
4740
4992
|
active: false,
|
|
4741
|
-
startPos: new
|
|
4742
|
-
endPos: new
|
|
4743
|
-
startRot: new
|
|
4744
|
-
endRot: new
|
|
4993
|
+
startPos: new THREE13.Vector3(),
|
|
4994
|
+
endPos: new THREE13.Vector3(),
|
|
4995
|
+
startRot: new THREE13.Quaternion(),
|
|
4996
|
+
endRot: new THREE13.Quaternion(),
|
|
4745
4997
|
startTime: 0,
|
|
4746
4998
|
duration: 1e3
|
|
4747
4999
|
});
|
|
@@ -4902,8 +5154,8 @@ var useIkController = createControllerHook(
|
|
|
4902
5154
|
const target = ikTargetRef.current;
|
|
4903
5155
|
if (!target) return;
|
|
4904
5156
|
const targetPos = toIkVector3(pos);
|
|
4905
|
-
const targetRot = new
|
|
4906
|
-
new
|
|
5157
|
+
const targetRot = new THREE13.Quaternion().setFromEuler(
|
|
5158
|
+
new THREE13.Euler(Math.PI, 0, 0)
|
|
4907
5159
|
);
|
|
4908
5160
|
if (duration > 0) {
|
|
4909
5161
|
const ga = gizmoAnimRef.current;
|
|
@@ -4928,7 +5180,7 @@ var useIkController = createControllerHook(
|
|
|
4928
5180
|
if (!ikCalculatingRef.current || !target) return null;
|
|
4929
5181
|
return {
|
|
4930
5182
|
pos: target.position.clone(),
|
|
4931
|
-
rot: new
|
|
5183
|
+
rot: new THREE13.Euler().setFromQuaternion(target.quaternion)
|
|
4932
5184
|
};
|
|
4933
5185
|
},
|
|
4934
5186
|
[]
|
|
@@ -5024,10 +5276,10 @@ function Body({
|
|
|
5024
5276
|
if (!hasChildren) return null;
|
|
5025
5277
|
return /* @__PURE__ */ jsx("group", { ref: groupRef, children });
|
|
5026
5278
|
}
|
|
5027
|
-
var _mat4 = new
|
|
5028
|
-
var _pos = new
|
|
5029
|
-
var _quat = new
|
|
5030
|
-
var _scale = new
|
|
5279
|
+
var _mat4 = new THREE13.Matrix4();
|
|
5280
|
+
var _pos = new THREE13.Vector3();
|
|
5281
|
+
var _quat = new THREE13.Quaternion();
|
|
5282
|
+
var _scale = new THREE13.Vector3(1, 1, 1);
|
|
5031
5283
|
function IkGizmo({ controller, siteName, scale = 0.18, onDrag }) {
|
|
5032
5284
|
const { mjModelRef, mjDataRef, status } = useMujocoContext();
|
|
5033
5285
|
const { ikTargetRef, siteIdRef, ikEnabledRef, setIkEnabled } = controller;
|
|
@@ -5126,7 +5378,7 @@ function IkGizmo({ controller, siteName, scale = 0.18, onDrag }) {
|
|
|
5126
5378
|
}
|
|
5127
5379
|
);
|
|
5128
5380
|
}
|
|
5129
|
-
var _dummy = new
|
|
5381
|
+
var _dummy = new THREE13.Object3D();
|
|
5130
5382
|
function ContactMarkers({
|
|
5131
5383
|
maxContacts = 100,
|
|
5132
5384
|
radius = 8e-3,
|
|
@@ -5180,11 +5432,11 @@ function ContactMarkers({
|
|
|
5180
5432
|
var _force = new Float64Array(3);
|
|
5181
5433
|
var _torque = new Float64Array(3);
|
|
5182
5434
|
var _point = new Float64Array(3);
|
|
5183
|
-
var _bodyPos = new
|
|
5184
|
-
var _bodyQuat = new
|
|
5185
|
-
var _worldHit = new
|
|
5186
|
-
var _raycaster2 = new
|
|
5187
|
-
var _mouse = new
|
|
5435
|
+
var _bodyPos = new THREE13.Vector3();
|
|
5436
|
+
var _bodyQuat = new THREE13.Quaternion();
|
|
5437
|
+
var _worldHit = new THREE13.Vector3();
|
|
5438
|
+
var _raycaster2 = new THREE13.Raycaster();
|
|
5439
|
+
var _mouse = new THREE13.Vector2();
|
|
5188
5440
|
function DragInteraction({
|
|
5189
5441
|
stiffness = 250,
|
|
5190
5442
|
showArrow = true,
|
|
@@ -5195,16 +5447,16 @@ function DragInteraction({
|
|
|
5195
5447
|
const draggingRef = useRef(false);
|
|
5196
5448
|
const bodyIdRef = useRef(-1);
|
|
5197
5449
|
const grabDistanceRef = useRef(0);
|
|
5198
|
-
const localHitRef = useRef(new
|
|
5199
|
-
const grabWorldRef = useRef(new
|
|
5200
|
-
const mouseWorldRef = useRef(new
|
|
5450
|
+
const localHitRef = useRef(new THREE13.Vector3());
|
|
5451
|
+
const grabWorldRef = useRef(new THREE13.Vector3());
|
|
5452
|
+
const mouseWorldRef = useRef(new THREE13.Vector3());
|
|
5201
5453
|
const arrowRef = useRef(null);
|
|
5202
5454
|
const groupRef = useRef(null);
|
|
5203
5455
|
useEffect(() => {
|
|
5204
5456
|
if (!showArrow || !groupRef.current) return;
|
|
5205
|
-
const arrow = new
|
|
5206
|
-
new
|
|
5207
|
-
new
|
|
5457
|
+
const arrow = new THREE13.ArrowHelper(
|
|
5458
|
+
new THREE13.Vector3(0, 1, 0),
|
|
5459
|
+
new THREE13.Vector3(),
|
|
5208
5460
|
0.1,
|
|
5209
5461
|
16729156
|
|
5210
5462
|
);
|
|
@@ -5387,7 +5639,7 @@ function useSceneLights(intensity = 1) {
|
|
|
5387
5639
|
const dr = lightDiffuse ? lightDiffuse[3 * i] : 1;
|
|
5388
5640
|
const dg = lightDiffuse ? lightDiffuse[3 * i + 1] : 1;
|
|
5389
5641
|
const db = lightDiffuse ? lightDiffuse[3 * i + 2] : 1;
|
|
5390
|
-
const color = new
|
|
5642
|
+
const color = new THREE13.Color(dr, dg, db);
|
|
5391
5643
|
const px = lightPos[3 * i];
|
|
5392
5644
|
const py = lightPos[3 * i + 1];
|
|
5393
5645
|
const pz = lightPos[3 * i + 2];
|
|
@@ -5395,7 +5647,7 @@ function useSceneLights(intensity = 1) {
|
|
|
5395
5647
|
const dy = lightDir[3 * i + 1];
|
|
5396
5648
|
const dz = lightDir[3 * i + 2];
|
|
5397
5649
|
if (isDirectional) {
|
|
5398
|
-
const light = new
|
|
5650
|
+
const light = new THREE13.DirectionalLight(color, finalIntensity);
|
|
5399
5651
|
light.position.set(px, py, pz);
|
|
5400
5652
|
light.target.position.set(px + dx, py + dy, pz + dz);
|
|
5401
5653
|
light.castShadow = castShadow;
|
|
@@ -5418,7 +5670,7 @@ function useSceneLights(intensity = 1) {
|
|
|
5418
5670
|
const cutoff = lightCutoff ? lightCutoff[i] : 45;
|
|
5419
5671
|
const exponent = lightExponent ? lightExponent[i] : 10;
|
|
5420
5672
|
const angle = cutoff * Math.PI / 180;
|
|
5421
|
-
const light = new
|
|
5673
|
+
const light = new THREE13.SpotLight(color, finalIntensity, 0, angle, exponent / 128);
|
|
5422
5674
|
light.position.set(px, py, pz);
|
|
5423
5675
|
light.target.position.set(px + dx, py + dy, pz + dz);
|
|
5424
5676
|
light.castShadow = castShadow;
|
|
@@ -5767,31 +6019,31 @@ var JOINT_COLORS = {
|
|
|
5767
6019
|
3: 16776960
|
|
5768
6020
|
// hinge - yellow
|
|
5769
6021
|
};
|
|
5770
|
-
var _v3a = new
|
|
5771
|
-
new
|
|
5772
|
-
var _quat2 = new
|
|
5773
|
-
var _cameraMatrix = new
|
|
5774
|
-
var _contactPos = new
|
|
5775
|
-
var _contactNormal = new
|
|
6022
|
+
var _v3a = new THREE13.Vector3();
|
|
6023
|
+
new THREE13.Vector3();
|
|
6024
|
+
var _quat2 = new THREE13.Quaternion();
|
|
6025
|
+
var _cameraMatrix = new THREE13.Matrix4();
|
|
6026
|
+
var _contactPos = new THREE13.Vector3();
|
|
6027
|
+
var _contactNormal = new THREE13.Vector3();
|
|
5776
6028
|
var MAX_CONTACT_ARROWS = 50;
|
|
5777
6029
|
var CAMERA_DEBUG_LENGTH = 0.12;
|
|
5778
6030
|
var CAMERA_DEBUG_FRUSTUM_DEPTH = 0.08;
|
|
5779
6031
|
function toVector32(value, fallback) {
|
|
5780
6032
|
if (!value) return fallback.clone();
|
|
5781
|
-
return value instanceof
|
|
6033
|
+
return value instanceof THREE13.Vector3 ? value.clone() : new THREE13.Vector3(value[0], value[1], value[2]);
|
|
5782
6034
|
}
|
|
5783
6035
|
function createCameraLabel(text, color) {
|
|
5784
6036
|
const canvas = document.createElement("canvas");
|
|
5785
6037
|
canvas.width = 256;
|
|
5786
6038
|
canvas.height = 64;
|
|
5787
6039
|
const ctx = canvas.getContext("2d");
|
|
5788
|
-
ctx.fillStyle = new
|
|
6040
|
+
ctx.fillStyle = new THREE13.Color(color).getStyle();
|
|
5789
6041
|
ctx.font = "bold 32px monospace";
|
|
5790
6042
|
ctx.textAlign = "center";
|
|
5791
6043
|
ctx.fillText(text, 128, 42);
|
|
5792
|
-
const texture = new
|
|
5793
|
-
const sprite = new
|
|
5794
|
-
new
|
|
6044
|
+
const texture = new THREE13.CanvasTexture(canvas);
|
|
6045
|
+
const sprite = new THREE13.Sprite(
|
|
6046
|
+
new THREE13.SpriteMaterial({
|
|
5795
6047
|
map: texture,
|
|
5796
6048
|
depthTest: false,
|
|
5797
6049
|
transparent: true
|
|
@@ -5806,12 +6058,12 @@ function createVirtualCameraDebugObject(camera, index) {
|
|
|
5806
6058
|
const color = camera.color ?? "#ff3d71";
|
|
5807
6059
|
const aimColor = camera.aimColor ?? "#38bdf8";
|
|
5808
6060
|
const markerScale = camera.markerScale ?? 1;
|
|
5809
|
-
const cameraPosition = toVector32(camera.position, new
|
|
5810
|
-
const configuredUp = toVector32(camera.up, new
|
|
5811
|
-
const cameraQuaternion = new
|
|
5812
|
-
const forward = new
|
|
6061
|
+
const cameraPosition = toVector32(camera.position, new THREE13.Vector3());
|
|
6062
|
+
const configuredUp = toVector32(camera.up, new THREE13.Vector3(0, 0, 1)).normalize();
|
|
6063
|
+
const cameraQuaternion = new THREE13.Quaternion();
|
|
6064
|
+
const forward = new THREE13.Vector3();
|
|
5813
6065
|
if (camera.quaternion) {
|
|
5814
|
-
if (camera.quaternion instanceof
|
|
6066
|
+
if (camera.quaternion instanceof THREE13.Quaternion) {
|
|
5815
6067
|
cameraQuaternion.copy(camera.quaternion);
|
|
5816
6068
|
} else {
|
|
5817
6069
|
cameraQuaternion.set(
|
|
@@ -5825,13 +6077,13 @@ function createVirtualCameraDebugObject(camera, index) {
|
|
|
5825
6077
|
} else {
|
|
5826
6078
|
const target2 = toVector32(
|
|
5827
6079
|
camera.lookAt,
|
|
5828
|
-
cameraPosition.clone().add(new
|
|
6080
|
+
cameraPosition.clone().add(new THREE13.Vector3(0, 0, -1))
|
|
5829
6081
|
);
|
|
5830
6082
|
forward.copy(target2).sub(cameraPosition);
|
|
5831
6083
|
if (forward.lengthSq() < 1e-8) forward.set(0, 0, -1);
|
|
5832
6084
|
forward.normalize();
|
|
5833
6085
|
cameraQuaternion.setFromRotationMatrix(
|
|
5834
|
-
new
|
|
6086
|
+
new THREE13.Matrix4().lookAt(cameraPosition, target2, configuredUp)
|
|
5835
6087
|
);
|
|
5836
6088
|
}
|
|
5837
6089
|
const target = camera.lookAt ? toVector32(camera.lookAt, cameraPosition.clone().add(forward)) : cameraPosition.clone().addScaledVector(forward, 0.4);
|
|
@@ -5843,7 +6095,7 @@ function createVirtualCameraDebugObject(camera, index) {
|
|
|
5843
6095
|
if (right.lengthSq() < 1e-8) right.set(1, 0, 0);
|
|
5844
6096
|
right.normalize();
|
|
5845
6097
|
const orthogonalUp = right.clone().cross(forward).normalize();
|
|
5846
|
-
const frustumHeight = 2 * Math.tan(
|
|
6098
|
+
const frustumHeight = 2 * Math.tan(THREE13.MathUtils.degToRad(fov) / 2) * depth;
|
|
5847
6099
|
const frustumWidth = frustumHeight * aspect;
|
|
5848
6100
|
const center = cameraPosition.clone().addScaledVector(forward, depth);
|
|
5849
6101
|
const halfRight = right.clone().multiplyScalar(frustumWidth / 2);
|
|
@@ -5870,13 +6122,13 @@ function createVirtualCameraDebugObject(camera, index) {
|
|
|
5870
6122
|
bottomLeft,
|
|
5871
6123
|
topLeft
|
|
5872
6124
|
];
|
|
5873
|
-
const group = new
|
|
6125
|
+
const group = new THREE13.Group();
|
|
5874
6126
|
group.name = camera.name ?? `virtual-camera-${index}`;
|
|
5875
6127
|
group.renderOrder = 999;
|
|
5876
6128
|
group.frustumCulled = false;
|
|
5877
|
-
const frustum = new
|
|
5878
|
-
new
|
|
5879
|
-
new
|
|
6129
|
+
const frustum = new THREE13.LineSegments(
|
|
6130
|
+
new THREE13.BufferGeometry().setFromPoints(frustumPoints),
|
|
6131
|
+
new THREE13.LineBasicMaterial({
|
|
5880
6132
|
color,
|
|
5881
6133
|
transparent: true,
|
|
5882
6134
|
opacity: 0.9,
|
|
@@ -5886,9 +6138,9 @@ function createVirtualCameraDebugObject(camera, index) {
|
|
|
5886
6138
|
frustum.renderOrder = 999;
|
|
5887
6139
|
frustum.frustumCulled = false;
|
|
5888
6140
|
group.add(frustum);
|
|
5889
|
-
const aim = new
|
|
5890
|
-
new
|
|
5891
|
-
new
|
|
6141
|
+
const aim = new THREE13.LineSegments(
|
|
6142
|
+
new THREE13.BufferGeometry().setFromPoints([cameraPosition, target]),
|
|
6143
|
+
new THREE13.LineBasicMaterial({
|
|
5892
6144
|
color: aimColor,
|
|
5893
6145
|
transparent: true,
|
|
5894
6146
|
opacity: 0.95,
|
|
@@ -5898,26 +6150,26 @@ function createVirtualCameraDebugObject(camera, index) {
|
|
|
5898
6150
|
aim.renderOrder = 999;
|
|
5899
6151
|
aim.frustumCulled = false;
|
|
5900
6152
|
group.add(aim);
|
|
5901
|
-
const markerGroup = new
|
|
6153
|
+
const markerGroup = new THREE13.Group();
|
|
5902
6154
|
markerGroup.position.copy(cameraPosition);
|
|
5903
6155
|
markerGroup.quaternion.copy(cameraQuaternion);
|
|
5904
6156
|
markerGroup.renderOrder = 999;
|
|
5905
6157
|
markerGroup.frustumCulled = false;
|
|
5906
|
-
markerGroup.add(new
|
|
5907
|
-
new
|
|
5908
|
-
new
|
|
6158
|
+
markerGroup.add(new THREE13.Mesh(
|
|
6159
|
+
new THREE13.BoxGeometry(0.045 * markerScale, 0.028 * markerScale, 0.022 * markerScale),
|
|
6160
|
+
new THREE13.MeshBasicMaterial({ color, depthTest: false })
|
|
5909
6161
|
));
|
|
5910
|
-
const lens = new
|
|
5911
|
-
new
|
|
5912
|
-
new
|
|
6162
|
+
const lens = new THREE13.Mesh(
|
|
6163
|
+
new THREE13.BoxGeometry(0.025 * markerScale, 0.018 * markerScale, 0.014 * markerScale),
|
|
6164
|
+
new THREE13.MeshBasicMaterial({ color: aimColor, depthTest: false })
|
|
5913
6165
|
);
|
|
5914
6166
|
lens.position.set(0, 0, -0.021 * markerScale);
|
|
5915
6167
|
markerGroup.add(lens);
|
|
5916
6168
|
if (camera.name) markerGroup.add(createCameraLabel(camera.name, color));
|
|
5917
6169
|
group.add(markerGroup);
|
|
5918
|
-
const targetMarker = new
|
|
5919
|
-
new
|
|
5920
|
-
new
|
|
6170
|
+
const targetMarker = new THREE13.Mesh(
|
|
6171
|
+
new THREE13.SphereGeometry(0.018 * markerScale, 16, 10),
|
|
6172
|
+
new THREE13.MeshBasicMaterial({ color: aimColor, depthTest: false })
|
|
5921
6173
|
);
|
|
5922
6174
|
targetMarker.position.copy(target);
|
|
5923
6175
|
targetMarker.renderOrder = 999;
|
|
@@ -5956,21 +6208,21 @@ function Debug({
|
|
|
5956
6208
|
let geometry = null;
|
|
5957
6209
|
switch (type) {
|
|
5958
6210
|
case 2:
|
|
5959
|
-
geometry = new
|
|
6211
|
+
geometry = new THREE13.SphereGeometry(s[3 * i], 12, 8);
|
|
5960
6212
|
break;
|
|
5961
6213
|
case 3:
|
|
5962
|
-
geometry = new
|
|
6214
|
+
geometry = new THREE13.CapsuleGeometry(s[3 * i], s[3 * i + 1] * 2, 6, 8);
|
|
5963
6215
|
break;
|
|
5964
6216
|
case 5:
|
|
5965
|
-
geometry = new
|
|
6217
|
+
geometry = new THREE13.CylinderGeometry(s[3 * i], s[3 * i], s[3 * i + 1] * 2, 12);
|
|
5966
6218
|
break;
|
|
5967
6219
|
case 6:
|
|
5968
|
-
geometry = new
|
|
6220
|
+
geometry = new THREE13.BoxGeometry(s[3 * i] * 2, s[3 * i + 1] * 2, s[3 * i + 2] * 2);
|
|
5969
6221
|
break;
|
|
5970
6222
|
}
|
|
5971
6223
|
if (geometry) {
|
|
5972
|
-
const mat = new
|
|
5973
|
-
const mesh = new
|
|
6224
|
+
const mat = new THREE13.MeshBasicMaterial({ color: 65280, wireframe: true, transparent: true, opacity: 0.3 });
|
|
6225
|
+
const mesh = new THREE13.Mesh(geometry, mat);
|
|
5974
6226
|
mesh.userData.geomId = i;
|
|
5975
6227
|
mesh.userData.bodyId = model.geom_bodyid[i];
|
|
5976
6228
|
geoms.push(mesh);
|
|
@@ -5993,9 +6245,9 @@ function Debug({
|
|
|
5993
6245
|
}
|
|
5994
6246
|
if (maxGeomSize > 0) radius = maxGeomSize * 0.15;
|
|
5995
6247
|
}
|
|
5996
|
-
const geometry = new
|
|
5997
|
-
const mat = new
|
|
5998
|
-
const mesh = new
|
|
6248
|
+
const geometry = new THREE13.OctahedronGeometry(radius);
|
|
6249
|
+
const mat = new THREE13.MeshBasicMaterial({ color: 16711935, depthTest: false });
|
|
6250
|
+
const mesh = new THREE13.Mesh(geometry, mat);
|
|
5999
6251
|
mesh.renderOrder = 999;
|
|
6000
6252
|
mesh.frustumCulled = false;
|
|
6001
6253
|
mesh.userData.siteId = i;
|
|
@@ -6007,9 +6259,9 @@ function Debug({
|
|
|
6007
6259
|
ctx.font = "bold 36px monospace";
|
|
6008
6260
|
ctx.textAlign = "center";
|
|
6009
6261
|
ctx.fillText(getName(model, model.name_siteadr[i]), 128, 42);
|
|
6010
|
-
const tex = new
|
|
6011
|
-
const spriteMat = new
|
|
6012
|
-
const sprite = new
|
|
6262
|
+
const tex = new THREE13.CanvasTexture(canvas);
|
|
6263
|
+
const spriteMat = new THREE13.SpriteMaterial({ map: tex, depthTest: false, transparent: true });
|
|
6264
|
+
const sprite = new THREE13.Sprite(spriteMat);
|
|
6013
6265
|
const labelScale = radius * 15;
|
|
6014
6266
|
sprite.scale.set(labelScale, labelScale * 0.25, 1);
|
|
6015
6267
|
sprite.position.y = radius * 2;
|
|
@@ -6032,9 +6284,9 @@ function Debug({
|
|
|
6032
6284
|
}
|
|
6033
6285
|
}
|
|
6034
6286
|
const arrowLen = Math.max(maxGeomSize * 0.8, 0.05);
|
|
6035
|
-
const arrow = new
|
|
6036
|
-
new
|
|
6037
|
-
new
|
|
6287
|
+
const arrow = new THREE13.ArrowHelper(
|
|
6288
|
+
new THREE13.Vector3(0, 0, 1),
|
|
6289
|
+
new THREE13.Vector3(),
|
|
6038
6290
|
arrowLen,
|
|
6039
6291
|
color,
|
|
6040
6292
|
arrowLen * 0.25,
|
|
@@ -6042,7 +6294,7 @@ function Debug({
|
|
|
6042
6294
|
);
|
|
6043
6295
|
arrow.renderOrder = 999;
|
|
6044
6296
|
arrow.frustumCulled = false;
|
|
6045
|
-
arrow.line.material = new
|
|
6297
|
+
arrow.line.material = new THREE13.LineBasicMaterial({ color, depthTest: false });
|
|
6046
6298
|
arrow.cone.material.depthTest = false;
|
|
6047
6299
|
arrow.line.renderOrder = 999;
|
|
6048
6300
|
arrow.line.frustumCulled = false;
|
|
@@ -6057,20 +6309,20 @@ function Debug({
|
|
|
6057
6309
|
}
|
|
6058
6310
|
if (showCameras && model.ncam && model.name_camadr) {
|
|
6059
6311
|
for (let i = 0; i < model.ncam; i++) {
|
|
6060
|
-
const group = new
|
|
6312
|
+
const group = new THREE13.Group();
|
|
6061
6313
|
group.userData.cameraId = i;
|
|
6062
6314
|
group.renderOrder = 999;
|
|
6063
6315
|
group.frustumCulled = false;
|
|
6064
|
-
const marker = new
|
|
6065
|
-
new
|
|
6066
|
-
new
|
|
6316
|
+
const marker = new THREE13.Mesh(
|
|
6317
|
+
new THREE13.BoxGeometry(0.014, 9e-3, 6e-3),
|
|
6318
|
+
new THREE13.MeshBasicMaterial({ color: 3718648, depthTest: false })
|
|
6067
6319
|
);
|
|
6068
6320
|
marker.renderOrder = 999;
|
|
6069
6321
|
marker.frustumCulled = false;
|
|
6070
6322
|
group.add(marker);
|
|
6071
|
-
const forward = new
|
|
6072
|
-
new
|
|
6073
|
-
new
|
|
6323
|
+
const forward = new THREE13.ArrowHelper(
|
|
6324
|
+
new THREE13.Vector3(0, 0, -1),
|
|
6325
|
+
new THREE13.Vector3(),
|
|
6074
6326
|
CAMERA_DEBUG_LENGTH,
|
|
6075
6327
|
3718648,
|
|
6076
6328
|
CAMERA_DEBUG_LENGTH * 0.24,
|
|
@@ -6078,20 +6330,20 @@ function Debug({
|
|
|
6078
6330
|
);
|
|
6079
6331
|
forward.renderOrder = 999;
|
|
6080
6332
|
forward.frustumCulled = false;
|
|
6081
|
-
forward.line.material = new
|
|
6333
|
+
forward.line.material = new THREE13.LineBasicMaterial({
|
|
6082
6334
|
color: 3718648,
|
|
6083
6335
|
depthTest: false
|
|
6084
6336
|
});
|
|
6085
6337
|
forward.cone.material.depthTest = false;
|
|
6086
6338
|
group.add(forward);
|
|
6087
|
-
const frustumGeometry = new
|
|
6339
|
+
const frustumGeometry = new THREE13.BufferGeometry();
|
|
6088
6340
|
frustumGeometry.setAttribute(
|
|
6089
6341
|
"position",
|
|
6090
|
-
new
|
|
6342
|
+
new THREE13.Float32BufferAttribute(new Float32Array(8 * 2 * 3), 3)
|
|
6091
6343
|
);
|
|
6092
|
-
const frustum = new
|
|
6344
|
+
const frustum = new THREE13.LineSegments(
|
|
6093
6345
|
frustumGeometry,
|
|
6094
|
-
new
|
|
6346
|
+
new THREE13.LineBasicMaterial({
|
|
6095
6347
|
color: 3718648,
|
|
6096
6348
|
transparent: true,
|
|
6097
6349
|
opacity: 0.8,
|
|
@@ -6110,9 +6362,9 @@ function Debug({
|
|
|
6110
6362
|
ctx.font = "bold 32px monospace";
|
|
6111
6363
|
ctx.textAlign = "center";
|
|
6112
6364
|
ctx.fillText(getName(model, model.name_camadr[i]), 128, 42);
|
|
6113
|
-
const texture = new
|
|
6114
|
-
const sprite = new
|
|
6115
|
-
new
|
|
6365
|
+
const texture = new THREE13.CanvasTexture(canvas);
|
|
6366
|
+
const sprite = new THREE13.Sprite(
|
|
6367
|
+
new THREE13.SpriteMaterial({
|
|
6116
6368
|
map: texture,
|
|
6117
6369
|
depthTest: false,
|
|
6118
6370
|
transparent: true
|
|
@@ -6131,9 +6383,9 @@ function Debug({
|
|
|
6131
6383
|
}
|
|
6132
6384
|
if (showCOM) {
|
|
6133
6385
|
for (let i = 1; i < model.nbody; i++) {
|
|
6134
|
-
const geometry = new
|
|
6135
|
-
const mat = new
|
|
6136
|
-
const mesh = new
|
|
6386
|
+
const geometry = new THREE13.SphereGeometry(5e-3, 6, 6);
|
|
6387
|
+
const mat = new THREE13.MeshBasicMaterial({ color: 16711680 });
|
|
6388
|
+
const mesh = new THREE13.Mesh(geometry, mat);
|
|
6137
6389
|
mesh.userData.bodyId = i;
|
|
6138
6390
|
comMarkers.push(mesh);
|
|
6139
6391
|
}
|
|
@@ -6243,7 +6495,7 @@ function Debug({
|
|
|
6243
6495
|
);
|
|
6244
6496
|
group.quaternion.setFromRotationMatrix(_cameraMatrix);
|
|
6245
6497
|
const fovy = model.cam_fovy?.[cameraId] ?? 45;
|
|
6246
|
-
const halfHeight = Math.tan(
|
|
6498
|
+
const halfHeight = Math.tan(THREE13.MathUtils.degToRad(fovy) / 2) * CAMERA_DEBUG_FRUSTUM_DEPTH;
|
|
6247
6499
|
const halfWidth = halfHeight * 4 / 3;
|
|
6248
6500
|
const positions = group.userData.frustum.geometry.attributes.position;
|
|
6249
6501
|
const array = positions.array;
|
|
@@ -6288,9 +6540,9 @@ function Debug({
|
|
|
6288
6540
|
contactPoolInitRef.current = true;
|
|
6289
6541
|
const pool = [];
|
|
6290
6542
|
for (let i = 0; i < MAX_CONTACT_ARROWS; i++) {
|
|
6291
|
-
const arrow = new
|
|
6292
|
-
new
|
|
6293
|
-
new
|
|
6543
|
+
const arrow = new THREE13.ArrowHelper(
|
|
6544
|
+
new THREE13.Vector3(0, 1, 0),
|
|
6545
|
+
new THREE13.Vector3(),
|
|
6294
6546
|
0.1,
|
|
6295
6547
|
16729156,
|
|
6296
6548
|
0.03,
|
|
@@ -6355,9 +6607,9 @@ function Debug({
|
|
|
6355
6607
|
}
|
|
6356
6608
|
);
|
|
6357
6609
|
}
|
|
6358
|
-
var DEFAULT_TENDON_COLOR = new
|
|
6610
|
+
var DEFAULT_TENDON_COLOR = new THREE13.Color(0.3, 0.3, 0.8);
|
|
6359
6611
|
var DEFAULT_TENDON_WIDTH = 2e-3;
|
|
6360
|
-
new
|
|
6612
|
+
new THREE13.Vector3();
|
|
6361
6613
|
function TendonRenderer(props) {
|
|
6362
6614
|
const { mjModelRef, mjDataRef, status } = useMujocoContext();
|
|
6363
6615
|
const groupRef = useRef(null);
|
|
@@ -6371,7 +6623,7 @@ function TendonRenderer(props) {
|
|
|
6371
6623
|
if (!model || !data || !group) return;
|
|
6372
6624
|
const ntendon = model.ntendon ?? 0;
|
|
6373
6625
|
if (ntendon === 0) return;
|
|
6374
|
-
const material = new
|
|
6626
|
+
const material = new THREE13.MeshStandardMaterial({
|
|
6375
6627
|
color: DEFAULT_TENDON_COLOR,
|
|
6376
6628
|
roughness: 0.6,
|
|
6377
6629
|
metalness: 0.1
|
|
@@ -6386,11 +6638,11 @@ function TendonRenderer(props) {
|
|
|
6386
6638
|
curves.push(null);
|
|
6387
6639
|
continue;
|
|
6388
6640
|
}
|
|
6389
|
-
const points = Array.from({ length: wrapNum }, () => new
|
|
6390
|
-
const curve = new
|
|
6641
|
+
const points = Array.from({ length: wrapNum }, () => new THREE13.Vector3());
|
|
6642
|
+
const curve = new THREE13.CatmullRomCurve3(points, false);
|
|
6391
6643
|
const segments = Math.max(wrapNum * 2, 4);
|
|
6392
|
-
const geometry = new
|
|
6393
|
-
const mesh = new
|
|
6644
|
+
const geometry = new THREE13.TubeGeometry(curve, segments, DEFAULT_TENDON_WIDTH, 6, false);
|
|
6645
|
+
const mesh = new THREE13.Mesh(geometry, material);
|
|
6394
6646
|
mesh.frustumCulled = false;
|
|
6395
6647
|
group.add(mesh);
|
|
6396
6648
|
meshes.push(mesh);
|
|
@@ -6445,11 +6697,11 @@ function TendonRenderer(props) {
|
|
|
6445
6697
|
if (curve.points.length !== validCount) {
|
|
6446
6698
|
curve.points.length = validCount;
|
|
6447
6699
|
while (curve.points.length < validCount) {
|
|
6448
|
-
curve.points.push(new
|
|
6700
|
+
curve.points.push(new THREE13.Vector3());
|
|
6449
6701
|
}
|
|
6450
6702
|
}
|
|
6451
6703
|
mesh.geometry.dispose();
|
|
6452
|
-
mesh.geometry = new
|
|
6704
|
+
mesh.geometry = new THREE13.TubeGeometry(
|
|
6453
6705
|
curve,
|
|
6454
6706
|
Math.max(validCount * 2, 4),
|
|
6455
6707
|
DEFAULT_TENDON_WIDTH,
|
|
@@ -6496,14 +6748,14 @@ function FlexRenderer(props) {
|
|
|
6496
6748
|
const vertAdr = model.flex_vertadr[f];
|
|
6497
6749
|
const vertNum = model.flex_vertnum[f];
|
|
6498
6750
|
if (vertNum === 0) continue;
|
|
6499
|
-
const geometry = new
|
|
6751
|
+
const geometry = new THREE13.BufferGeometry();
|
|
6500
6752
|
const positions = new Float32Array(vertNum * 3);
|
|
6501
|
-
geometry.setAttribute("position", new
|
|
6753
|
+
geometry.setAttribute("position", new THREE13.BufferAttribute(positions, 3));
|
|
6502
6754
|
const topology = getFlexTopology(model, f);
|
|
6503
6755
|
if (topology.indices.length) geometry.setIndex(topology.indices);
|
|
6504
|
-
let color = new
|
|
6756
|
+
let color = new THREE13.Color(0.5, 0.5, 0.5);
|
|
6505
6757
|
if (model.flex_rgba) {
|
|
6506
|
-
color = new
|
|
6758
|
+
color = new THREE13.Color(
|
|
6507
6759
|
model.flex_rgba[4 * f],
|
|
6508
6760
|
model.flex_rgba[4 * f + 1],
|
|
6509
6761
|
model.flex_rgba[4 * f + 2]
|
|
@@ -6511,7 +6763,7 @@ function FlexRenderer(props) {
|
|
|
6511
6763
|
}
|
|
6512
6764
|
const opacity = model.flex_rgba[4 * f + 3];
|
|
6513
6765
|
const materialOptions = { color, opacity, transparent: opacity < 1 };
|
|
6514
|
-
const mesh = topology.kind === "mesh" ? new
|
|
6766
|
+
const mesh = topology.kind === "mesh" ? new THREE13.Mesh(geometry, new THREE13.MeshStandardMaterial({ ...materialOptions, roughness: 0.7, side: THREE13.DoubleSide })) : topology.kind === "lines" ? new THREE13.LineSegments(geometry, new THREE13.LineBasicMaterial(materialOptions)) : new THREE13.Points(geometry, new THREE13.PointsMaterial({ ...materialOptions, size: 0.01 }));
|
|
6515
6767
|
mesh.frustumCulled = false;
|
|
6516
6768
|
mesh.userData.flexId = f;
|
|
6517
6769
|
mesh.userData.vertAdr = vertAdr;
|
|
@@ -6541,14 +6793,14 @@ function FlexRenderer(props) {
|
|
|
6541
6793
|
posAttr.setXYZ(v, data.flexvert_xpos[srcIdx], data.flexvert_xpos[srcIdx + 1], data.flexvert_xpos[srcIdx + 2]);
|
|
6542
6794
|
}
|
|
6543
6795
|
posAttr.needsUpdate = true;
|
|
6544
|
-
if (mesh instanceof
|
|
6796
|
+
if (mesh instanceof THREE13.Mesh) mesh.geometry.computeVertexNormals();
|
|
6545
6797
|
}
|
|
6546
6798
|
});
|
|
6547
6799
|
if (status !== "ready") return null;
|
|
6548
6800
|
return /* @__PURE__ */ jsx("group", { ...props, ref: groupRef });
|
|
6549
6801
|
}
|
|
6550
6802
|
var GEOM_TYPE_NAMES2 = ["plane", "hfield", "sphere", "capsule", "ellipsoid", "cylinder", "box", "mesh"];
|
|
6551
|
-
var _matrix = new
|
|
6803
|
+
var _matrix = new THREE13.Matrix4();
|
|
6552
6804
|
function getGeomInfo(model, geomId) {
|
|
6553
6805
|
const size = model.geom_size.subarray(geomId * 3, geomId * 3 + 3);
|
|
6554
6806
|
const type = model.geom_type[geomId];
|
|
@@ -6570,10 +6822,10 @@ function geomSignature(model, geomId) {
|
|
|
6570
6822
|
return [type, size, mat, data, rgba].join("|");
|
|
6571
6823
|
}
|
|
6572
6824
|
function firstMesh(object) {
|
|
6573
|
-
if (object instanceof
|
|
6825
|
+
if (object instanceof THREE13.Mesh) return object;
|
|
6574
6826
|
let mesh = null;
|
|
6575
6827
|
object.traverse((child) => {
|
|
6576
|
-
if (!mesh && child instanceof
|
|
6828
|
+
if (!mesh && child instanceof THREE13.Mesh) mesh = child;
|
|
6577
6829
|
});
|
|
6578
6830
|
return mesh;
|
|
6579
6831
|
}
|
|
@@ -6994,12 +7246,12 @@ function useActuators() {
|
|
|
6994
7246
|
return actuators;
|
|
6995
7247
|
}, [status, mjModelRef]);
|
|
6996
7248
|
}
|
|
6997
|
-
var _mat42 = new
|
|
7249
|
+
var _mat42 = new THREE13.Matrix4();
|
|
6998
7250
|
function useSitePosition(siteName) {
|
|
6999
7251
|
const { mjModelRef, mjDataRef, status } = useMujocoContext();
|
|
7000
7252
|
const siteIdRef = useRef(-1);
|
|
7001
|
-
const positionRef = useRef(new
|
|
7002
|
-
const quaternionRef = useRef(new
|
|
7253
|
+
const positionRef = useRef(new THREE13.Vector3());
|
|
7254
|
+
const quaternionRef = useRef(new THREE13.Quaternion());
|
|
7003
7255
|
useEffect(() => {
|
|
7004
7256
|
const model = mjModelRef.current;
|
|
7005
7257
|
if (!model || status !== "ready") {
|
|
@@ -7192,10 +7444,10 @@ function useJointState(name, options = {}) {
|
|
|
7192
7444
|
function useBodyState(name) {
|
|
7193
7445
|
const { mjModelRef, status } = useMujocoContext();
|
|
7194
7446
|
const bodyIdRef = useRef(-1);
|
|
7195
|
-
const position = useRef(new
|
|
7196
|
-
const quaternion = useRef(new
|
|
7197
|
-
const linearVelocity = useRef(new
|
|
7198
|
-
const angularVelocity = useRef(new
|
|
7447
|
+
const position = useRef(new THREE13.Vector3());
|
|
7448
|
+
const quaternion = useRef(new THREE13.Quaternion());
|
|
7449
|
+
const linearVelocity = useRef(new THREE13.Vector3());
|
|
7450
|
+
const angularVelocity = useRef(new THREE13.Vector3());
|
|
7199
7451
|
useEffect(() => {
|
|
7200
7452
|
const model = mjModelRef.current;
|
|
7201
7453
|
if (!model || status !== "ready") return;
|
|
@@ -7221,7 +7473,7 @@ function useBodyState(name) {
|
|
|
7221
7473
|
});
|
|
7222
7474
|
return { position, quaternion, linearVelocity, angularVelocity };
|
|
7223
7475
|
}
|
|
7224
|
-
var _matrix2 = new
|
|
7476
|
+
var _matrix2 = new THREE13.Matrix4();
|
|
7225
7477
|
function quaternionFromMatrixArray(target, values, offset) {
|
|
7226
7478
|
_matrix2.set(
|
|
7227
7479
|
values[offset],
|
|
@@ -7255,8 +7507,8 @@ function useNamedPose(kind, name) {
|
|
|
7255
7507
|
const { mjModelRef, status } = useMujocoContext();
|
|
7256
7508
|
const idRef = useRef(-1);
|
|
7257
7509
|
const foundRef = useRef(false);
|
|
7258
|
-
const positionRef = useRef(new
|
|
7259
|
-
const quaternionRef = useRef(new
|
|
7510
|
+
const positionRef = useRef(new THREE13.Vector3());
|
|
7511
|
+
const quaternionRef = useRef(new THREE13.Quaternion());
|
|
7260
7512
|
useEffect(() => {
|
|
7261
7513
|
const model = mjModelRef.current;
|
|
7262
7514
|
if (!model || status !== "ready") {
|
|
@@ -7750,9 +8002,9 @@ function useKeyboardTeleop(config) {
|
|
|
7750
8002
|
}
|
|
7751
8003
|
var DEFAULT_TRANSLATE_SPEED = 0.25;
|
|
7752
8004
|
var DEFAULT_ROTATE_SPEED = 1;
|
|
7753
|
-
var _translation = new
|
|
7754
|
-
var _axis = new
|
|
7755
|
-
var _quat3 = new
|
|
8005
|
+
var _translation = new THREE13.Vector3();
|
|
8006
|
+
var _axis = new THREE13.Vector3();
|
|
8007
|
+
var _quat3 = new THREE13.Quaternion();
|
|
7756
8008
|
function actionSign(action) {
|
|
7757
8009
|
return action.endsWith("+") ? 1 : -1;
|
|
7758
8010
|
}
|
|
@@ -9127,7 +9379,7 @@ function useSelectionHighlight(bodyId, options = {}) {
|
|
|
9127
9379
|
}
|
|
9128
9380
|
}
|
|
9129
9381
|
prevRef.current = [];
|
|
9130
|
-
const highlightColor = new
|
|
9382
|
+
const highlightColor = new THREE13.Color(color);
|
|
9131
9383
|
for (const mesh of meshes) {
|
|
9132
9384
|
const mat = mesh.material;
|
|
9133
9385
|
if (mat.emissive) {
|
|
@@ -9154,15 +9406,15 @@ function useSelectionHighlight(bodyId, options = {}) {
|
|
|
9154
9406
|
}
|
|
9155
9407
|
function useCameraAnimation() {
|
|
9156
9408
|
const { camera } = useThree();
|
|
9157
|
-
const orbitTargetRef = useRef(new
|
|
9409
|
+
const orbitTargetRef = useRef(new THREE13.Vector3(0, 0, 0));
|
|
9158
9410
|
const cameraAnimRef = useRef({
|
|
9159
9411
|
active: false,
|
|
9160
|
-
startPos: new
|
|
9161
|
-
endPos: new
|
|
9162
|
-
startRot: new
|
|
9163
|
-
endRot: new
|
|
9164
|
-
startTarget: new
|
|
9165
|
-
endTarget: new
|
|
9412
|
+
startPos: new THREE13.Vector3(),
|
|
9413
|
+
endPos: new THREE13.Vector3(),
|
|
9414
|
+
startRot: new THREE13.Quaternion(),
|
|
9415
|
+
endRot: new THREE13.Quaternion(),
|
|
9416
|
+
startTarget: new THREE13.Vector3(),
|
|
9417
|
+
endTarget: new THREE13.Vector3(),
|
|
9166
9418
|
startTime: 0,
|
|
9167
9419
|
duration: 0,
|
|
9168
9420
|
resolve: null
|
|
@@ -9236,6 +9488,7 @@ function useCameraAnimation() {
|
|
|
9236
9488
|
*
|
|
9237
9489
|
* Helpers for turning Three/MuJoCo camera captures into policy image payloads.
|
|
9238
9490
|
*/
|
|
9491
|
+
/** @license SPDX-License-Identifier: Apache-2.0 */
|
|
9239
9492
|
/**
|
|
9240
9493
|
* @license
|
|
9241
9494
|
* SPDX-License-Identifier: Apache-2.0
|