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:
@@ -1,4 +1,5 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import DeviceModel from './DeviceModel';
|
||||
import LODManager, { LOD_LEVELS } from './LODManager';
|
||||
|
||||
@@ -49,6 +50,96 @@ const RackModel = ({
|
||||
return colors.default;
|
||||
};
|
||||
|
||||
// 设备组的Y偏移量(与下方设备渲染的偏移一致)
|
||||
const deviceGroupOffset = 0.1;
|
||||
|
||||
// 生成U位刻度标识 - 写在机柜左右两侧柱子上
|
||||
const uLabels = useMemo(() => {
|
||||
const labels = [];
|
||||
// 每一个U位都显示数字,从底部开始(U1在底部)
|
||||
for (let u = 1; u <= rackHeight; u += 1) {
|
||||
// 计算U位标识的Y坐标,需要加上设备组的偏移量
|
||||
const yPos = (u - 1) * uHeight + uHeight / 2 + deviceGroupOffset;
|
||||
|
||||
// 创建数字纹理 - 白色数字在深色背景上更清晰
|
||||
const createNumberTexture = (num) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 128;
|
||||
canvas.height = 128;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 清除画布
|
||||
ctx.clearRect(0, 0, 128, 128);
|
||||
|
||||
// 绘制白色数字
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.font = 'bold 80px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillText(num.toString(), 64, 64);
|
||||
|
||||
return new THREE.CanvasTexture(canvas);
|
||||
};
|
||||
|
||||
const leftTexture = createNumberTexture(u);
|
||||
const rightTexture = createNumberTexture(u);
|
||||
|
||||
// 创建平面几何体显示数字 - 每5U使用稍大的尺寸
|
||||
const isMajorU = u % 5 === 0;
|
||||
const planeSize = isMajorU ? 0.035 : 0.025;
|
||||
const planeGeometry = new THREE.PlaneGeometry(planeSize, planeSize);
|
||||
|
||||
// 前侧柱子的位置: [-width/2 + postWidth/2, y, depth/2 - postWidth/2]
|
||||
const leftPostX = -width/2 + postWidth/2;
|
||||
const rightPostX = width/2 - postWidth/2;
|
||||
const frontPostZ = depth/2 - postWidth/2;
|
||||
|
||||
// 刻度线颜色:每5U使用醒目的黄色,其他使用灰色
|
||||
const tickColor = isMajorU ? '#fbbf24' : '#6b7280';
|
||||
const tickHeight = isMajorU ? 0.002 : 0.001;
|
||||
|
||||
labels.push(
|
||||
<group key={`u-label-${u}`}>
|
||||
{/* 左前侧柱子上的U位标识 - 贴在柱子正侧面(面向前方) */}
|
||||
<mesh
|
||||
position={[leftPostX, yPos, frontPostZ + postWidth/2 + 0.001]}
|
||||
geometry={planeGeometry}
|
||||
>
|
||||
<meshBasicMaterial
|
||||
map={leftTexture}
|
||||
transparent={true}
|
||||
opacity={1}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
{/* 右前侧柱子上的U位标识 - 贴在柱子正侧面(面向前方) */}
|
||||
<mesh
|
||||
position={[rightPostX, yPos, frontPostZ + postWidth/2 + 0.001]}
|
||||
geometry={planeGeometry}
|
||||
>
|
||||
<meshBasicMaterial
|
||||
map={rightTexture}
|
||||
transparent={true}
|
||||
opacity={1}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
{/* 左前侧柱子上的刻度线 */}
|
||||
<mesh position={[leftPostX, yPos, frontPostZ + postWidth/2 + 0.002]}>
|
||||
<boxGeometry args={[postWidth, tickHeight, 0.001]} />
|
||||
<meshBasicMaterial color={tickColor} />
|
||||
</mesh>
|
||||
{/* 右前侧柱子上的刻度线 */}
|
||||
<mesh position={[rightPostX, yPos, frontPostZ + postWidth/2 + 0.002]}>
|
||||
<boxGeometry args={[postWidth, tickHeight, 0.001]} />
|
||||
<meshBasicMaterial color={tickColor} />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
return labels;
|
||||
}, [rackHeight, uHeight, width, depth, deviceGroupOffset]);
|
||||
|
||||
// 生成机柜框架
|
||||
const frame = useMemo(() => {
|
||||
const materialProps = { color: "#333", roughness: 0.5, metalness: 0.8 };
|
||||
@@ -86,35 +177,21 @@ const RackModel = ({
|
||||
{[-1, 1].map((side) => (
|
||||
<mesh key={`side-${side}`} position={[side * (width/2 - 0.005), height/2, 0]}>
|
||||
<boxGeometry args={[0.01, height - 0.04, depth - 0.04]} />
|
||||
<meshStandardMaterial
|
||||
color="#2d3748"
|
||||
roughness={0.4}
|
||||
metalness={0.7}
|
||||
<meshStandardMaterial
|
||||
color="#2d3748"
|
||||
roughness={0.4}
|
||||
metalness={0.7}
|
||||
side={2}
|
||||
/>
|
||||
</mesh>
|
||||
))}
|
||||
|
||||
<mesh position={[0, height/2, -depth/2 + 0.005]}>
|
||||
<boxGeometry args={[width - 0.04, height - 0.04, 0.01]} />
|
||||
<meshPhysicalMaterial
|
||||
color="#e2e8f0"
|
||||
transparent
|
||||
opacity={0.2}
|
||||
roughness={0}
|
||||
metalness={0.9}
|
||||
transmission={0.8}
|
||||
thickness={0.01}
|
||||
/>
|
||||
<mesh position={[0.2, 0, 0.01]}>
|
||||
<boxGeometry args={[0.02, 0.15, 0.02]} />
|
||||
<meshStandardMaterial color="#333" />
|
||||
</mesh>
|
||||
</mesh>
|
||||
{/* U位刻度标识 */}
|
||||
{uLabels}
|
||||
|
||||
</group>
|
||||
);
|
||||
}, [width, height, depth, postWidth]);
|
||||
}, [width, height, depth, postWidth, uLabels]);
|
||||
|
||||
return (
|
||||
<group position={[0, 0.5, 0]}>
|
||||
|
||||
Reference in New Issue
Block a user