修宁 7 months ago
parent
commit
238ef90228
  1. BIN
      src/assets/images/moveline_point.png
  2. 4
      src/core/ModelUtils.ts
  3. 10
      src/core/base/BaseInteraction.ts
  4. 14
      src/core/base/BaseRenderer.ts
  5. 8
      src/core/controls/MouseMoveInspect.ts
  6. 58
      src/core/engine/SceneHelp.ts
  7. 4
      src/core/engine/Viewport.ts
  8. 4
      src/core/manager/ModuleManager.ts
  9. 17
      src/core/manager/WorldModel.ts
  10. 36
      src/example/example1.js
  11. 68
      src/modules/measure/MeasureRenderer.ts
  12. 2
      src/modules/measure/index.ts
  13. 5
      src/modules/way/WayEntity.ts
  14. 8
      src/modules/way/WayInteraction.ts
  15. 14
      src/modules/way/WayMeta.ts
  16. 199
      src/modules/way/WayRenderer.ts
  17. 15
      src/modules/way/index.ts
  18. 11
      src/types/model.d.ts

BIN
src/assets/images/moveline_point.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

4
src/core/ModelUtils.ts

@ -192,7 +192,9 @@ export function findStateItemsByDistance(viewport: Viewport, point: Vector2, dis
export function quickCopyByMouse() {
// 获取鼠标位置,查看鼠标是否在某个 viewport 的画布上,并取得该 viewport
if (!CurrentMouseInfo?.viewport || !CurrentMouseInfo.x || !CurrentMouseInfo.z) {
if (!CurrentMouseInfo?.viewport ||
isNaN(CurrentMouseInfo.x) || isNaN(CurrentMouseInfo.z) ||
isNaN(CurrentMouseInfo.x) || isNaN(CurrentMouseInfo.z)) {
system.msg('无法获取鼠标位置')
return
}

10
src/core/base/BaseInteraction.ts

@ -92,7 +92,7 @@ export default abstract class BaseInteraction {
if (this.viewport !== viewport) return
// 获取当前鼠标所在位置
if (!CurrentMouseInfo || !CurrentMouseInfo.x || !this.dragItem?.tf?.[0]) {
if (!CurrentMouseInfo || isNaN(CurrentMouseInfo.x) || isNaN(CurrentMouseInfo.z) || !this.dragItem?.tf?.[0]) {
return
}
@ -297,8 +297,8 @@ export default abstract class BaseInteraction {
} else {
const renderer = getRenderer(this.itemTypeName)
const defaultScale = renderer.getDefaultScale()
const defaultRotation = renderer.getDefaultRotation()
const defaultScale = renderer.defaultScale
const defaultRotation = renderer.defaultRotation
// 添加正式点
catchPoint = {
@ -349,8 +349,8 @@ export default abstract class BaseInteraction {
createTempPointMarker(position?: THREE.Vector3): THREE.Mesh {
const p = position
const renderer = getRenderer(this.itemTypeName)
const scale = renderer.getDefaultScale()
const rotation = renderer.getDefaultRotation()
const scale = renderer.defaultScale
const rotation = renderer.defaultRotation
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0x303133, transparent: true, opacity: 0.9 })

14
src/core/base/BaseRenderer.ts

@ -54,9 +54,9 @@ export default abstract class BaseRenderer {
*/
abstract createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D[]
abstract getDefaultScale(): THREE.Vector3
abstract get defaultScale(): THREE.Vector3
abstract getDefaultRotation(): THREE.Vector3
abstract get defaultRotation(): THREE.Vector3
/**
* 线
@ -65,6 +65,12 @@ export default abstract class BaseRenderer {
}
/**
*
*/
afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, objects: THREE.Object3D[]) {
}
/**
* 线
*/
afterDeleteLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, objects: THREE.Object3D[]) {
@ -147,6 +153,7 @@ export default abstract class BaseRenderer {
point.scale.set(item.tf[2][0], item.tf[2][1], item.tf[2][2])
})
this.fillObjectUserDataFromItem(item, ...points)
this.afterCreateOrUpdatePoint(item, option, points)
this.tempViewport.entityManager.appendObject(item.id, points)
this.appendToScene(...points)
@ -194,6 +201,9 @@ export default abstract class BaseRenderer {
point.scale.set(item.tf[2][0], item.tf[2][1], item.tf[2][2])
})
this.fillObjectUserDataFromItem(item, ...objects)
this.afterCreateOrUpdatePoint(item, option, objects)
}
/**

8
src/core/controls/MouseMoveInspect.ts

@ -36,11 +36,11 @@ export default class MouseMoveInspect implements IControls {
}
mouseLv() {
this.viewport.state.mouse.x = 0
this.viewport.state.mouse.z = 0
this.viewport.state.mouse.x = NaN
this.viewport.state.mouse.z = NaN
window['CurrentMouseInfo'] = {
x: 0,
z: 0
x: NaN,
z: NaN
}
}

58
src/core/engine/SceneHelp.ts

@ -1,5 +1,8 @@
import * as THREE from 'three'
import type WorldModel from '@/core/manager/WorldModel'
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry'
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial'
import { Line2 } from 'three/examples/jsm/lines/Line2'
/**
*
@ -7,7 +10,7 @@ import type WorldModel from '@/core/manager/WorldModel'
*/
export default class SceneHelp {
scene: THREE.Scene
axesHelper: THREE.GridHelper
axesHelper: THREE.Group
gridHelper: THREE.GridHelper
worldModel: WorldModel
catalogCode: string
@ -21,25 +24,17 @@ export default class SceneHelp {
this.worldModel = worldModel
this.catalogCode = catalogCode
// 初始化 Three.js 场景
this.scene = new THREE.Scene()
this.scene.background = new THREE.Color(0xeeeeee)
// 辅助线
const gridOption = this.worldModel.gridOption
const axesHelper = new THREE.GridHelper(gridOption.axesSize, gridOption.axesDivisions)
axesHelper.material.color.setHex(gridOption.axesColor)
axesHelper.material.linewidth = 2
axesHelper.material.opacity = gridOption.gridOpacity
axesHelper.material.transparent = true
if (!gridOption.axesEnabled) {
axesHelper.visible = false
}
// @ts-ignore
axesHelper.material.vertexColors = false
this.axesHelper = axesHelper
// 初始化 Three.js 场景
this.scene = new THREE.Scene()
this.scene.background = new THREE.Color(gridOption.backgroundColor)
if (gridOption.axesEnabled) {
this.axesHelper = createAxes(gridOption.axesSize, gridOption.axesColor, gridOption.axesWidth)
this.scene.add(this.axesHelper)
}
const gridHelper = new THREE.GridHelper(gridOption.gridSize, gridOption.gridDivisions)
gridHelper.material.color.setHex(gridOption.gridColor)
@ -137,3 +132,34 @@ export default class SceneHelp {
this.scene = null
}
}
function createAxes(axesSize = 5, axesColor = 0x000000, axesWidth = 2) {
// 创建四个方向的线条几何体
const positions = [
// X 轴(水平)
[new THREE.Vector3(0, 0, 0), new THREE.Vector3(axesSize, 0, 0)], // 向东
[new THREE.Vector3(0, 0, 0), new THREE.Vector3(-axesSize, 0, 0)], // 向西
// Y 轴(垂直)
[new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, axesSize)], // 向北
[new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, -axesSize)] // 向南
]
const group = new THREE.Group()
positions.forEach(([start, end]) => {
const geometry = new LineGeometry()
const pa = new Float32Array([
start.x, start.y, start.z,
end.x, end.y, end.z
])
geometry.setPositions(pa)
const material = new LineMaterial({
color: axesColor,
linewidth: axesWidth,
vertexColors: false
})
const line = new Line2(geometry, material)
group.add(line)
})
return group
}

4
src/core/engine/Viewport.ts

@ -350,10 +350,6 @@ export default class Viewport {
return this.scene.worldModel
}
get axesHelper(): THREE.GridHelper {
return this.scene.axesHelper
}
get gridHelper(): THREE.GridHelper {
return this.scene.gridHelper
}

4
src/core/manager/ModuleManager.ts

@ -23,12 +23,12 @@ window['modules'] = modules
/**
*
*/
export function defineModule(option: ModuleDefineOption): void {
export function defineModule(option: ModuleDefineOption): Promise<any> {
if (modules.has(option.name)) {
throw new Error(`Module with name "${option.name}" is already defined.`)
}
modules.set(option.name, option)
option.renderer.init().finally()
return option.renderer.init()
}
/**

17
src/core/manager/WorldModel.ts

@ -1,7 +1,8 @@
import _ from 'lodash'
import { reactive, watch } from 'vue'
import EventBus from '@/runtime/EventBus'
import localforage from 'localforage'
import Measure from '@/modules/measure'
import Way from '@/modules/way'
import StateManager from '@/core/manager/StateManager.ts'
export interface WorldModelState {
@ -33,16 +34,17 @@ export default class WorldModel {
const data = _.get(this.data, 'Tool.gridHelper')
return _.defaultsDeep(data, {
axesEnabled: true,
axesSize: 1000,
axesDivisions: 4,
axesColor: 0x000000,
axesOpacity: 1,
axesSize: 5,
axesColor: 0xDDDDDD,
axesWidth: 2,
gridEnabled: true, // 启用网格
gridSize: 1000, // 网格大小, 单位米
gridDivisions: 1000, // 网格分割数
gridColor: 0x999999, // 网格颜色, 十六进制颜色值
gridColor: 0xDDDDDD, // 网格颜色, 十六进制颜色值
gridOpacity: 0.8, // 网格透明度
backgroundColor: 0xF5F5F5, // 背景颜色, 十六进制颜色值
snapEnabled: true, // 启用吸附
snapDistance: 0.25 // 吸附距离, 单位米
})
@ -59,7 +61,8 @@ export default class WorldModel {
watch(() => this.state.catalogCode, this.onCatalogCodeChanged.bind(this))
return Promise.all([
import('@/modules/measure')
Measure,
Way
]).then(() => {
console.log('世界模型初始化完成')

36
src/example/example1.js

@ -14,17 +14,17 @@ export default {
],
gridHelper: { // 网格辅助线
axesEnabled: true, // 是否显示中心轴
axesSize: 50, // 中心轴长度
axesDivisions: 2, // 中心轴分割数
axesColor: 0x000000, // 中心轴颜色
axesOpacity: 1, // 中心轴透明度
axesSize: 5,
axesColor: 0xC7C7C7,
axesWidth: 2,
gridEnabled: true, // 是否显示网格
gridSize: 1000, // 网格大小
gridDivisions: 1000, // 网格分割数
gridColor: 0x999999, // 网格颜色
gridOpacity: 0.8, // 网格透明度
gridColor: 0xC7C7C7, // 网格颜色
gridOpacity: 1, // 网格透明度
backgroundColor: 0x24292E, // 背景颜色
snapEnabled: true, // 是否启用吸附
snapDistance: 0.25 // 吸附距离
}
@ -82,8 +82,8 @@ export default {
v: true,
tf: [
[-4, 0.1, 4.75],
[0, 0, 0],
[0.25, 0.1, 0.25]
[90, 0, 0],
[0.25, 0.25, 0.1]
],
dt: {
in: [],
@ -96,8 +96,8 @@ export default {
v: true,
tf: [
[5, 0.1, 2.75],
[0, 0, 0],
[0.25, 0.1, 0.25]
[90, 0, 0],
[0.25, 0.25, 0.1]
],
dt: {
in: [],
@ -110,8 +110,8 @@ export default {
v: true,
tf: [
[5, 0.1, 5.75],
[0, 0, 0],
[0.25, 0.1, 0.25]
[90, 0, 0],
[0.25, 0.25, 0.1]
],
dt: {
in: [],
@ -124,8 +124,8 @@ export default {
v: true,
tf: [
[-1.25, 0.1, 7.25],
[0, 0, 0],
[0.25, 0.1, 0.25]
[90, 0, 0],
[0.25, 0.25, 0.1]
],
dt: {
in: [],
@ -138,8 +138,8 @@ export default {
v: true,
tf: [
[-2, 0.1, 6],
[0, 0, 0],
[0.25, 0.1, 0.25]
[90, 0, 0],
[0.25, 0.25, 0.1]
],
dt: {
in: [],
@ -152,8 +152,8 @@ export default {
v: true,
tf: [
[-3.5, 0.1, 5.25],
[0, 0, 0],
[0.25, 0.1, 0.25]
[90, 0, 0],
[0.25, 0.25, 0.1]
],
dt: {
in: [],

68
src/modules/measure/MeasureRenderer.ts

@ -25,35 +25,52 @@ export default class MeasureRenderer extends BaseRenderer {
public useHtmlLabel = false
pointMaterial: THREE.MeshBasicMaterial
pointMaterial: THREE.Material
lineMaterial: LineMaterial
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(0.25, 0.1, 0.25)
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(0, 0, 0)
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(0.25, 0.25, 0.1)
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(90, 0, 0)
constructor(itemTypeName: string) {
super(itemTypeName)
}
async init() {
this.pointMaterial = new THREE.MeshBasicMaterial({ color: 0x303133, transparent: true, opacity: 0.9 })
this.pointMaterial = new THREE.SpriteMaterial({
color: 0xFFFF99, // 0x303133,
transparent: true,
side: THREE.DoubleSide,
opacity: 1,
sizeAttenuation: true
})
this.lineMaterial = new LineMaterial({
color: 0xE63C17, // 主颜色
linewidth: 2, // 实际可用的线宽
vertexColors: true, // 启用顶点颜色
dashed: false,
alphaToCoverage: true
color: 0xFF8C00,
linewidth: 1,
vertexColors: false,
dashed: false
})
return Promise.all([
super.init(),
this.loadFont()
super.init()
])
}
async loadFont() {
return Promise.resolve()
/**
* 使,
*/
override afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, objects: THREE.Object3D[]) {
super.afterCreateOrUpdatePoint(item, option, objects)
const point = objects[0]
point.scale.set(this.defaultScale.x, this.defaultScale.y, this.defaultScale.z)
point.rotation.set(
THREE.MathUtils.degToRad(this.defaultRotation.x),
THREE.MathUtils.degToRad(this.defaultRotation.y),
THREE.MathUtils.degToRad(this.defaultRotation.z)
)
}
createLineBasic(start: ItemJson, end: ItemJson, type: LinkType): THREE.Object3D[] {
const geom = new LineGeometry()
const obj = new Line2(geom, this.lineMaterial)
@ -65,11 +82,16 @@ export default class MeasureRenderer extends BaseRenderer {
}
createPointBasic(item: ItemJson, option?: RendererCudOption): THREE.Object3D[] {
const tt = new THREE.BoxGeometry(1, 1, 1)
const obj = new THREE.Mesh(tt, this.pointMaterial)
// const tt = new THREE.BoxGeometry(1, 1, 1)
// const obj = new THREE.Mesh(tt, this.movelinePoint)
// obj.name = MeasureRenderer.POINT_NAME
// obj.uuid = item.id
//
// return [obj]
// 创建平面几何体
const obj = new THREE.Sprite(this.pointMaterial as THREE.SpriteMaterial)
obj.name = MeasureRenderer.POINT_NAME
obj.uuid = item.id
return [obj]
}
@ -102,7 +124,7 @@ export default class MeasureRenderer extends BaseRenderer {
const p1 = endPoint.position
const dist = p0.distanceTo(p1)
const label = `${numberToString(dist)} m`
const label = numberToString(dist) + ' m'
const position = new THREE.Vector3().addVectors(p0, p1).multiplyScalar(0.5)
let labelObj: Text | CSS2DObject | undefined = objects[0].userData.labelObj
@ -161,7 +183,7 @@ export default class MeasureRenderer 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'
@ -178,14 +200,6 @@ export default class MeasureRenderer extends BaseRenderer {
}
}
getDefaultScale(): THREE.Vector3 {
return this.defaultScale
}
getDefaultRotation(): THREE.Vector3 {
return this.defaultRotation
}
dispose() {
super.dispose()

2
src/modules/measure/index.ts

@ -6,7 +6,7 @@ import MeasureInteraction from './MeasureInteraction.ts'
export const ITEM_TYPE_NAME = 'measure'
defineModule({
export default defineModule({
name: ITEM_TYPE_NAME,
renderer: new MeasureRenderer(ITEM_TYPE_NAME),
interaction: new MeasureInteraction(ITEM_TYPE_NAME),

5
src/modules/way/WayEntity.ts

@ -0,0 +1,5 @@
import BaseEntity from '@/core/base/BaseItemEntity.ts'
export default class WayEntity extends BaseEntity {
}

8
src/modules/way/WayInteraction.ts

@ -0,0 +1,8 @@
import BaseInteraction from '@/core/base/BaseInteraction.ts'
export default class WayInteraction extends BaseInteraction {
constructor(itemTypeName: string) {
super(itemTypeName)
}
}

14
src/modules/way/WayMeta.ts

@ -0,0 +1,14 @@
import type { IMeta } from '@/core/base/IMeta.ts'
export default [
{ field: 'uuid', editor: 'UUID', label: 'uuid', readonly: true, category: 'basic' },
{ field: 'name', editor: 'TextInput', label: '名称', category: 'basic' },
{ field: 'dt.label', editor: 'TextInput', label: '标签', category: 'basic' },
{ editor: 'TransformEditor', category: 'basic' },
{ field: 'dt.color', editor: 'Color', label: '颜色', category: 'basic' },
{ editor: '-', category: 'basic' },
{ field: 'tf', editor: 'InOutCenterEditor', category: 'basic' },
{ field: 'dt.selectable', editor: 'Switch', label: '可选中', category: 'basic' },
{ field: 'dt.protected', editor: 'Switch', label: '受保护', category: 'basic' },
{ field: 'visible', editor: 'Switch', label: '可见', category: 'basic' }
] as IMeta

199
src/modules/way/WayRenderer.ts

@ -0,0 +1,199 @@
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'
/**
*
*/
export default class WayRenderer extends BaseRenderer {
static LABEL_NAME = 'way_label'
static POINT_NAME = 'way_point'
static LINE_NAME = 'way_line'
public useHtmlLabel = false
pointMaterial: THREE.Material
lineMaterial: LineMaterial
readonly defaultScale: THREE.Vector3 = new THREE.Vector3(0.5, 0.5, 0.1)
readonly defaultRotation: THREE.Vector3 = new THREE.Vector3(90, 0, 0)
constructor(itemTypeName: string) {
super(itemTypeName)
}
async init() {
this.lineMaterial = new LineMaterial({
color: 0xE63C17, // 主颜色
linewidth: 2, // 实际可用的线宽
vertexColors: true, // 启用顶点颜色
dashed: false,
alphaToCoverage: true
})
return Promise.all([
super.init(),
this.loadFont()
])
}
async loadFont() {
return new Promise<void>((resolve, reject) => {
new THREE.TextureLoader().load(
MoveLinePointPng,
(texture) => {
this.pointMaterial = new THREE.SpriteMaterial({
map: texture,
transparent: true,
side: THREE.DoubleSide
})
resolve()
},
undefined,
function(err) {
reject(err)
}
)
})
}
/**
* 使,
*/
override afterCreateOrUpdatePoint(item: ItemJson, option: RendererCudOption, objects: THREE.Object3D[]) {
super.afterCreateOrUpdatePoint(item, option, objects)
const point = objects[0]
point.scale.set(this.defaultScale.x, this.defaultScale.y, this.defaultScale.z)
point.rotation.set(
THREE.MathUtils.degToRad(this.defaultRotation.x),
THREE.MathUtils.degToRad(this.defaultRotation.y),
THREE.MathUtils.degToRad(this.defaultRotation.z)
)
}
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)
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')
this.tempViewport?.scene.add(...objects)
}
afterCreateOrUpdateLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, objects: THREE.Object3D[]) {
super.afterCreateOrUpdateLine(start, end, type, option, objects)
const startPoint = this.tempViewport?.entityManager.findObjectsById(start.id)?.[0]
const endPoint = this.tempViewport?.entityManager.findObjectsById(end.id)?.[0]
const p0 = startPoint.position
const p1 = endPoint.position
const dist = p0.distanceTo(p1)
const label = `${numberToString(dist)} m`
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)
objects[0].userData.labelObj = labelObj
}
labelObj.position.set(position.x, position.y + 0.3, position.z - 0.2)
if (this.useHtmlLabel) {
labelObj.element.innerHTML = label
} else {
// 让文本朝向摄像机
labelObj.quaternion.copy(this.tempViewport.camera.quaternion)
labelObj.text = label
labelObj.sync()
}
}
afterDeleteLine(start: ItemJson, end: ItemJson, type: LinkType, option: RendererCudOption, objects: THREE.Object3D[]) {
super.afterDeleteLine(start, end, type, option, objects)
// 删除标签
const labelObj = objects[0]?.userData?.labelObj
if (labelObj && labelObj.parent) {
labelObj.parent.remove(labelObj)
}
}
/**
*
*/
createLabel(text: string): Text | CSS2DObject {
if (this.useHtmlLabel) {
const div = document.createElement('div')
div.className = 'css2dObjectLabel'
div.innerHTML = text
div.style.padding = '5px 8px'
div.style.color = '#fff'
div.style.fontSize = '14px'
div.style.position = 'absolute'
div.style.backgroundColor = 'rgba(25, 25, 25, 0.3)'
div.style.borderRadius = '12px'
div.style.top = '0px'
div.style.left = '0px'
// div.style.pointerEvents = 'none' //避免HTML元素影响场景的鼠标事件
const obj = new CSS2DObject(div)
obj.name = WayRenderer.LABEL_NAME
return obj
} else {
const label = new Text()
label.text = text
label.font = SimSunTTF
label.fontSize = 0.4
label.color = '#ff0000'
label.opacity = 0.8
label.padding = 0.2
label.anchorX = 'center'
label.anchorY = 'middle'
label.depthOffset = 1
label.backgroundColor = '#000000' // 黑色背景
label.backgroundOpacity = 0.6 // 背景半透明
label.padding = 0.2 // 内边距
label.material.depthTest = false
label.name = WayRenderer.LABEL_NAME
label.sync()
return label
}
}
dispose() {
super.dispose()
this.pointMaterial.dispose()
this.lineMaterial.dispose()
}
}

15
src/modules/way/index.ts

@ -0,0 +1,15 @@
import { defineModule } from '@/core/manager/ModuleManager.ts'
import WayRenderer from './WayRenderer.ts'
import WayEntity from './WayEntity.ts'
import WayMeta from './WayMeta.ts'
import WayInteraction from './WayInteraction.ts'
export const ITEM_TYPE_NAME = 'way'
export default defineModule({
name: ITEM_TYPE_NAME,
renderer: new WayRenderer(ITEM_TYPE_NAME),
interaction: new WayInteraction(ITEM_TYPE_NAME),
meta: WayMeta,
entity: WayEntity
})

11
src/types/model.d.ts

@ -57,17 +57,13 @@ interface IGridHelper {
*/
axesSize: number;
/**
*
*/
axesDivisions: number;
/**
* ,
*/
axesColor: number;
/**
*
*/
axesOpacity: number;
axesWidth: number;
/**
*
@ -91,6 +87,11 @@ interface IGridHelper {
gridOpacity: number;
/**
* ,
*/
backgroundColor: number;
/**
*
*/
snapEnabled: boolean;

Loading…
Cancel
Save