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.
176 lines
5.5 KiB
176 lines
5.5 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 { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
|
|
import { Line2 } from 'three/examples/jsm/lines/Line2.js'
|
|
import Constract from '@/core/Constract.ts'
|
|
|
|
/**
|
|
* 辅助测量工具渲染器
|
|
*/
|
|
export default class MeasureRenderer extends BaseRenderer {
|
|
/**
|
|
* 当前测绘内容组, 所有测量点、线、标签都在这个组中. 但不包括临时点、线
|
|
*/
|
|
group: THREE.Group
|
|
|
|
static GROUP_NAME = 'measure_group'
|
|
static LABEL_NAME = 'measure_label'
|
|
static POINT_NAME = 'measure_point'
|
|
static LINE_NAME = 'measure_line'
|
|
|
|
public useHtmlLabel = false
|
|
|
|
pointMaterial: THREE.Material
|
|
lineMaterial: LineMaterial
|
|
|
|
readonly defulePositionY = Constract.HEIGHT_MEASURE
|
|
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(0.1, 0.1, 0.1)
|
|
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(0, 0, 0)
|
|
|
|
constructor(itemTypeName: string) {
|
|
super(itemTypeName)
|
|
}
|
|
|
|
async init() {
|
|
this.pointMaterial = new THREE.SpriteMaterial({
|
|
color: 0xFFFF99, // 0x303133,
|
|
transparent: true,
|
|
side: THREE.DoubleSide,
|
|
opacity: 1,
|
|
sizeAttenuation: true
|
|
})
|
|
this.lineMaterial = new LineMaterial({
|
|
color: 0xFF8C00,
|
|
linewidth: 1,
|
|
vertexColors: false,
|
|
dashed: false
|
|
})
|
|
return Promise.all([
|
|
super.init()
|
|
])
|
|
}
|
|
|
|
/**
|
|
* 所有的点,必须使用同一个尺寸, 改属性也无效
|
|
*/
|
|
override afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, object: THREE.Object3D) {
|
|
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)
|
|
)
|
|
}
|
|
|
|
|
|
createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D {
|
|
const geom = new LineGeometry()
|
|
const obj = new Line2(geom, this.lineMaterial)
|
|
obj.frustumCulled = false
|
|
obj.name = MeasureRenderer.LINE_NAME
|
|
obj.uuid = getLineId(start.id, end.id, type)
|
|
|
|
return obj
|
|
}
|
|
|
|
createPointBasic(item: ItemJson, option?: RendererCudOption): THREE.Object3D {
|
|
// const tt = new THREE.BoxGeometry(1, 1, 1)
|
|
// const obj = new THREE.Mesh(tt, this.movelinePoint)
|
|
// obj.name = MeasureRenderer.POINT_NAME
|
|
// obj.uuid = item.id
|
|
//
|
|
// return [obj]
|
|
|
|
// 创建平面几何体
|
|
const obj = new THREE.Sprite(this.pointMaterial as THREE.SpriteMaterial)
|
|
obj.name = MeasureRenderer.POINT_NAME
|
|
return obj
|
|
}
|
|
|
|
// appendToScene(...objects: THREE.Object3D[]) {
|
|
// if (!this.group || this.group.parent !== this.tempViewport.scene.scene) {
|
|
// if (this.group && this.group.parent !== this.tempViewport.scene.scene) {
|
|
// // 幻影加载问题
|
|
// this.group.parent.removeFromParent()
|
|
// }
|
|
//
|
|
// this.group = new THREE.Group()
|
|
// this.group.name = MeasureRenderer.GROUP_NAME
|
|
// this.tempViewport?.scene.add(this.group)
|
|
// }
|
|
//
|
|
// const dragObjects = objects.filter(obj => !!obj.userData.draggable)
|
|
// //this.tempViewport.dragControl.setDragObjects(dragObjects, 'push')
|
|
//
|
|
// this.group.add(...objects)
|
|
// }
|
|
|
|
afterCreateOrUpdateLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, object: THREE.Object3D) {
|
|
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'
|
|
})
|
|
|
|
// const p0 = startPoint.position
|
|
// const p1 = endPoint.position
|
|
//
|
|
// const dist = p0.distanceTo(p1)
|
|
// const label = numberToString(dist) + ' m'
|
|
//
|
|
// const position = new THREE.Vector3().addVectors(p0, p1).multiplyScalar(0.5)
|
|
// let labelObj: Text | CSS2DObject | undefined = object.userData.labelObj
|
|
// if (!labelObj || !labelObj.parent) {
|
|
// labelObj = this.createLabel(label)
|
|
// this.appendToScene(labelObj)
|
|
// object.userData.labelObj = labelObj
|
|
// }
|
|
//
|
|
// labelObj.position.set(position.x, position.y + 0.3, position.z - 0.2)
|
|
//
|
|
// if (this.useHtmlLabel) {
|
|
// labelObj.element.innerHTML = label
|
|
//
|
|
// } else {
|
|
// // 让文本朝向摄像机
|
|
// labelObj.quaternion.copy(this.tempViewport.camera.quaternion)
|
|
// labelObj.text = label
|
|
// labelObj.sync()
|
|
// }
|
|
}
|
|
|
|
afterDeleteLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, object: THREE.Object3D) {
|
|
super.afterDeleteLine(start, end, type, option, object)
|
|
|
|
this.tempViewport.labelManager.removeLabel(object)
|
|
// 删除标签
|
|
// const labelObj = object.userData?.labelObj
|
|
// if (labelObj && labelObj.parent) {
|
|
// labelObj.parent.remove(labelObj)
|
|
// }
|
|
}
|
|
|
|
|
|
dispose() {
|
|
super.dispose()
|
|
|
|
if (this.group && this.group.parent) {
|
|
this.group.parent.remove(this.group)
|
|
}
|
|
this.group = undefined
|
|
|
|
this.pointMaterial?.dispose()
|
|
this.lineMaterial?.dispose()
|
|
}
|
|
}
|
|
|