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.
217 lines
6.2 KiB
217 lines
6.2 KiB
import type Viewport from '@/core/engine/Viewport'
|
|
import * as THREE from 'three'
|
|
import { getLineId } from '@/core/ModelUtils.ts'
|
|
import { Line2 } from 'three/examples/jsm/lines/Line2'
|
|
|
|
/**
|
|
* 基本渲染器基类
|
|
* 定义了点 / 线如何渲染到 Three.js 场景中
|
|
*/
|
|
export default abstract class BaseRenderer {
|
|
|
|
/**
|
|
* 每次 beginUpdate 时记录临时 viewport, endUpdate 之后要马上删除, 因为 BaseRenderer 全局只有一个实例, 而 viewport 有多个
|
|
*/
|
|
tempViewport?: Viewport = undefined
|
|
|
|
/**
|
|
* 开始更新
|
|
* @param viewport 当前视口
|
|
*/
|
|
beginRendererUpdate(viewport: Viewport): void {
|
|
this.tempViewport = viewport
|
|
}
|
|
|
|
/**
|
|
* 创建一个最基本的点对象, 不用管 item 的 name / id / 位置 / 转换 / 大小 和 userData, 除非有明确定义
|
|
*/
|
|
abstract createPointBasic(item: ItemJson, option?: RendererCudOption): THREE.Object3D[]
|
|
|
|
/**
|
|
* 创建测量线
|
|
*/
|
|
abstract createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D[]
|
|
|
|
fillObjectUserDataFromItem(item: ItemJson, ...objects: THREE.Object3D[]) {
|
|
_.forEach(objects, (object) => {
|
|
if (!object.name && item.name) {
|
|
object.name = item.name
|
|
}
|
|
object.userData = {
|
|
...object.userData,
|
|
createType: 'point',
|
|
entityId: item.id,
|
|
t: item.t
|
|
}
|
|
})
|
|
}
|
|
|
|
fillObjectUserDataFromLine(start: ItemJson, end: ItemJson, type: LinkType, ...objects: THREE.Object3D[]) {
|
|
const id = getLineId(start.id, end.id, type)
|
|
_.forEach(objects, (object) => {
|
|
if (!object.name) {
|
|
object.name = id
|
|
}
|
|
object.userData = {
|
|
...object.userData,
|
|
createType: 'line',
|
|
entityId: getLineId(start.id, end.id, type),
|
|
t: start.t
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 将对象添加到当前视口的场景中
|
|
*/
|
|
appendToScene(...objects: THREE.Object3D[]) {
|
|
if (!this.tempViewport || !this.tempViewport.scene) {
|
|
console.warn('No active viewport to append objects to.')
|
|
return
|
|
}
|
|
this.tempViewport.scene.add(...objects)
|
|
}
|
|
|
|
/**
|
|
* 创建一个点
|
|
* @param item 点的定义
|
|
* @param option 渲染选项
|
|
*/
|
|
createPoint(item: ItemJson, option?: RendererCudOption) {
|
|
// 由基础类创造一个属于自己的点演示
|
|
const points = this.createPointBasic(item, option)
|
|
_.forEach(points, (point) => {
|
|
if (item.name) {
|
|
point.name = item.name
|
|
}
|
|
|
|
point.position.set(item.tf[0][0], item.tf[0][1], item.tf[0][2])
|
|
|
|
point.rotation.set(
|
|
THREE.MathUtils.degToRad(item.tf[1][0]),
|
|
THREE.MathUtils.degToRad(item.tf[1][1]),
|
|
THREE.MathUtils.degToRad(item.tf[1][2])
|
|
)
|
|
|
|
point.scale.set(item.tf[2][0], item.tf[2][1], item.tf[2][2])
|
|
})
|
|
this.fillObjectUserDataFromItem(item, ...points)
|
|
this.tempViewport.entityManager.appendObject(item.id, points)
|
|
this.appendToScene(...points)
|
|
}
|
|
|
|
|
|
/**
|
|
* 删除一个点
|
|
* @param id 点的唯一标识
|
|
* @param option 渲染选项
|
|
*/
|
|
deletePoint(id: string, option?: RendererCudOption) {
|
|
const objects = this.tempViewport.entityManager.findObjectsById(id)
|
|
if (objects) {
|
|
this.tempViewport.scene.remove(...objects)
|
|
}
|
|
|
|
this.tempViewport.entityManager.deleteEntityOnly(id)
|
|
this.tempViewport.entityManager.deleteObjectsOnly(id)
|
|
}
|
|
|
|
/**
|
|
* 更新一个点
|
|
* @param item 点的定义
|
|
* @param option 渲染选项
|
|
*/
|
|
updatePoint(item: ItemJson, option?: RendererCudOption) {
|
|
const objects = this.tempViewport.entityManager.findObjectsById(item.id)
|
|
if (!objects || objects.length === 0) {
|
|
console.warn(`Point with ID "${item.id}" does not exist.`)
|
|
return
|
|
}
|
|
|
|
_.forEach(objects, (point) => {
|
|
point.name = item.name || point.name
|
|
|
|
point.position.set(item.tf[0][0], item.tf[0][1], item.tf[0][2])
|
|
|
|
point.rotation.set(
|
|
THREE.MathUtils.degToRad(item.tf[1][0]),
|
|
THREE.MathUtils.degToRad(item.tf[1][1]),
|
|
THREE.MathUtils.degToRad(item.tf[1][2])
|
|
)
|
|
|
|
point.scale.set(item.tf[2][0], item.tf[2][1], item.tf[2][2])
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 创建一根线
|
|
* @param start 起点
|
|
* @param end 终点
|
|
* @param type 线的类型
|
|
* @param option 渲染选项
|
|
*/
|
|
createLine(start: ItemJson, end: ItemJson, type: LinkType, option?: RendererCudOption) {
|
|
const lines = this.createLineBasic(start, end, type)
|
|
const id = getLineId(start.id, end.id, type)
|
|
|
|
const startPoint = this.tempViewport.entityManager.findObjectsById(start.id)?.[0]
|
|
const endPoint = this.tempViewport.entityManager.findObjectsById(end.id)?.[0]
|
|
|
|
_.forEach(lines, (line) => {
|
|
this.tempViewport.entityManager.findObjectsById(id)
|
|
|
|
const geom = line.geometry
|
|
geom.setFromPoints([startPoint.position, endPoint.position])
|
|
})
|
|
this.fillObjectUserDataFromLine(start, end, type, ...lines)
|
|
|
|
this.tempViewport.entityManager.appendLineObject(id, lines)
|
|
this.appendToScene(...lines)
|
|
}
|
|
|
|
/**
|
|
* 更新一根线
|
|
* @param start 起点
|
|
* @param end 终点
|
|
* @param type 线的类型
|
|
* @param option 渲染选项
|
|
*/
|
|
updateLine(start: ItemJson, end: ItemJson, type: LinkType, option?: RendererCudOption) {
|
|
const lineId = getLineId(start.id, end.id, type)
|
|
|
|
const lines = this.tempViewport.entityManager.findLineObjectsById(lineId)
|
|
_.forEach(lines, (line: THREE.Object3D) => {
|
|
const startPoint = this.tempViewport.entityManager.findObjectsById(start.id)?.[0]
|
|
const endPoint = this.tempViewport.entityManager.findObjectsById(end.id)?.[0]
|
|
|
|
if (line instanceof Line2) {
|
|
const geom = line.geometry
|
|
geom.setFromPoints([startPoint.position, endPoint.position])
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 删除一根线
|
|
* @param start 起点
|
|
* @param end 终点
|
|
* @param option 渲染选项
|
|
*/
|
|
deleteLine(start: ItemJson, end: ItemJson, option?: RendererCudOption) {
|
|
const id = getLineId(start.id, end.id, 'center')
|
|
const lines = this.tempViewport.entityManager.findLineObjectsById(id)
|
|
if (lines) {
|
|
this.tempViewport.scene.remove(...lines)
|
|
}
|
|
|
|
this.tempViewport.entityManager.deleteLineObjectOnly(id)
|
|
}
|
|
|
|
/**
|
|
* 结束更新
|
|
*/
|
|
endRendererUpdate(): void {
|
|
this.tempViewport = undefined
|
|
}
|
|
}
|
|
|
|
|