Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

optimize spline helper #10295

Merged
merged 5 commits into from
Jun 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 58 additions & 65 deletions packages/engine/src/scene/components/debug/SplineHelperComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,45 +24,34 @@ Ethereal Engine. All Rights Reserved.
*/

import { useEffect } from 'react'
import {
BufferAttribute,
BufferGeometry,
Line,
LineBasicMaterial,
Mesh,
MeshBasicMaterial,
SphereGeometry,
Vector3
} from 'three'
import { BufferAttribute, BufferGeometry, Line, LineBasicMaterial, MeshBasicMaterial, Vector3 } from 'three'

import {
createEntity,
defineComponent,
Entity,
removeEntity,
setComponent,
useComponent,
useEntityContext
} from '@etherealengine/ecs'
import { TransformComponent } from '@etherealengine/spatial'
import { AxesHelperComponent } from '@etherealengine/spatial/src/common/debug/AxesHelperComponent'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { addObjectToGroup } from '@etherealengine/spatial/src/renderer/components/GroupComponent'
import { ObjectLayerMaskComponent } from '@etherealengine/spatial/src/renderer/components/ObjectLayerComponent'
import { setVisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
import { ObjectLayerMasks } from '@etherealengine/spatial/src/renderer/constants/ObjectLayers'
import { useDisposable, useResource } from '@etherealengine/spatial/src/resources/resourceHooks'
import { useResource } from '@etherealengine/spatial/src/resources/resourceHooks'
import { EntityTreeComponent } from '@etherealengine/spatial/src/transform/components/EntityTree'

import { SplineComponent } from '../SplineComponent'

const ARC_SEGMENTS = 200
const _point = new Vector3()

const lineGeometry = new BufferGeometry()
lineGeometry.setAttribute('position', new BufferAttribute(new Float32Array(ARC_SEGMENTS * 3), 3))
const lineMaterial = new LineBasicMaterial({ color: 0xff0000, opacity: 0.35 })

const lineMaterial = new LineBasicMaterial({ color: 'white', opacity: 0.35 })
const createLineGeom = () => {
const lineGeometry = new BufferGeometry()
lineGeometry.setAttribute('position', new BufferAttribute(new Float32Array(ARC_SEGMENTS * 3), 3))
return lineGeometry
}
const greenMeshMaterial = () => new MeshBasicMaterial({ color: 'lightgreen', opacity: 0.2 })
const redMeshMaterial = () => new MeshBasicMaterial({ color: 'red', opacity: 0.2 })

Expand All @@ -75,39 +64,43 @@ export const SplineHelperComponent = defineComponent({

onSet: (entity, component, json) => {
if (!json) return
if (typeof json.layerMask == 'number') component.layerMask.set(json.layerMask)
if (typeof json.layerMask === 'number') component.layerMask.set(json.layerMask)
},

reactor: function () {
const entity = useEntityContext()
const component = useComponent(entity, SplineHelperComponent)
const spline = useComponent(entity, SplineComponent)
const [sphereGeometry] = useResource(() => new SphereGeometry(0.05, 4, 2), entity)

const [greenMat] = useResource(greenMeshMaterial, entity)
const [greenSphere] = useDisposable(
Mesh,
entity,
sphereGeometry.value as SphereGeometry,
greenMat.value as MeshBasicMaterial
)

const [redMat] = useResource(redMeshMaterial, entity)
const [redSphere] = useDisposable(
Mesh,
entity,
sphereGeometry.value as SphereGeometry,
redMat.value as MeshBasicMaterial
)

const [lineGeometry] = useResource(createLineGeom, entity)
/** @todo these are probably unnecessary and were just used for debugging the implementation */
HexaField marked this conversation as resolved.
Show resolved Hide resolved
// const [sphereGeometry] = useResource(() => new SphereGeometry(0.05, 4, 2), entity)

// const [greenMat] = useResource(greenMeshMaterial, entity)
// const [greenSphere] = useDisposable(
// Mesh,
// entity,
// sphereGeometry.value as SphereGeometry,
// greenMat.value as MeshBasicMaterial
// )

// const [redMat] = useResource(redMeshMaterial, entity)
// const [redSphere] = useDisposable(
// Mesh,
// entity,
// sphereGeometry.value as SphereGeometry,
// redMat.value as MeshBasicMaterial
// )

useEffect(() => {
const gizmoEntities = [] as Entity[]
// const gizmoEntities = [] as Entity[]
const curve = spline.curve.value
const elements = spline.elements
if (elements.length < 3) return
const lineEntity = createEntity()

// Geometry and material are created in module scope and reused, do not dispose
const line = new Line(lineGeometry, lineMaterial)
const line = new Line(lineGeometry.value as BufferGeometry, lineMaterial)
line.name = `SplineHelperComponent-${entity}`

addObjectToGroup(lineEntity, line)
Expand All @@ -116,31 +109,31 @@ export const SplineHelperComponent = defineComponent({

setVisibleComponent(lineEntity, true)

if (elements.length > 0) {
const first = elements[0].value
greenSphere.position.copy(first.position)
addObjectToGroup(lineEntity, greenSphere)
}

if (elements.length > 1) {
const last = elements[elements.length - 1].value
redSphere.position.copy(last.position)
addObjectToGroup(lineEntity, redSphere)
}

let id = 0
for (const elem of elements.value) {
const gizmoEntity = createEntity()
gizmoEntities.push(gizmoEntity)
setComponent(gizmoEntity, EntityTreeComponent, { parentEntity: lineEntity })
setComponent(gizmoEntity, TransformComponent, {
position: elem.position,
rotation: elem.quaternion
})
setComponent(gizmoEntity, AxesHelperComponent, { name: `spline-gizmo-${++id}` })
}

setComponent(lineEntity, ObjectLayerMaskComponent, component.layerMask.value)
// if (elements.length > 0) {
// const first = elements[0].value
// greenSphere.position.copy(first.position)
// addObjectToGroup(lineEntity, greenSphere)
// }

// if (elements.length > 1) {
// const last = elements[elements.length - 1].value
// redSphere.position.copy(last.position)
// addObjectToGroup(lineEntity, redSphere)
// }

// let id = 0
// for (const elem of elements.value) {
// const gizmoEntity = createEntity()
// gizmoEntities.push(gizmoEntity)
// setComponent(gizmoEntity, EntityTreeComponent, { parentEntity: lineEntity })
// setComponent(gizmoEntity, TransformComponent, {
// position: elem.position,
// rotation: elem.quaternion
// })
// setComponent(gizmoEntity, AxesHelperComponent, { name: `spline-gizmo-${++id}` })
// }

// setComponent(lineEntity, ObjectLayerMaskComponent, component.layerMask.value)

const positions = line.geometry.attributes.position
for (let i = 0; i < ARC_SEGMENTS; i++) {
Expand All @@ -152,7 +145,7 @@ export const SplineHelperComponent = defineComponent({

return () => {
if (lineEntity) removeEntity(lineEntity)
for (const gizmoEntity of gizmoEntities) removeEntity(gizmoEntity)
// for (const gizmoEntity of gizmoEntities) removeEntity(gizmoEntity)
}
}, [spline.curve, component.layerMask])

Expand Down
Loading