You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

165 lines
4.8 KiB

import * as THREE from 'three'
import BaseRenderer from '@/core/base/BaseRenderer.ts'
import Constract from '@/core/Constract.ts'
import { type Object3DLike } from '@/types/ModelTypes.ts'
import { getMatrixFromTf } from '@/core/ModelUtils.ts'
import InstanceMeshManager from '@/core/manager/InstanceMeshManager.ts'
/**
* 地堆货位渲染器
* 没有使用 InstanceMesh 目前性能不好
*/
export default class GstoreRenderer extends BaseRenderer {
static POINT_NAME = 'ground_store'
/**
* 默认点的高度, 防止和地面重合
*/
readonly defulePositionY: number = Constract.HEIGHT_GSTORE
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(1.5, 1.2, 0.1)
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(0, 0, 0)
readonly defaultLineWidth: number = 0.05
readonly defaultPointOption = {
weight: 0.1,
width: 1.5,
depth: 1.3,
strokeColor: 0x038217,
strokeWidth: 0.08
}
pointGeometry = new THREE.BoxGeometry(
1, 1, 1
).translate(0, 0.5, 0)
pointMaterial: THREE.Material = new THREE.MeshBasicMaterial({
color: 0xffffff,
transparent: true,
opacity: 0.5
})
strokeMaterial = new THREE.MeshBasicMaterial({
color: 0x038217,
// transparent: true,
// opacity: 0.2,
side: THREE.DoubleSide
})
strokeGeometry = new THREE.BoxGeometry(1, 1, 1)
createPointBasic(item: ItemJson, option?: RendererCudOption): Object3DLike {
return this.pointManager.createByItem(item)
}
createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D {
throw new Error('not allow store line.')
}
updateLine(start: ItemJson, end: ItemJson, type: LinkType, option?: RendererCudOption) {
throw new Error('not allow store line.')
}
/**
* 地堆位置发生变化后, 创建地堆货位标记
* @param item
* @param option
* @param object
*/
afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, object: Object3DLike) {
super.afterCreateOrUpdatePoint(item, option, object)
// 目标物体 matrix
const matrix = getMatrixFromTf(item.tf)
const depth = item.dt.strokeWidth || 0.2
// 从矩阵分解位置、旋转和缩放
const position = new THREE.Vector3()
const rotation = new THREE.Quaternion()
const scale = new THREE.Vector3()
matrix.decompose(position, rotation, scale)
// 计算半尺寸(考虑建筑物缩放)
const halfWidth = scale.x / 2
const halfHeight = scale.y / 2
const halfLength = scale.z / 2
const halfDepth = depth / 2
position.y = position.y + halfHeight
// 计算向内偏移量(确保墙完全包含在内部)
const insetX = halfWidth - halfDepth
const insetZ = halfLength - halfDepth
// 定义四面墙的参数:位置偏移和缩放(全部向内偏移)
const walls = [
// 前墙 (Z+方向)
{
offset: new THREE.Vector3(0, 0, insetZ),
scale: new THREE.Vector3(scale.x, scale.y, depth)
},
// 后墙 (Z-方向)
{
offset: new THREE.Vector3(0, 0, -insetZ),
scale: new THREE.Vector3(scale.x, scale.y, depth)
},
// 左墙 (X-方向)
{
offset: new THREE.Vector3(-insetX, 0, 0),
scale: new THREE.Vector3(depth, scale.y, scale.z - depth * 2)
},
// 右墙 (X+方向)
{
offset: new THREE.Vector3(insetX, 0, 0),
scale: new THREE.Vector3(depth, scale.y, scale.z - depth * 2)
}
]
// 为每面墙创建变换矩阵
const tempMatrix = new THREE.Matrix4()
const tempPosition = new THREE.Vector3()
const tempScale = new THREE.Vector3()
walls.forEach((wall, i) => {
tempPosition.copy(wall.offset).applyQuaternion(rotation).add(position)
tempScale.copy(wall.scale)
tempMatrix.compose(tempPosition, rotation, tempScale)
const wrap1 = this.wallManager.create(item.id + '_' + i, {})
wrap1.setMatrix4(tempMatrix)
})
}
dispose() {
super.dispose()
this.pointGeometry.dispose()
this.pointMaterial.dispose()
// this.strokeMaterial.dispose()
}
get pointManager(): InstanceMeshManager {
if (!this.tempViewport) {
throw new Error('tempViewport is not set.')
}
return this.tempViewport.getOrCreateMeshManager(this.itemTypeName, () =>
// 构建 InstanceMesh 代理对象
new InstanceMeshManager(this.itemTypeName,
this.tempViewport,
this.pointGeometry,
this.pointMaterial,
true, true)
)
}
get wallManager(): InstanceMeshManager {
if (!this.tempViewport) {
throw new Error('tempViewport is not set.')
}
const name = 'GS_WALL'
return this.tempViewport.getOrCreateMeshManager(name, () => {
// 构建 LineSegment.points 代理对象
return new InstanceMeshManager(name, this.tempViewport, this.strokeGeometry, this.strokeMaterial,
false, false)
})
}
}