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