From d10904e0640267007327ab110f5144f857cd6b80 Mon Sep 17 00:00:00 2001 From: luoyifan Date: Tue, 3 Jun 2025 22:18:53 +0800 Subject: [PATCH] Way --- src/core/ModelUtils.ts | 4 +- src/core/base/BaseInteraction.ts | 12 ++-- src/core/base/BaseRenderer.ts | 9 ++- src/core/manager/InteractionManager.ts | 5 +- src/modules/way/WayRenderer.ts | 103 ++++++++++++++++++++------------- 5 files changed, 80 insertions(+), 53 deletions(-) diff --git a/src/core/ModelUtils.ts b/src/core/ModelUtils.ts index 0fa88cc..d61030f 100644 --- a/src/core/ModelUtils.ts +++ b/src/core/ModelUtils.ts @@ -214,8 +214,8 @@ export function quickCopyByMouse() { // } // console.log('intersections:', intersections) - // 如果不在线上,查找0.2米内的有效点 Object3D, 如果有,则以这个点为起点, 延伸同类型的点,并让他们相连 - const items = findStateItemsByDistance(viewport, new Vector2(x, z), 0.2) + // 如果不在线上,查找1米内的有效点 Object3D, 如果有,则以这个点为起点, 延伸同类型的点,并让他们相连 + const items = findStateItemsByDistance(viewport, new Vector2(x, z), 1) if (items[0]) { // 找到一个有效点,执行复制操作 viewport.interactionManager.startInteraction(items[0].t, { startPoint: items[0].id }) diff --git a/src/core/base/BaseInteraction.ts b/src/core/base/BaseInteraction.ts index dfb8ad7..05a4dc5 100644 --- a/src/core/base/BaseInteraction.ts +++ b/src/core/base/BaseInteraction.ts @@ -42,6 +42,10 @@ export default abstract class BaseInteraction { linkStartPointId: string linkStartPointObject: THREE.Object3D + dragOption: DragOption | undefined + dragOriginPosition: THREE.Vector3 | undefined + dragItem: ItemJson | undefined + templineMaterial = new LineMaterial({ color: 0xE63C17, // 主颜色 linewidth: 2, // 实际可用的线宽 @@ -54,11 +58,6 @@ export default abstract class BaseInteraction { this.itemTypeName = itemTypeName } - - dragOption: DragOption | undefined - dragOriginPosition: THREE.Vector3 | undefined - dragItem: ItemJson | undefined - /** * 拖拽点开始 */ @@ -121,7 +120,10 @@ export default abstract class BaseInteraction { this.canvas = this.viewport.renderer.domElement if (option?.startPoint) { this.linkStartPointId = option.startPoint + } else { + this.linkStartPointId = undefined } + if (this.linkStartPointId) { this.linkStartPointObject = this.viewport.entityManager.findObjectsById(this.linkStartPointId)?.[0] } diff --git a/src/core/base/BaseRenderer.ts b/src/core/base/BaseRenderer.ts index 0bce096..cc279e8 100644 --- a/src/core/base/BaseRenderer.ts +++ b/src/core/base/BaseRenderer.ts @@ -58,6 +58,8 @@ export default abstract class BaseRenderer { abstract get defaultRotation(): THREE.Vector3 + abstract get defulePositionY(): number + /** * 创建或更新线之后的回调 */ @@ -222,9 +224,10 @@ export default abstract class BaseRenderer { _.forEach(lines, (line) => { this.tempViewport.entityManager.findObjectsById(id) - - const geom = line.geometry - geom.setFromPoints([startPoint.position, endPoint.position]) + if (line instanceof Line2) { + const geom = line.geometry + geom.setFromPoints([startPoint.position, endPoint.position]) + } }) this.fillObjectUserDataFromLine(start, end, type, ...lines) diff --git a/src/core/manager/InteractionManager.ts b/src/core/manager/InteractionManager.ts index 82d07b9..a846d21 100644 --- a/src/core/manager/InteractionManager.ts +++ b/src/core/manager/InteractionManager.ts @@ -56,6 +56,7 @@ export default class InteractionManager implements IControls { this.viewport.dragControl.dragControls.enabled = true this.viewport.viewerDom.style.cursor = '' + this.option = undefined // system.msg('退出新建模式') } @@ -85,9 +86,7 @@ export default class InteractionManager implements IControls { } // 保存参数 - if (option) { - this.option = option - } + this.option = option // 初始化交互 this.currentTool = interaction diff --git a/src/modules/way/WayRenderer.ts b/src/modules/way/WayRenderer.ts index 878f4aa..43b9895 100644 --- a/src/modules/way/WayRenderer.ts +++ b/src/modules/way/WayRenderer.ts @@ -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()