26bb5634bd
web-platform-ci / Standalone decision service (no cloud credentials) (push) Waiting to run
web-platform-ci / TypeScript, lint, unit, build (push) Waiting to run
web-platform-ci / Playwright E2E (push) Waiting to run
lekiwi-compatibility / cpu-compatibility (push) Waiting to run
73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
import type * as THREE from 'three';
|
|
import type { MjvGeom } from '@mujoco/mujoco';
|
|
|
|
/** 更新既有网格展示,不创建/缓存/释放任何 Three.js 或 MuJoCo 资源。 */
|
|
export function updateMeshPresentation(
|
|
mesh: THREE.Mesh,
|
|
g: MjvGeom,
|
|
{ geomId, bodyId, isCollision }: { geomId: number; bodyId: number; isCollision: boolean },
|
|
): void {
|
|
const mat = mesh.material as THREE.MeshStandardMaterial;
|
|
if (isCollision) {
|
|
const worldCollision = bodyId === 0;
|
|
mat.color.setHex(worldCollision ? 0x64748b : 0x22d3ee);
|
|
mat.opacity = worldCollision ? 0.12 : 0.28;
|
|
mat.transparent = true;
|
|
mat.depthTest = worldCollision;
|
|
mat.depthWrite = false;
|
|
mat.roughness = 0.85;
|
|
mat.metalness = 0;
|
|
mesh.renderOrder = worldCollision ? 0 : 60;
|
|
} else {
|
|
mat.color.setRGB(g.rgba[0], g.rgba[1], g.rgba[2]);
|
|
mat.opacity = g.rgba[3];
|
|
mat.transparent = g.rgba[3] < 1;
|
|
mat.depthTest = true;
|
|
mat.depthWrite = true;
|
|
mat.roughness = Math.max(0.05, 1 - g.shininess);
|
|
mat.metalness = g.reflectance;
|
|
mesh.renderOrder = 0;
|
|
}
|
|
mesh.matrix.set(
|
|
g.mat[0],
|
|
g.mat[1],
|
|
g.mat[2],
|
|
g.pos[0],
|
|
g.mat[3],
|
|
g.mat[4],
|
|
g.mat[5],
|
|
g.pos[1],
|
|
g.mat[6],
|
|
g.mat[7],
|
|
g.mat[8],
|
|
g.pos[2],
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
);
|
|
mesh.matrixWorldNeedsUpdate = true;
|
|
mesh.userData.geomId = geomId;
|
|
mesh.userData.bodyId = bodyId;
|
|
mesh.userData.geomType = g.type;
|
|
mesh.userData.isCollision = isCollision;
|
|
}
|
|
|
|
export function applyMeshHighlight(
|
|
mesh: THREE.Mesh,
|
|
selected: THREE.Mesh | null,
|
|
highlightedBodyId: number,
|
|
): void {
|
|
const material = mesh.material as THREE.MeshStandardMaterial;
|
|
if (Number(mesh.userData.bodyId) === highlightedBodyId) {
|
|
material.emissive.setHex(0x8a6d00);
|
|
material.emissiveIntensity = 0.85;
|
|
} else if (mesh === selected) {
|
|
material.emissive.setHex(0x14532d);
|
|
material.emissiveIntensity = 1;
|
|
} else {
|
|
material.emissive.setHex(0);
|
|
material.emissiveIntensity = 1;
|
|
}
|
|
}
|