Browse Source

WAY 的渲染, 上下左右调整

master
修宁 6 months ago
parent
commit
654241df77
  1. 2
      package.json
  2. 4
      src/core/Constract.ts
  3. 83
      src/core/ModelUtils.ts
  4. 12
      src/core/controls/MouseMoveInspect.ts
  5. 3
      src/core/controls/SelectInspect.ts
  6. 31
      src/core/manager/StateManager.ts
  7. 34
      src/editor/menus/EditMenu.ts
  8. 6
      src/example/example1.js
  9. 44
      src/modules/way/WayRenderer.ts
  10. 2
      src/runtime/EventBus.ts
  11. 5
      src/types/model.d.ts

2
package.json

@ -1,5 +1,5 @@
{
"name": "yvan-rcs-web",
"name": "yvan-lcc",
"version": "0.1.0",
"private": true,
"type": "module",

4
src/core/Constract.ts

@ -25,6 +25,8 @@ const Constract = Object.freeze({
HEIGHT_GSTORE: 0.03,
HEIGHT_MEASURE: 0.02,
HEIGHT_RACK: 0,
HEIGHT_WAY: 0.01
HEIGHT_WAY: 0.01,
HEIGHT_WAY_LABEL: 0.03,
HEIGHT_WAY_LINE: 0.02
})
export default Constract

83
src/core/ModelUtils.ts

@ -230,6 +230,87 @@ export function findStateItemsByDistance(viewport: Viewport, point: Vector2, dis
})
}
export function moveSelectedItem(direct: '↑' | '↓' | '←' | '→') {
// 获取当前是否按住了 Shift
const viewport: Viewport = window['viewport']
if (!viewport) {
system.msg('没有找到当前视图')
return
}
let delta = 0.25
if (CurrentMouseInfo.isShiftKey || CurrentMouseInfo.isMetaKey) {
// 按住 Shift 键时,移动距离只有0.1
delta = 0.1
}
const entityId = viewport.state.selectedEntityId
if (!entityId) {
const multiSelectedEntityIds = viewport.state.multiSelectedEntityIds
if (!multiSelectedEntityIds && multiSelectedEntityIds.length === 0) {
system.msg('请选中要调整坐标的实体', 'error')
return
}
// 群体移动
const stateManager = viewport.stateManager
stateManager.beginStateUpdate()
for (const item of stateManager.vdata.items) {
if (multiSelectedEntityIds.includes(item.id)) {
// 根据方向移动
switch (direct) {
case '↑':
console.log('向上移动', item.tf[0][2],'-=', delta)
item.tf[0][2] -= delta // 向上移动
break
case '↓':
item.tf[0][2] += delta // 向下移动
break
case '←':
item.tf[0][0] -= delta // 向左移动
break
case '→':
item.tf[0][0] += delta // 向右移动
break
}
}
}
stateManager.endStateUpdate()
EventBus.dispatch('multiselectedObjectChanged', {
multiSelectedObjects: viewport.state.multiSelectedObjects
})
EventBus.dispatch('selectedObjectPropertyChanged', {})
return
}
const stateManager = viewport.stateManager
viewport.stateManager.beginStateUpdate()
for (const item of stateManager.vdata.items) {
if (item.id === entityId) {
// 根据方向移动
switch (direct) {
case '↑':
item.tf[0][2] -= delta // 向上移动
break
case '↓':
item.tf[0][2] += delta // 向下移动
break
case '←':
item.tf[0][0] -= delta // 向左移动
break
case '→':
item.tf[0][0] += delta // 向右移动
break
}
}
}
viewport.stateManager.endStateUpdate()
EventBus.dispatch('multiselectedObjectChanged', {
multiSelectedObjects: viewport.state.multiSelectedObjects
})
EventBus.dispatch('selectedObjectPropertyChanged', {})
}
export function quickCopyByMouse() {
// 获取鼠标位置,查看鼠标是否在某个 viewport 的画布上,并取得该 viewport
if (!CurrentMouseInfo?.viewport ||
@ -484,7 +565,7 @@ function loadObject3DFromJson(items: ItemJson[]): THREE.Object3D[] {
export function decimalSumBy<T>(collection: ArrayLike<T> | null | undefined, iteratee?: ((value: T) => number)): number {
let sum = new Decimal(0)
_.forEach(collection, (t)=>{
_.forEach(collection, (t) => {
if (typeof iteratee === 'function') {
sum = sum.add(new Decimal(iteratee(t)))
} else {

12
src/core/controls/MouseMoveInspect.ts

@ -35,12 +35,16 @@ export default class MouseMoveInspect implements IControls {
lvFn = undefined
}
mouseLv() {
mouseLv(event: MouseEvent) {
this.viewport.state.mouse.x = NaN
this.viewport.state.mouse.z = NaN
window['CurrentMouseInfo'] = {
x: NaN,
z: NaN
z: NaN,
isShiftKey: false,
isCtrlKey: false,
isAltKey: false,
isMetaKey: false
}
}
@ -66,6 +70,10 @@ export default class MouseMoveInspect implements IControls {
viewport: this.viewport,
x: point.x,
z: point.z,
isShiftKey: event.shiftKey,
isCtrlKey: event.ctrlKey,
isAltKey: event.altKey,
isMetaKey: event.metaKey,
mouse: mouse
}

3
src/core/controls/SelectInspect.ts

@ -89,6 +89,9 @@ export default class SelectInspect implements IControls {
EventBus.on('selectedObjectPropertyChanged', (data) => {
this.updateSelectionBox(this.viewport.state.selectedObject)
})
EventBus.on('multiselectedObjectChanged', (data) => {
this.updateMultiSelectionBoxes(data.multiSelectedObjects)
})
EventBus.on('entityDeleted', (data) => {
const id = data.deleteEntityId

31
src/core/manager/StateManager.ts

@ -6,6 +6,7 @@ import { markRaw, reactive, ref } from 'vue'
import type Viewport from '@/core/engine/Viewport.ts'
import { getQueryParams, setQueryParam } from '@/utils/webutils.ts'
import { ensureEntityRelationsConsistency } from '@/core/ModelUtils.ts'
import EventBus from '@/runtime/EventBus.ts'
// 差异类型定义
interface DataDiff {
@ -278,6 +279,11 @@ export default class StateManager {
*
*/
undo() {
const viewport: Viewport = window['viewport']
if (!viewport) {
system.msg('没有找到当前视图')
return
}
if (!this.undoEnabled()) return
const step = this.historySteps[this.historyIndex]
@ -292,6 +298,16 @@ export default class StateManager {
this.pendingChanges = true
system.msg('撤销完成')
if (viewport.state.multiSelectedObjects.length > 0) {
EventBus.dispatch('multiselectedObjectChanged', {
multiSelectedObjects: viewport.state.multiSelectedObjects
})
}
if (viewport.state.selectedObject) {
EventBus.dispatch('selectedObjectPropertyChanged', {
selectedObject: viewport.state.selectedObject
})
}
this.startAutoSave()
}
@ -299,6 +315,11 @@ export default class StateManager {
*
*/
redo() {
const viewport: Viewport = window['viewport']
if (!viewport) {
system.msg('没有找到当前视图')
return
}
if (!this.redoEnabled()) return
this.historyIndex++
@ -312,6 +333,16 @@ export default class StateManager {
this.pendingChanges = true
system.msg('重做完成')
if (viewport.state.multiSelectedObjects.length > 0) {
EventBus.dispatch('multiselectedObjectChanged', {
multiSelectedObjects: viewport.state.multiSelectedObjects
})
}
if (viewport.state.selectedObject) {
EventBus.dispatch('selectedObjectPropertyChanged', {
selectedObject: viewport.state.selectedObject
})
}
this.startAutoSave()
}

34
src/editor/menus/EditMenu.ts

@ -1,7 +1,7 @@
import { renderIcon } from '@/utils/webutils.ts'
import { defineMenu } from '@/runtime/DefineMenu.ts'
import SvgCode from '@/components/icons/SvgCode'
import { escByKeyboard, quickCopyByMouse, deletePointByKeyboard } from '@/core/ModelUtils'
import { escByKeyboard, quickCopyByMouse, deletePointByKeyboard, moveSelectedItem } from '@/core/ModelUtils'
export default defineMenu((menus) => {
menus.insertChildren('modelFile',
@ -88,25 +88,49 @@ export default defineMenu((menus) => {
{
name: 'edit_up', label: '上移', tip: 'key-up',
click() {
system.msg('↑')
moveSelectedItem('↑')
}
},
{
name: 'edit_down', label: '下移', tip: 'key-down',
click() {
system.msg('↓')
moveSelectedItem('↓')
}
},
{
name: 'edit_left', label: '左移', tip: 'key-left',
click() {
system.msg('←')
moveSelectedItem('←')
}
},
{
name: 'edit_right', label: '右移', tip: 'key-right',
click() {
system.msg('→')
moveSelectedItem('→')
}
},
{
name: 'edit_up', label: '上移', tip: 'shift-up',
click() {
moveSelectedItem('↑')
}
},
{
name: 'edit_down', label: '下移', tip: 'shift-down',
click() {
moveSelectedItem('↓')
}
},
{
name: 'edit_left', label: '左移', tip: 'shift-left',
click() {
moveSelectedItem('←')
}
},
{
name: 'edit_right', label: '右移', tip: 'shift-right',
click() {
moveSelectedItem('→')
}
}
]

6
src/example/example1.js

@ -127,12 +127,6 @@ export default {
tf: [[-4, 0.1, 2], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: { in: [], out: [], center: ['6wrGKiVJniwgKkoggOoEy6'] }
}, {
id: '39zML1rnSOOQGQYQ2YUMGy',
t: 'way',
v: true,
tf: [[-4, 0.1, 2], [90, 0, 0], [0.25, 0.25, 0.1]],
dt: { in: [], out: [], center: ['6wrGKiVJniwgKkoggOoEy6'] }
}, {
id: '6wrGKiVJniwgKkoggOoEy6',
t: 'way',
v: true,

44
src/modules/way/WayRenderer.ts

@ -7,6 +7,7 @@ import { getLineId } from '@/core/ModelUtils.ts'
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
import { numberToString } from '@/utils/webutils.ts'
import Constract from '@/core/Constract.ts'
import type { ExtrudeGeometryOptions } from 'three/src/geometries/ExtrudeGeometry'
/**
*
@ -78,16 +79,38 @@ export default class WayRenderer extends BaseRenderer {
)
}
private _createOrUpdateLine(startPosition: THREE.Vector3, endPosition: THREE.Vector3, type: LinkType) {
const width = 1
const halfWidth = width / 2
const path = new THREE.LineCurve3(
new THREE.Vector3(startPosition.x, startPosition.z, halfWidth - Constract.HEIGHT_WAY_LINE),
new THREE.Vector3(endPosition.x, endPosition.z, halfWidth - Constract.HEIGHT_WAY_LINE)
)
const shape = new THREE.Shape()
shape.moveTo(halfWidth, -halfWidth)
shape.lineTo(halfWidth, halfWidth)
const extrudeSettings: ExtrudeGeometryOptions = {
steps: 2, // 沿路径的分段数
depth: 1, // 实际由路径长度决定
bevelEnabled: false, // 禁用倒角
extrudePath: path // 挤出路径
}
const extrudedGeometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
extrudedGeometry.rotateX(Math.PI / 2)
return new THREE.Mesh(extrudedGeometry, this.lineMaterial)
}
createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D[] {
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
const startPosition = new THREE.Vector3(start.tf[0][0], 0, start.tf[0][2])
const endPosition = new THREE.Vector3(end.tf[0][0], 0, end.tf[0][2])
const curve = new THREE.LineCurve3(startPosition, endPosition)
const tubeGeometry = new THREE.TubeGeometry(curve, 1, width / 2, 2, false)
const lineMesh = new THREE.Mesh(tubeGeometry, this.lineMaterial)
const group = new THREE.Group()
const lineMesh = this._createOrUpdateLine(startPosition, endPosition, type)
group.add(lineMesh)
@ -110,7 +133,7 @@ export default class WayRenderer extends BaseRenderer {
label.name = WayRenderer.LABEL_NAME
label.quaternion.copy(this.tempViewport.camera.quaternion)
label.sync()
label.position.set(midPoint.x, midPoint.y, midPoint.z)
label.position.set(midPoint.x, Constract.HEIGHT_WAY_LABEL, midPoint.z)
group.add(label)
@ -122,7 +145,6 @@ export default class WayRenderer extends BaseRenderer {
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)
@ -132,9 +154,7 @@ export default class WayRenderer extends BaseRenderer {
const label: Text = group.children[1]
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)
const lineMesh = this._createOrUpdateLine(startPosition, endPosition, type)
group.add(lineMesh)
const midPoint = new THREE.Vector3()

2
src/runtime/EventBus.ts

@ -2,7 +2,7 @@ import mitt from 'mitt'
const instance = mitt()
export type DispatchNames = 'selectedObjectChanged' |
export type DispatchNames = 'selectedObjectChanged' | 'multiselectedObjectChanged' |
'catalogChanged' |
'dataLoadComplete' |
'entityDeleted' |

5
src/types/model.d.ts

@ -20,6 +20,11 @@ interface CurrentMouseInfo {
* , [0, 1]
*/
mouse: any
isShiftKey: boolean
isCtrlKey: boolean
isAltKey: boolean
isMetaKey: boolean
}
interface InitThreeOption {

Loading…
Cancel
Save