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; } }