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.
117 lines
4.1 KiB
117 lines
4.1 KiB
import * as THREE from 'three'
|
|
import BaseRenderer from '@/core/base/BaseRenderer.ts'
|
|
import { getLineId } from '@/core/ModelUtils.ts'
|
|
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
|
|
import Constract from '@/core/Constract.ts'
|
|
import InstancePointManager from '@/core/manager/InstancePointManager.ts'
|
|
import LineSegmentManager from '@/core/manager/LineSegmentManager.ts'
|
|
import type { Object3DLike } from '@/types/ModelTypes.ts'
|
|
|
|
/**
|
|
* 辅助测量工具渲染器
|
|
* 支持 InstanceMesh 和 LineSegment
|
|
*/
|
|
export default class MeasureRenderer extends BaseRenderer {
|
|
static LABEL_NAME = 'measure_label'
|
|
static POINT_NAME = 'measure_point'
|
|
|
|
public useHtmlLabel = false
|
|
|
|
pointMaterial: THREE.Material = new THREE.MeshBasicMaterial({
|
|
color: 0xFFFF99,
|
|
transparent: true,
|
|
depthWrite: false,
|
|
side: THREE.DoubleSide
|
|
})
|
|
pointGeometry = new THREE.PlaneGeometry(1, 1)
|
|
lineMaterial: LineMaterial = new LineMaterial({
|
|
color: 0xFF8C00,
|
|
linewidth: 1,
|
|
vertexColors: false,
|
|
dashed: false
|
|
})
|
|
readonly defulePositionY = Constract.HEIGHT_MEASURE
|
|
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(0.25, 0.25, 0.1)
|
|
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(90, 0, 0)
|
|
|
|
/**
|
|
* 所有的点,必须使用同一个尺寸, 改属性也无效
|
|
*/
|
|
override afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, object: Object3DLike) {
|
|
super.afterCreateOrUpdatePoint(item, option, object)
|
|
|
|
const point = object
|
|
|
|
point.scale.set(this.defaultScale.x, this.defaultScale.y, this.defaultScale.z)
|
|
point.rotation.set(
|
|
THREE.MathUtils.degToRad(this.defaultRotation.x),
|
|
THREE.MathUtils.degToRad(this.defaultRotation.y),
|
|
THREE.MathUtils.degToRad(this.defaultRotation.z)
|
|
)
|
|
}
|
|
|
|
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)
|
|
return this.lineSegmentManager.createLine(lineId, start.tf[0], end.tf[0], this.lineMaterial.color)
|
|
}
|
|
|
|
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: this.useHtmlLabel,
|
|
fontSize: 0.4,
|
|
color: '#333333'
|
|
})
|
|
}
|
|
|
|
afterDeleteLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, object: Object3DLike) {
|
|
super.afterDeleteLine(start, end, type, option, object)
|
|
this.tempViewport.labelManager.removeLabel(object)
|
|
}
|
|
|
|
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_MEASURE_INSTANCES)
|
|
)
|
|
}
|
|
|
|
get lineSegmentManager(): LineSegmentManager {
|
|
if (!this.tempViewport) {
|
|
throw new Error('tempViewport is not set.')
|
|
}
|
|
return this.tempViewport.getOrCreateLineManager(this.itemTypeName, () =>
|
|
// 构建 LineSegment.points 代理对象
|
|
LineSegmentManager.create(this.itemTypeName,
|
|
this.tempViewport,
|
|
this.lineMaterial)
|
|
)
|
|
}
|
|
|
|
dispose() {
|
|
super.dispose()
|
|
this.pointMaterial?.dispose()
|
|
this.lineMaterial?.dispose()
|
|
}
|
|
}
|
|
|