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

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