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.
 
 
 

156 lines
5.4 KiB

import * as THREE from 'three'
import BaseRenderer from '@/core/base/BaseRenderer.ts'
import MoveLinePointPng from '@/assets/images/moveline_point.png'
import { getLineId, linkPlaneByPoint } from '@/core/ModelUtils.ts'
import Constract from '@/core/Constract.ts'
import InstancePointManager, { PointManageWrap } from '@/core/manager/InstancePointManager.ts'
import type { Object3DLike } from '@/types/ModelTypes.ts'
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial'
import LineSegmentManager from '@/core/manager/LineSegmentManager.ts'
/**
* AGV行走路线渲染器 point 是二维码站点
*/
export default class WayRenderer extends BaseRenderer {
static LABEL_NAME = 'way_label'
static POINT_NAME = 'way_point'
static LINE_NAME = 'way_line'
pointGeometry: THREE.BufferGeometry
pointMaterial: THREE.Material
// lineMaterial: LineMaterial = new LineMaterial({
// color: 0xa0cfff,
// linewidth: 0.8,
// vertexColors: false,
// dashed: false,
// gapSize: 0,
// worldUnits: true
// })
lineGeometry: THREE.BufferGeometry = new THREE.PlaneGeometry(1, 1).rotateX(-Math.PI / 2)
lineMaterial = new THREE.MeshBasicMaterial({
color: 0xa0cfff,
transparent: true,
opacity: 0.2,
side: THREE.DoubleSide
})
/**
* 默认点的高度, 防止和地面重合
*/
readonly defulePositionY: number = Constract.HEIGHT_WAY
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(0.5, 0.1, 0.5)
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(0, 0, 0)
readonly rendererOption = {
lineWidth: 0.8
}
async init() {
return Promise.all([
super.init(),
new THREE.TextureLoader().loadAsync(MoveLinePointPng)
]).then(([_, texture]) => {
texture.flipY = false
this.pointGeometry = new THREE.PlaneGeometry(1, 1).rotateX(-Math.PI / 2)
this.pointGeometry.center()
this.pointMaterial = new THREE.MeshBasicMaterial({
map: texture,
transparent: true,
depthWrite: false,
side: THREE.DoubleSide
})
this.pointMaterial.needsUpdate = true
})
}
createPointBasic(item: ItemJson, option?: RendererCudOption): Object3DLike {
// 不允许改变高度/角度/大小
item.tf = [
[item.tf[0][0], this.defulePositionY, item.tf[0][2]],
[this.defaultRotation.x, this.defaultRotation.y, this.defaultRotation.z],
[this.defaultScale.x, this.defaultScale.y, this.defaultScale.z]
]
return this.pointManager.createPoint(item)
}
createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): Object3DLike {
const lineId = getLineId(start.id, end.id, type)
// 用 PlaneGeometry 替代线段
const startPosition = new THREE.Vector3(start.tf[0][0], this.defulePositionY, start.tf[0][2])
const endPosition = new THREE.Vector3(end.tf[0][0], this.defulePositionY, end.tf[0][2])
const wrap = this.lineManager.createPointSimple(lineId)
const matrix = linkPlaneByPoint(startPosition, endPosition, this.rendererOption.lineWidth)
wrap.applyMatrix4(matrix)
return wrap
}
updateLine(start: ItemJson, end: ItemJson, type: LinkType, option?: RendererCudOption) {
const lineId = getLineId(start.id, end.id, type)
const startPosition = new THREE.Vector3(start.tf[0][0], this.defulePositionY, start.tf[0][2])
const endPosition = new THREE.Vector3(end.tf[0][0], this.defulePositionY, end.tf[0][2])
const wrap = this.tempViewport.entityManager.findLineObjectById(lineId) as PointManageWrap
const matrix = linkPlaneByPoint(startPosition, endPosition, this.rendererOption.lineWidth)
wrap.applyMatrix4(matrix)
}
afterCreateOrUpdateLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, object: Object3DLike) {
super.afterCreateOrUpdateLine(start, end, type, option, object)
const startPoint = this.tempViewport?.entityManager.findObjectById(start.id)
const endPoint = this.tempViewport?.entityManager.findObjectById(end.id)
this.tempViewport.labelManager.createOrUpdateLabelByDistance(object, startPoint.position, endPoint.position, {
useHtmlLabel: false,
fontSize: 0.2,
color: '#333333',
format: (distance) => {
return (distance * 1000).toFixed(0)
}
})
}
afterDeleteLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, object: Object3DLike) {
super.afterDeleteLine(start, end, type, option, object)
this.tempViewport.labelManager.removeLabel(object)
}
dispose() {
super.dispose()
this.pointMaterial?.dispose()
this.lineMaterial?.dispose()
}
get lineManager(): InstancePointManager {
if (!this.tempViewport) {
throw new Error('tempViewport is not set.')
}
return this.tempViewport.getOrCreatePointManager(this.itemTypeName + '_line', () =>
// 构建 LineSegment.points 代理对象
InstancePointManager.create(this.itemTypeName + '_line',
this.tempViewport,
this.lineGeometry,
this.lineMaterial,
Constract.MAX_WAY_LINE_INSTANCES)
)
}
get pointManager(): InstancePointManager {
if (!this.tempViewport) {
throw new Error('tempViewport is not set.')
}
return this.tempViewport.getOrCreatePointManager(this.itemTypeName, () =>
// 构建 InstanceMesh 代理对象
InstancePointManager.create(this.itemTypeName,
this.tempViewport,
this.pointGeometry,
this.pointMaterial,
Constract.MAX_WAY_INSTANCES)
)
}
}