feat(3d): 添加Scene3DContext优化3D场景状态管理
refactor(3d): 重构LODManager使用ref优化性能 feat(3d): 在RackModel中添加U位刻度标识 refactor(3d): 优化Scene组件相机控制和渲染设置 refactor(3d): 重构DeviceModel使用共享几何体和材质缓存 refactor(3d): 优化Rack3DVisualization使用Scene3DContext style(dashboard): 改进响应式布局和样式 perf(3d): 优化InstancedMesh性能减少内存占用
This commit is contained in:
@@ -80,7 +80,7 @@ const createMediumDeviceMesh = (device, uHeight, rackDepth, deviceColor, statusC
|
||||
</group>
|
||||
<group position={[0.05, 0, frontZ + 0.006]}>
|
||||
{Array.from({ length: is2U ? 4 : 2 }).map((_, i) => (
|
||||
<mesh key={i} position={[(i - 1) * 0.08, 0, 0]}>
|
||||
<mesh key={`drive-bay-${device.id || 'unknown'}-${i}`} position={[(i - 1) * 0.08, 0, 0]}>
|
||||
<boxGeometry args={[0.06, 0.03, 0.004]} />
|
||||
<meshStandardMaterial color="#334155" roughness={0.6} />
|
||||
</mesh>
|
||||
@@ -105,24 +105,56 @@ const LODManager = ({
|
||||
level = LOD_LEVELS.HIGH
|
||||
}) => {
|
||||
const groupRef = useRef();
|
||||
const highDetailRef = useRef();
|
||||
const mediumDetailRef = useRef();
|
||||
const lowDetailRef = useRef();
|
||||
const { camera } = useThree();
|
||||
const [lodLevel, setLodLevel] = React.useState(LOD_LEVELS.HIGH);
|
||||
// 使用 ref 存储 LOD 级别,避免 React 状态更新
|
||||
const lodLevelRef = useRef(LOD_LEVELS.HIGH);
|
||||
const distanceRef = useRef(0);
|
||||
// 帧计数器,用于节流
|
||||
const frameCount = useRef(0);
|
||||
// 用于强制重新渲染的 state(仅在必要时更新)
|
||||
const [, forceUpdate] = React.useReducer(x => x + 1, 0);
|
||||
|
||||
useFrame(() => {
|
||||
if (groupRef.current) {
|
||||
const distance = camera.position.distanceTo(groupRef.current.position);
|
||||
distanceRef.current = distance;
|
||||
|
||||
let newLevel = LOD_LEVELS.HIGH;
|
||||
if (distance > LOD_DISTANCES.MEDIUM) {
|
||||
newLevel = LOD_LEVELS.LOW;
|
||||
} else if (distance > LOD_DISTANCES.HIGH) {
|
||||
newLevel = LOD_LEVELS.MEDIUM;
|
||||
if (!groupRef.current) return;
|
||||
|
||||
// 节流:每5帧检查一次
|
||||
frameCount.current++;
|
||||
if (frameCount.current % 5 !== 0) return;
|
||||
|
||||
const distance = camera.position.distanceTo(groupRef.current.position);
|
||||
distanceRef.current = distance;
|
||||
|
||||
// 添加缓冲避免频繁切换(10% 缓冲)
|
||||
const buffer = 0.1;
|
||||
const highThreshold = LOD_DISTANCES.HIGH * (1 + buffer);
|
||||
const mediumThreshold = LOD_DISTANCES.MEDIUM * (1 + buffer);
|
||||
|
||||
let newLevel = LOD_LEVELS.HIGH;
|
||||
if (distance > mediumThreshold) {
|
||||
newLevel = LOD_LEVELS.LOW;
|
||||
} else if (distance > highThreshold) {
|
||||
newLevel = LOD_LEVELS.MEDIUM;
|
||||
}
|
||||
|
||||
// 只有当级别变化时才更新
|
||||
if (newLevel !== lodLevelRef.current) {
|
||||
lodLevelRef.current = newLevel;
|
||||
// 直接操作 ref 切换可见性,避免频繁的 React 重渲染
|
||||
if (highDetailRef.current) {
|
||||
highDetailRef.current.visible = newLevel === LOD_LEVELS.HIGH;
|
||||
}
|
||||
|
||||
if (newLevel !== lodLevel) {
|
||||
setLodLevel(newLevel);
|
||||
if (mediumDetailRef.current) {
|
||||
mediumDetailRef.current.visible = newLevel === LOD_LEVELS.MEDIUM;
|
||||
}
|
||||
if (lowDetailRef.current) {
|
||||
lowDetailRef.current.visible = newLevel === LOD_LEVELS.LOW;
|
||||
}
|
||||
// 偶尔强制更新以确保同步(每30帧)
|
||||
if (frameCount.current % 30 === 0) {
|
||||
forceUpdate();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -131,20 +163,22 @@ const LODManager = ({
|
||||
return children;
|
||||
}
|
||||
|
||||
const renderLODMesh = () => {
|
||||
switch (lodLevel) {
|
||||
case LOD_LEVELS.LOW:
|
||||
return createSimplifiedDeviceMesh(device, uHeight, rackDepth, deviceColor, statusColor);
|
||||
case LOD_LEVELS.MEDIUM:
|
||||
return createMediumDeviceMesh(device, uHeight, rackDepth, deviceColor, statusColor);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<group ref={groupRef} position={position}>
|
||||
{lodLevel === LOD_LEVELS.HIGH ? children : renderLODMesh()}
|
||||
{/* 高细节模型 - 默认显示 */}
|
||||
<group ref={highDetailRef} visible={true}>
|
||||
{children}
|
||||
</group>
|
||||
|
||||
{/* 中等细节模型 */}
|
||||
<group ref={mediumDetailRef} visible={false}>
|
||||
{createMediumDeviceMesh(device, uHeight, rackDepth, deviceColor, statusColor)}
|
||||
</group>
|
||||
|
||||
{/* 低细节模型 */}
|
||||
<group ref={lowDetailRef} visible={false}>
|
||||
{createSimplifiedDeviceMesh(device, uHeight, rackDepth, deviceColor, statusColor)}
|
||||
</group>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user