|
|
|
@ -1,14 +1,11 @@ |
|
|
|
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 { numberToString } from '@/utils/webutils.ts' |
|
|
|
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer' |
|
|
|
import { Text } from 'troika-three-text' |
|
|
|
import SimSunTTF from '@/assets/fonts/simsunb.ttf' |
|
|
|
import MoveLinePointPng from '@/assets/images/moveline_point.png' |
|
|
|
import SimSunTTF from '@/assets/fonts/simsunb.ttf' |
|
|
|
import { getLineId } from '@/core/ModelUtils.ts' |
|
|
|
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer' |
|
|
|
import { numberToString } from '@/utils/webutils.ts' |
|
|
|
|
|
|
|
/** |
|
|
|
* 辅助测量工具渲染器 |
|
|
|
@ -21,9 +18,18 @@ export default class WayRenderer extends BaseRenderer { |
|
|
|
public useHtmlLabel = false |
|
|
|
|
|
|
|
pointMaterial: THREE.Material |
|
|
|
lineMaterial: LineMaterial |
|
|
|
lineMaterial = new THREE.MeshBasicMaterial({ |
|
|
|
color: 0xa0cfff, |
|
|
|
transparent: true, |
|
|
|
opacity: 0.2, |
|
|
|
side: THREE.DoubleSide |
|
|
|
}) |
|
|
|
|
|
|
|
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(0.5, 0.5, 0.1) |
|
|
|
/** |
|
|
|
* 默认点的高度, 防止和地面重合 |
|
|
|
*/ |
|
|
|
readonly defulePositionY: number = 0.8 // 默认点的高度, 0.01, 防止和地面重合
|
|
|
|
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(1, 1, 0.1) |
|
|
|
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(90, 0, 0) |
|
|
|
|
|
|
|
constructor(itemTypeName: string) { |
|
|
|
@ -31,13 +37,6 @@ export default class WayRenderer extends BaseRenderer { |
|
|
|
} |
|
|
|
|
|
|
|
async init() { |
|
|
|
this.lineMaterial = new LineMaterial({ |
|
|
|
color: 0xE63C17, // 主颜色
|
|
|
|
linewidth: 2, // 实际可用的线宽
|
|
|
|
vertexColors: true, // 启用顶点颜色
|
|
|
|
dashed: false, |
|
|
|
alphaToCoverage: true |
|
|
|
}) |
|
|
|
return Promise.all([ |
|
|
|
super.init(), |
|
|
|
this.loadFont() |
|
|
|
@ -71,7 +70,7 @@ export default class WayRenderer extends BaseRenderer { |
|
|
|
super.afterCreateOrUpdatePoint(item, option, objects) |
|
|
|
|
|
|
|
const point = objects[0] |
|
|
|
|
|
|
|
point.position.y = this.defulePositionY |
|
|
|
point.scale.set(this.defaultScale.x, this.defaultScale.y, this.defaultScale.z) |
|
|
|
point.rotation.set( |
|
|
|
THREE.MathUtils.degToRad(this.defaultRotation.x), |
|
|
|
@ -82,27 +81,17 @@ export default class WayRenderer extends BaseRenderer { |
|
|
|
|
|
|
|
|
|
|
|
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 = WayRenderer.LINE_NAME |
|
|
|
obj.uuid = getLineId(start.id, end.id, type) |
|
|
|
const group = new THREE.Group() |
|
|
|
const startPosition = new THREE.Vector3(start.tf[0][0], 0.01, start.tf[0][2]) |
|
|
|
const endPosition = new THREE.Vector3(end.tf[0][0], 0.01, end.tf[0][2]) |
|
|
|
const width = 1 |
|
|
|
|
|
|
|
return [obj] |
|
|
|
} |
|
|
|
|
|
|
|
createPointBasic(item: ItemJson, option?: RendererCudOption): THREE.Object3D[] { |
|
|
|
const obj = new THREE.Sprite(this.pointMaterial as THREE.SpriteMaterial) |
|
|
|
obj.name = WayRenderer.POINT_NAME |
|
|
|
return [obj] |
|
|
|
} |
|
|
|
|
|
|
|
appendToScene(...objects: THREE.Object3D[]) { |
|
|
|
const dragObjects = objects.filter(obj => !!obj.userData.draggable) |
|
|
|
this.tempViewport.dragControl.setDragObjects(dragObjects, 'push') |
|
|
|
// this.tempViewport.dragControl.setDragObjects(objects, 'remove')
|
|
|
|
const curve = new THREE.LineCurve3(startPosition, endPosition) |
|
|
|
const tubeGeometry = new THREE.TubeGeometry(curve, 1, width / 2, 8, false) |
|
|
|
const lineMesh = new THREE.Mesh(tubeGeometry, this.lineMaterial) |
|
|
|
group.add(lineMesh) |
|
|
|
|
|
|
|
this.tempViewport?.scene.add(...objects) |
|
|
|
return [group] |
|
|
|
} |
|
|
|
|
|
|
|
afterCreateOrUpdateLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, objects: THREE.Object3D[]) { |
|
|
|
@ -115,17 +104,17 @@ export default class WayRenderer extends BaseRenderer { |
|
|
|
const p1 = endPoint.position |
|
|
|
|
|
|
|
const dist = p0.distanceTo(p1) |
|
|
|
const label = `${numberToString(dist)} m` |
|
|
|
const label = numberToString(dist) |
|
|
|
|
|
|
|
const position = new THREE.Vector3().addVectors(p0, p1).multiplyScalar(0.5) |
|
|
|
let labelObj: Text | CSS2DObject | undefined = objects[0].userData.labelObj |
|
|
|
if (!labelObj || !labelObj.parent) { |
|
|
|
labelObj = this.createLabel(label) |
|
|
|
this.appendToScene(labelObj) |
|
|
|
this.tempViewport.scene.add(labelObj) |
|
|
|
objects[0].userData.labelObj = labelObj |
|
|
|
} |
|
|
|
|
|
|
|
labelObj.position.set(position.x, position.y + 0.3, position.z - 0.2) |
|
|
|
labelObj.position.set(position.x, position.y, position.z) |
|
|
|
|
|
|
|
if (this.useHtmlLabel) { |
|
|
|
labelObj.element.innerHTML = label |
|
|
|
@ -174,7 +163,7 @@ export default class WayRenderer extends BaseRenderer { |
|
|
|
label.text = text |
|
|
|
label.font = SimSunTTF |
|
|
|
label.fontSize = 0.4 |
|
|
|
label.color = '#ff0000' |
|
|
|
label.color = '#333333' |
|
|
|
label.opacity = 0.8 |
|
|
|
label.padding = 0.2 |
|
|
|
label.anchorX = 'center' |
|
|
|
@ -191,6 +180,40 @@ export default class WayRenderer extends BaseRenderer { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
updateLine(start: ItemJson, end: ItemJson, type: LinkType, option?: RendererCudOption) { |
|
|
|
super.updateLine(start, end, type, option) |
|
|
|
|
|
|
|
const startPosition = new THREE.Vector3(start.tf[0][0], 0.01, start.tf[0][2]) |
|
|
|
const endPosition = new THREE.Vector3(end.tf[0][0], 0.01, end.tf[0][2]) |
|
|
|
const width = 1 |
|
|
|
|
|
|
|
const lineId = getLineId(start.id, end.id, type) |
|
|
|
const lines = this.tempViewport.entityManager.findLineObjectsById(lineId) |
|
|
|
const group: THREE.Group = lines[0] as THREE.Group |
|
|
|
|
|
|
|
// 清空group里的元素
|
|
|
|
group.clear() |
|
|
|
|
|
|
|
const curve = new THREE.LineCurve3(startPosition, endPosition) |
|
|
|
const tubeGeometry = new THREE.TubeGeometry(curve, 1, width / 2, 8, false) |
|
|
|
const lineMesh = new THREE.Mesh(tubeGeometry, this.lineMaterial) |
|
|
|
group.add(lineMesh) |
|
|
|
} |
|
|
|
|
|
|
|
createPointBasic(item: ItemJson, option?: RendererCudOption): THREE.Object3D[] { |
|
|
|
const obj = new THREE.Sprite(this.pointMaterial as THREE.SpriteMaterial) |
|
|
|
obj.name = WayRenderer.POINT_NAME |
|
|
|
return [obj] |
|
|
|
} |
|
|
|
|
|
|
|
appendToScene(...objects: THREE.Object3D[]) { |
|
|
|
const dragObjects = objects.filter(obj => !!obj.userData.draggable) |
|
|
|
this.tempViewport.dragControl.setDragObjects(dragObjects, 'push') |
|
|
|
// this.tempViewport.dragControl.setDragObjects(objects, 'remove')
|
|
|
|
|
|
|
|
this.tempViewport?.scene.add(...objects) |
|
|
|
} |
|
|
|
|
|
|
|
dispose() { |
|
|
|
super.dispose() |
|
|
|
this.pointMaterial.dispose() |
|
|
|
|