Browse Source

Merge remote-tracking branch 'origin/master'

master
修宁 6 months ago
parent
commit
fab377e56a
  1. 16
      src/components/Model3DView.vue
  2. 423
      src/modules/rack/RackRenderer.ts

16
src/components/Model3DView.vue

@ -575,9 +575,9 @@ function createGroundStore() {
alphaMap: texture1, //
normalMap: texture2, //
// side: THREE.DoubleSide //
metalness: 0.6,
roughness: 0.8,
specular: 0x6d6d6d,
// metalness: 0.6,
// roughness: 0.8,
// specular: 0x6d6d6d,
transparent: true,
needsUpdate: true,
});
@ -587,7 +587,7 @@ function createGroundStore() {
// const material1 = new THREE.MeshBasicMaterial({ color: 0xff0000 });
// const mesh1 = new THREE.Mesh(geometry1, material1);
let mesh = new THREE.InstancedMesh(geometry1, material1, 160000);
let mesh = new THREE.InstancedMesh(geometry1, material1, 1600);
mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
mesh.castShadow = true;
mesh.receiveShadow = true;
@ -595,11 +595,11 @@ function createGroundStore() {
let dummy = new THREE.Object3D();
for (let i = 0; i < 400; i++) {
for (let j = 0; j < 400; j++) {
dummy.position.set(i * 0.1, 0, j * 0.2);
for (let i = 0; i < 40; i++) {
for (let j = 0; j < 40; j++) {
dummy.position.set(i * 0.5, 0, j * 0.5);
dummy.updateMatrix();
mesh.setMatrixAt(i*400 + j, dummy.matrix);
mesh.setMatrixAt(i*40 + j, dummy.matrix);
}
}

423
src/modules/rack/RackRenderer.ts

@ -7,6 +7,9 @@ import { decimalSumBy } from '@/core/ModelUtils'
import Constract from '@/core/Constract.ts'
import Plastic_Rough_JPG from '@/assets/Models/Plastic_Rough.jpg'
import {BufferGeometry} from "three";
import storageBar_PNG from "@/assets/Models/storageBar.png";
import {Material} from "three/src/materials/Material";
import {InstancedMesh} from "three/src/objects/InstancedMesh";
/**
*
@ -65,69 +68,75 @@ export default class RackRenderer extends BaseRenderer {
const group = new THREE.Group()
group.name = RackRenderer.POINT_NAME
const rackWidth = decimalSumBy(item.dt.bays, (b: any) => b.bayWidth)
const heights = []
for (let i = 0; i < item.dt.bays.length; i++) {
const bay = item.dt.bays[i]
const bayHeight = decimalSumBy(bay.levelHeight)
heights.push(bayHeight)
}
const rackHeight = _.max(heights)
// 绘制背景矩形框
const planeGeometry = new THREE.PlaneGeometry(rackWidth, item.dt.rackDepth)
// const rackWidth = decimalSumBy(item.dt.bays, (b: any) => b.bayWidth)
// const heights = []
// for (let i = 0; i < item.dt.bays.length; i++) {
// const bay = item.dt.bays[i]
// const bayHeight = decimalSumBy(bay.levelHeight)
// heights.push(bayHeight)
// }
// const rackHeight = _.max(heights)
// // 绘制背景矩形框
// const planeGeometry = new THREE.PlaneGeometry(rackWidth, item.dt.rackDepth)
//
// planeGeometry.rotateX(Math.PI / 2)
//
// const planeMaterial = new THREE.MeshBasicMaterial({
// color: '#9a9090',
// transparent: true, // 启用透明
// opacity: 0.5, // 50%透明度
// depthWrite: false, // 防止深度冲突
// side: THREE.DoubleSide // 双面渲染:ml-citation{ref="5,8" data="citationList"}
// })
// const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial)
// group.add(planeMesh)
//
//
// // 绘制边框
// const lineXLen = rackWidth - this.defaultLineWidth
// const lineYLen = item.dt.rackDepth - this.defaultLineWidth
//
// const lineGeometry = new LineGeometry().setPositions([
// -(lineXLen / 2), 0, -(lineYLen / 2),
// lineXLen / 2, 0, -(lineYLen / 2),
// lineXLen / 2, 0, lineYLen / 2,
// -(lineXLen / 2), 0, lineYLen / 2,
// -(lineXLen / 2), 0, -(lineYLen / 2)
// ])
// const lineMaterial = new LineMaterial({
// color: '#0d89a5',
// linewidth: this.defaultLineWidth,
// worldUnits: true,
// resolution: new THREE.Vector2(window.innerWidth, window.innerHeight),
// side: THREE.DoubleSide
// })
// const line = new Line2(lineGeometry, lineMaterial)
// group.add(line as THREE.Object3D)
//
// let lineDistanceX = 0
//
// for (let i = 0; item.dt.bays.length > 1 && i < item.dt.bays.length - 1; i++) {
// const bay = item.dt.bays[i]
// lineDistanceX += bay.bayWidth
// const lineGeometryT = new LineGeometry().setPositions([
// -(lineDistanceX) + (lineXLen / 2), 0, lineYLen / 2,
// -(lineDistanceX) + (lineXLen / 2), 0, -(lineYLen / 2)
// ])
// const lineT = new Line2(lineGeometryT, lineMaterial)
// group.add(lineT as THREE.Object3D)
// }
planeGeometry.rotateX(Math.PI / 2)
const meshes = this.createRack(item, option);
const planeMaterial = new THREE.MeshBasicMaterial({
color: '#9a9090',
transparent: true, // 启用透明
opacity: 0.5, // 50%透明度
depthWrite: false, // 防止深度冲突
side: THREE.DoubleSide // 双面渲染:ml-citation{ref="5,8" data="citationList"}
})
const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial)
group.add(planeMesh)
// 绘制边框
const lineXLen = rackWidth - this.defaultLineWidth
const lineYLen = item.dt.rackDepth - this.defaultLineWidth
const lineGeometry = new LineGeometry().setPositions([
-(lineXLen / 2), 0, -(lineYLen / 2),
lineXLen / 2, 0, -(lineYLen / 2),
lineXLen / 2, 0, lineYLen / 2,
-(lineXLen / 2), 0, lineYLen / 2,
-(lineXLen / 2), 0, -(lineYLen / 2)
])
const lineMaterial = new LineMaterial({
color: '#0d89a5',
linewidth: this.defaultLineWidth,
worldUnits: true,
resolution: new THREE.Vector2(window.innerWidth, window.innerHeight),
side: THREE.DoubleSide
meshes.forEach(mesh => {
group.add(mesh)
})
const line = new Line2(lineGeometry, lineMaterial)
group.add(line as THREE.Object3D)
let lineDistanceX = 0
for (let i = 0; item.dt.bays.length > 1 && i < item.dt.bays.length - 1; i++) {
const bay = item.dt.bays[i]
lineDistanceX += bay.bayWidth
const lineGeometryT = new LineGeometry().setPositions([
-(lineDistanceX) + (lineXLen / 2), 0, lineYLen / 2,
-(lineDistanceX) + (lineXLen / 2), 0, -(lineYLen / 2)
])
const lineT = new Line2(lineGeometryT, lineMaterial)
group.add(lineT as THREE.Object3D)
}
// 设置位置
group.position.set(item.tf[0][0], item.tf[0][1], item.tf[0][2])
item.dt.rackWidth = rackWidth
item.dt.rackHeight = rackHeight
// group.position.set(item.tf[0][0], item.tf[0][1], item.tf[0][2])
//
// item.dt.rackWidth = rackWidth
// item.dt.rackHeight = rackHeight
return group
}
@ -144,9 +153,305 @@ export default class RackRenderer extends BaseRenderer {
rackVerticalBarDepth = 0.08
rackVerticalBarColor = 0xFF35499C
rackVerticalBarGeometry: BufferGeometry = null
rackVerticalBarMaterial: Material = null
rackHorizontalBarWidth = 0.1
rackHorizontalBarDepth = 0.08
rackHorizontalBarColor = 0xFFF97F27
rackHorizontalBarGeometry: BufferGeometry = null
rackHorizontalBarMaterial: Material = null
sectionPoints = [
{x: -0.05, y: -0.05},
{x: -0.025, y: -0.05},
{x: 0.04-0.05, y: 0.005-0.05},
{x: 0.06-0.05, y: 0.005-0.05},
{x: 0.075-0.05, y: 0-0.05},
{x: 0.1-0.05, y: 0-0.05},
{x: 0.1-0.05, y: 0.092-0.05},
{x: 0.092-0.05, y: 0.1-0.05},
{x: 0.075-0.05, y: 0.1-0.05},
{x: 0.075-0.05, y: 0.092-0.05},
{x: 0.092-0.05, y: 0.092-0.05},
{x: 0.092-0.05, y: 0.008-0.05},
{x: 0.008-0.05, y: 0.008-0.05},
{x: 0.008-0.05, y: 0.092-0.05},
{x: 0.025-0.05, y: 0.092-0.05},
{x: 0.025-0.05, y: 0.1-0.05},
{x: 0.008-0.05, y: 0.1-0.05},
{x: 0-0.05, y: 0.092-0.05},
{x: 0-0.05, y: 0-0.05}
]
createVerticalBar(x, y, z, length): THREE.BufferGeometry {
// 创建一个形状 柱子的截面形状
const shape = new THREE.Shape();
shape.moveTo(this.sectionPoints[0].x, this.sectionPoints[0].y);
for (let i = 1; i < this.sectionPoints.length; i++) {
shape.lineTo(this.sectionPoints[i].x , this.sectionPoints[i].y);
}
// 拉伸轨迹线
const curve = new THREE.CatmullRomCurve3(
[new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, length, 0)],
false, // 闭合曲线
'catmullrom',
0
);
// 挤出几何图形 参数
const options = {
steps: 1,
bevelEnabled: false,
extrudePath: curve, // 设置挤出轨迹
};
// 创建挤出几何体
const geometry = new THREE.ExtrudeGeometry(shape, options);
// 调整uv方便正确贴图
this.resetUVs(geometry);
return geometry
}
createVerticalBarMaterial(): THREE.Material {
let textureLoader = new THREE.TextureLoader()
// 加载纹理
const textureHole = textureLoader.load(storageBar_PNG); // 孔洞
const textureMaterial = textureLoader.load(Plastic_Rough_JPG); // 表面材质
textureHole.repeat.set(10, 18); // X轴重复,Y轴重复
textureMaterial.repeat.set(2, 2); // X轴重复,Y轴重复
// textureHole.offset.set(0.5, 0)
// textureHole.center.set(0.5, 0)
// 必须设置包裹模式为重复
textureHole.wrapS = THREE.RepeatWrapping;
textureHole.wrapT = THREE.RepeatWrapping;
textureMaterial.wrapS = THREE.RepeatWrapping;
textureMaterial.wrapT = THREE.RepeatWrapping;
const material = new THREE.MeshPhongMaterial();
material.alphaMap = textureHole;
material.normalMap = textureMaterial;
material.color.setHex(this.rackVerticalBarColor, "srgb");
material.specular.setHex(0xff6d6d6d, 'srgb');
material.transparent = true;
material.needsUpdate = true;
return material;
}
createHorizontalBar(x, y, z, length): THREE.BufferGeometry {
// 创建一个形状 柱子的截面形状
const shape = new THREE.Shape();
shape.moveTo(this.sectionPoints[0].x, this.sectionPoints[0].y);
for (let i = 1; i < this.sectionPoints.length; i++) {
shape.lineTo(this.sectionPoints[i].x , this.sectionPoints[i].y);
}
// 拉伸轨迹线
const curve = new THREE.CatmullRomCurve3(
[new THREE.Vector3(0, 0, 0), new THREE.Vector3(length, 0, 0)],
false, // 闭合曲线
'catmullrom',
0
);
// 挤出几何图形 参数
const options = {
steps: 1,
bevelEnabled: false,
extrudePath: curve, // 设置挤出轨迹
};
// 创建挤出几何体
const geometry = new THREE.ExtrudeGeometry(shape, options);
// 调整uv方便正确贴图
this.resetUVs(geometry);
return geometry
}
createHorizontalBarMaterial(): THREE.Material {
const material = new THREE.MeshPhongMaterial();
material.color.setHex(this.rackHorizontalBarColor, "srgb");
material.specular.setHex(0xff6d6d6d, 'srgb');
material.transparent = true;
material.needsUpdate = true;
return material;
}
createRack(item: ItemJson, option?: RendererCudOption): InstancedMesh[] {
if (!item.dt.bays || !item.dt.rackDepth) {
system.showErrorDialog('RackRenderer field bays / rackDepth is null!')
return null
}
const rackPoint = {
x: item.tf[0][0],
y: item.tf[0][1],
z: item.tf[0][2]
}
const heights = []
for (let i = 0; i < item.dt.bays.length; i++) {
const bay = item.dt.bays[i]
const bayHeight = decimalSumBy(bay.levelHeight)
heights.push(bayHeight)
}
const rackHeight = _.max(heights)
createVerticalBar(x, y, z, length) {
// 计算立住坐标点和长度
const vBarMatrix: {x: number, y: number, z: number, sx: number, sy: number, sz: number, rx: number, ry: number, rz: number, l: number}[] = [];
let distanceX = 0, distanceY = 0;
for (let i = -1; i < item.dt.bays.length; i++) {
if (i >= 0) {
const bay = item.dt.bays[i]
distanceX += bay.bayWidth
}
vBarMatrix.push({
x: rackPoint.x + distanceX,
y: rackPoint.y,
z: rackPoint.z,
sx: 0.8,
sy: 1,
sz: 1,
rx: 0,
ry: Math.PI/2,
rz: 0,
l: rackHeight
})
vBarMatrix.push({
x: rackPoint.x + distanceX,
y: rackPoint.y,
z: rackPoint.z + item.dt.rackDepth,
sx: 0.8,
sy: 1,
sz: 1,
rx: 0,
ry: -Math.PI/2,
rz: 0,
l: rackHeight
})
}
// 计算横梁数量
const hBarMatrix: {x: number, y: number, z: number, sx: number, sy: number, sz: number, rx: number, ry: number, rz: number, l: number}[] = [];
distanceX = 0;
for (let i = 0; i < item.dt.bays.length; i++) {
distanceY = 0;
const bay = item.dt.bays[i]
for (let j = 0; j < bay.levelHeight.length; j++) {
const levelHeight = bay.levelHeight[j]
hBarMatrix.push({
x: rackPoint.x + distanceX,
y: rackPoint.y + distanceY,
z: rackPoint.z,
sx: 1,
sy: 0.8,
sz: 1,
rx: Math.PI/2,
ry: 0,
rz: 0,
l: bay.bayWidth
})
hBarMatrix.push({
x: rackPoint.x + distanceX,
y: rackPoint.y + distanceY,
z: rackPoint.z + item.dt.rackDepth,
sx: 1,
sy: 0.8,
sz: 1,
rx: -Math.PI/2,
ry: 0,
rz: 0,
l: bay.bayWidth
})
distanceY += levelHeight
}
distanceX += bay.bayWidth
}
const meshes: InstancedMesh[] = [];
if (vBarMatrix.length > 0) {
if (!this.rackVerticalBarGeometry) {
this.rackVerticalBarGeometry = this.createVerticalBar(vBarMatrix[0].x, vBarMatrix[0].y, vBarMatrix[0].z, vBarMatrix[0].l)
}
if (!this.rackVerticalBarMaterial) {
this.rackVerticalBarMaterial = this.createVerticalBarMaterial()
}
const dummy = new THREE.Object3D();
const vBarMesh = new THREE.InstancedMesh(this.rackVerticalBarGeometry, this.rackVerticalBarMaterial, vBarMatrix.length);
for (let i = 0; i < vBarMatrix.length; i++) {
const vp = vBarMatrix[i]
dummy.position.set(vp.x, vp.y, vp.z);
dummy.rotation.set(vp.rx, vp.ry, vp.rz);
dummy.scale.set(vp.sx, vp.sy, vp.sz);
dummy.updateMatrix();
vBarMesh.setMatrixAt(i, dummy.matrix);
}
meshes.push(vBarMesh)
}
if (hBarMatrix.length > 0) {
if (!this.rackHorizontalBarGeometry) {
this.rackHorizontalBarGeometry = this.createHorizontalBar(hBarMatrix[0].x, hBarMatrix[0].y, hBarMatrix[0].z, hBarMatrix[0].l)
}
if (!this.rackHorizontalBarMaterial) {
this.rackHorizontalBarMaterial = this.createHorizontalBarMaterial()
}
const dummy = new THREE.Object3D();
const hBarMesh = new THREE.InstancedMesh(this.rackHorizontalBarGeometry, this.rackHorizontalBarMaterial, hBarMatrix.length);
for (let i = 0; i < hBarMatrix.length; i++) {
const hp = hBarMatrix[i]
dummy.position.set(hp.x, hp.y, hp.z);
dummy.rotation.set(hp.rx, hp.ry, hp.rz);
dummy.scale.set(hp.sx, hp.sy, hp.sz);
dummy.updateMatrix();
hBarMesh.setMatrixAt(i, dummy.matrix);
}
meshes.push(hBarMesh)
}
return meshes;
}
resetUVs(geometry) {
if (geometry == undefined) return;
const pos = geometry.getAttribute("position"),
nor = geometry.getAttribute("normal"),
uvs = geometry.getAttribute("uv");
for (let i = 0; i < pos.count; i++) {
let x = 0, y = 0;
const nx = Math.abs(nor.getX(i)), ny = Math.abs(nor.getY(i)), nz = Math.abs(nor.getZ(i));
// if facing X
if (nx >= ny && nx >= nz) {
x = pos.getZ(i);
y = pos.getY(i);
}
// if facing Y
if (ny >= nx && ny >= nz) {
x = pos.getX(i);
y = pos.getZ(i);
}
// if facing Z
if (nz >= nx && nz >= ny) {
x = pos.getX(i);
y = pos.getY(i);
}
uvs.setXY(i, x, y);
}
}
}

Loading…
Cancel
Save