From 4d1c3ab376086f0459c8ce8378d648b9e5cf0ddf Mon Sep 17 00:00:00 2001 From: yvan Date: Mon, 2 Jun 2025 21:00:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=96=E6=8B=BD=E7=82=B9=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/base/BaseInteraction.ts | 77 +++++++++++++++++++++++++++------- src/core/base/BaseRenderer.ts | 17 +++++++- src/core/controls/EsDragControls.ts | 62 +++++++++++++++++---------- src/core/manager/InteractionManager.ts | 2 + src/modules/measure/MeasureRenderer.ts | 6 ++- src/types/global.d.ts | 2 + src/types/model.d.ts | 22 ++++++++++ 7 files changed, 149 insertions(+), 39 deletions(-) diff --git a/src/core/base/BaseInteraction.ts b/src/core/base/BaseInteraction.ts index 57207cf..29e31e5 100644 --- a/src/core/base/BaseInteraction.ts +++ b/src/core/base/BaseInteraction.ts @@ -55,6 +55,63 @@ export default abstract class BaseInteraction { this.itemTypeName = itemTypeName } + + dragOption: DragOption | undefined + dragOriginPosition: THREE.Vector3 | undefined + dragItem: ItemJson | undefined + + /** + * 拖拽点开始 + */ + dragPointStart(viewport: Viewport, dragOption: DragOption) { + this.viewport = viewport + this.dragOption = dragOption + this.dragOriginPosition = dragOption.object.position.clone() + + // 找到 itemJson + const itemJson = _.find(this.viewport.stateManager.vdata.items, (item) => item.id === dragOption.entityId) + if (!itemJson) { + system.showErrorDialog('Not found for entityId:' + dragOption.entityId) + return false + } + + this.dragItem = itemJson + return true + } + + /** + * 拖拽点移动 + */ + dragPointMove(viewport: Viewport, e: MouseEvent) { + if (this.viewport !== viewport) return + } + + /** + * 拖拽点完成 + */ + dragPointComplete(viewport: Viewport, e: MouseEvent) { + if (this.viewport !== viewport) return + + // 获取当前鼠标所在位置 + if (!CurrentMouseInfo || !CurrentMouseInfo.x || !this.dragItem?.tf?.[0]) { + return + } + + // 提交状态管理器 + console.log('drag from ', [this.dragItem.tf[0][0], this.dragItem.tf[0][2]], 'to', [CurrentMouseInfo.x, CurrentMouseInfo.z]) + + const stateManager = this.viewport.stateManager + stateManager.beginStateUpdate({ createFromInteraction: true }) + this.dragItem.tf[0][0] = CurrentMouseInfo.x + this.dragItem.tf[0][2] = CurrentMouseInfo.z + stateManager.endStateUpdate() + + this.viewport = undefined + this.dragOption = undefined + this.dragItem = undefined + return true + } + /** * 开始交互 */ @@ -108,21 +165,6 @@ export default abstract class BaseInteraction { this.canvas = undefined } - /** - * 拖拽点开始 - * @param viewport 当前视口 - * @param point 拖拽的点 - */ - dragPointStart(viewport: Viewport, point: THREE.Object3D) { - } - - /** - * 拖拽点完成 - * @param viewport 当前视口 - */ - dragPointComplete(viewport: Viewport) { - } - mousedown() { this.mouseOnlyClick = true } @@ -318,4 +360,9 @@ export default abstract class BaseInteraction { const obj = new CSS2DObject(div) return obj } +} + +export interface DragOption { + object: THREE.Object3D + entityId: string } \ No newline at end of file diff --git a/src/core/base/BaseRenderer.ts b/src/core/base/BaseRenderer.ts index 71a5b05..b11cf95 100644 --- a/src/core/base/BaseRenderer.ts +++ b/src/core/base/BaseRenderer.ts @@ -75,6 +75,7 @@ export default abstract class BaseRenderer { ...object.userData, createType: 'point', entityId: item.id, + draggable: item.dt.protected !== true, t: item.t } }) @@ -103,9 +104,21 @@ export default abstract class BaseRenderer { console.warn('No active viewport to append objects to.') return } + + const dragObjects = objects.filter(obj => !!obj.userData.draggable) + this.tempViewport.dragControl.setDragObjects(dragObjects, 'push') this.tempViewport.scene.add(...objects) } + removeFromScene(...objects: THREE.Object3D[]) { + if (!this.tempViewport || !this.tempViewport.scene) { + console.warn('No active viewport to remove objects from.') + return + } + this.tempViewport.scene.remove(...objects) + this.tempViewport.dragControl.setDragObjects(objects, 'remove') + } + /** * 创建一个点 * @param item 点的定义 @@ -145,7 +158,7 @@ export default abstract class BaseRenderer { deletePoint(id: string, option?: RendererCudOption) { const objects = this.tempViewport.entityManager.findObjectsById(id) if (objects) { - this.tempViewport.scene.remove(...objects) + this.removeFromScene(...objects) } this.tempViewport.entityManager.deleteEntityOnly(id) @@ -241,7 +254,7 @@ export default abstract class BaseRenderer { const id = getLineId(start.id, end.id, type) const lines = this.tempViewport.entityManager.findLineObjectsById(id) if (lines) { - this.tempViewport.scene.remove(...lines) + this.removeFromScene(...lines) } this.tempViewport.entityManager.deleteLineObjectOnly(id) diff --git a/src/core/controls/EsDragControls.ts b/src/core/controls/EsDragControls.ts index 01b718f..5005dbd 100644 --- a/src/core/controls/EsDragControls.ts +++ b/src/core/controls/EsDragControls.ts @@ -5,6 +5,8 @@ import { getItemTypeByName } from '@/model/itemType/ItemTypeDefine' import type { ItemTypeDefineOption } from '@/model/itemType/ItemTypeDefine' import { markRaw } from 'vue' import EventBus from '@/runtime/EventBus' +import { getInteraction } from '@/core/manager/ModuleManager.ts' +import type BaseInteraction from '@/core/base/BaseInteraction.ts' // dragControls 绑定函数 let dragStartFn, dragFn, dragEndFn, clickblankFn @@ -15,6 +17,7 @@ export default class EsDragControls { private onDownPosition: { x: number; y: number } = { x: -1, y: -1 } viewport: Viewport + currentInteraction: BaseInteraction isDragging = false constructor(viewport) { @@ -68,7 +71,24 @@ export default class EsDragControls { // 拖拽开始 dragControlsStart(e) { // 右键拖拽不响应 - if (e.e.button === 2 || !e.object.userData.type || !e.object.visible) return + if (e.e.button === 2 || !e.object.visible) return + + const type = e.object.userData?.t + const entityId = e.object.userData?.entityId + + if (!type || !entityId) return + + this.currentInteraction = getInteraction(e.object.userData?.t) + if (!this.currentInteraction) { + return + } + + // 有效拖拽对象 + const enable = this.currentInteraction.dragPointStart(this.viewport, { + object: e.object, + entityId: entityId + }) + if (!enable) return e.e.preventDefault() @@ -80,12 +100,10 @@ export default class EsDragControls { // 记录拖拽按下的位置和对象 this.onDownPosition = { x: e.e.clientX, y: e.e.clientY } - if (e.object.userData?.type) { - const itemType: ItemTypeDefineOption = getItemTypeByName(e.object.userData.type) - if (itemType?.clazz) { - itemType.clazz.dragPointStart(this.viewport, e.object) - } - } + // const itemType: ItemTypeDefineOption = getItemTypeByName(e.object.userData.type) + // if (itemType?.clazz) { + // itemType.clazz.dragPointStart(this.viewport, e.object) + // } // switch (e.object.userData.type) { // case Constract.MeasureMarker: // this.viewport.measure.dragPointStart(e.object) @@ -95,6 +113,7 @@ export default class EsDragControls { // 拖拽中 drag(e) { + this.currentInteraction?.dragPointMove(this.viewport, e) EventBus.dispatch('objectChanged', { viewport: this, object: e.object @@ -105,15 +124,9 @@ export default class EsDragControls { dragControlsEnd(e) { // 右键拖拽不响应 if (e.e.button === 2 || !e.object.visible) return + if (!e.object.userData?.t) return - // 拖拽结束启用其他控制器 - this.viewport.controls.enabled = true - - this.isDragging = false - - if (!e.object.userData.type) return - - // 判断位置是否有变化,没有变化则为点击 + // 单选点击 if (this.onDownPosition.x === e.e.clientX && this.onDownPosition.y === e.e.clientY) { if (e.object.userData.onClick) { e.object.userData.onClick(e) @@ -127,12 +140,19 @@ export default class EsDragControls { } } - if (e.object.userData?.type) { - const itemType: ItemTypeDefineOption = getItemTypeByName(e.object.userData.type) - if (itemType?.clazz) { - itemType.clazz.dragPointComplete(this.viewport) - } - } + const ret = this.currentInteraction?.dragPointComplete(this.viewport, e) + if (!ret) return + + // 拖拽结束启用其他控制器 + this.viewport.controls.enabled = true + this.isDragging = false + + // if (e.object.userData?.type) { + // const itemType: ItemTypeDefineOption = getItemTypeByName(e.object.userData.type) + // if (itemType?.clazz) { + // itemType.clazz.dragPointComplete(this.viewport) + // } + // } // switch (e.object.userData.type) { // case Constract.MeasureMarker: // this.viewport.measure.dragPointComplete() diff --git a/src/core/manager/InteractionManager.ts b/src/core/manager/InteractionManager.ts index 1f1f3c1..3b4c48f 100644 --- a/src/core/manager/InteractionManager.ts +++ b/src/core/manager/InteractionManager.ts @@ -54,6 +54,7 @@ export default class InteractionManager implements IControls { this.viewport.state.cursorMode = 'normal' this.viewport.dragControl.dragControls.enabled = true + debugger this.viewport.viewerDom.style.cursor = '' system.msg('退出新建模式') } @@ -91,6 +92,7 @@ export default class InteractionManager implements IControls { // 初始化交互 this.currentTool = interaction this.viewport.dragControl.dragControls.enabled = false + debugger this.currentTool.start(this.viewport, { startPoint: this.toolStartObject }) // 更新 UI 状态 diff --git a/src/modules/measure/MeasureRenderer.ts b/src/modules/measure/MeasureRenderer.ts index 6b90931..61beff9 100644 --- a/src/modules/measure/MeasureRenderer.ts +++ b/src/modules/measure/MeasureRenderer.ts @@ -37,7 +37,7 @@ export default class MeasureRenderer extends BaseRenderer { readonly defaultScale: THREE.Vector3 = new THREE.Vector3(0.25, 0.1, 0.25) readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(0, 0, 0) - constructor(itemTypeName:string) { + constructor(itemTypeName: string) { super(itemTypeName) } @@ -72,6 +72,10 @@ export default class MeasureRenderer extends BaseRenderer { this.tempViewport?.scene.add(this.group) } + const dragObjects = objects.filter(obj => !!obj.userData.draggable) + this.tempViewport.dragControl.setDragObjects(dragObjects, 'push') + // this.tempViewport.dragControl.setDragObjects(objects, 'remove') + this.group.add(...objects) } diff --git a/src/types/global.d.ts b/src/types/global.d.ts index ff22c30..f19c1fe 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -2,6 +2,7 @@ import _ from 'lodash' import $ from 'jquery' import type System from '@/runtime/System' import type WorldModel from '@/core/manager/WorldModel' +import type { CurrentMouseInfo } from '@/types/model' declare global { const $: $ @@ -9,4 +10,5 @@ declare global { const system: System const worldModel: WorldModel + const CurrentMouseInfo: CurrentMouseInfo } \ No newline at end of file diff --git a/src/types/model.d.ts b/src/types/model.d.ts index be482a2..bc63beb 100644 --- a/src/types/model.d.ts +++ b/src/types/model.d.ts @@ -1,5 +1,27 @@ type LinkType = 'in' | 'out' | 'center' +interface CurrentMouseInfo { + /** + * 当前鼠标所在的设计图 + */ + viewport: any + + /** + * 鼠标在设计图上的 X 坐标 + */ + x: number + + /** + * 鼠标在设计图上的 Y 坐标 + */ + z: number + + /** + * 鼠标在设计图上的坐标, 归一化到 [0, 1] 范围 + */ + mouse: any +} + interface InitThreeOption { stateManagerId: string }