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

Commit

Permalink
Transform Gizmo uses Spatial Input (#9832)
Browse files Browse the repository at this point in the history
* Transform Gizmo uses Spatial Input
Fixes #9775

* ensure up on context loss

* gizmo query tag, gizmo heuristic, fix to cross selection

* remove comments

* fix plane layer

* move gizmo tag component to spatial package

---------

Co-authored-by: HexaField <joshfield999@gmail.com>
  • Loading branch information
SYBIOTE and HexaField authored Mar 6, 2024
1 parent 36b1396 commit 8cbdf53
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 108 deletions.
100 changes: 60 additions & 40 deletions packages/editor/src/classes/TransformGizmoControlComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,18 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import { Entity, UndefinedEntity, defineComponent, useComponent, useEntityContext } from '@etherealengine/ecs'
import {
Entity,
InputSystemGroup,
UndefinedEntity,
defineComponent,
getComponent,
getOptionalComponent,
setComponent,
useComponent,
useEntityContext,
useExecute
} from '@etherealengine/ecs'
import {
SnapMode,
TransformAxisType,
Expand All @@ -33,21 +44,22 @@ import {
TransformSpaceType
} from '@etherealengine/engine/src/scene/constants/transformConstants'
import { getMutableState, matches, useHookstate } from '@etherealengine/hyperflux'
import { InputComponent } from '@etherealengine/spatial/src/input/components/InputComponent'
import { InputSourceComponent } from '@etherealengine/spatial/src/input/components/InputSourceComponent'
import { EngineRenderer } from '@etherealengine/spatial/src/renderer/WebGLRendererSystem'
import { addObjectToGroup } from '@etherealengine/spatial/src/renderer/components/GroupComponent'
import { setObjectLayers } from '@etherealengine/spatial/src/renderer/components/ObjectLayerComponent'
import { ObjectLayers } from '@etherealengine/spatial/src/renderer/constants/ObjectLayers'
import { TransformGizmoTagComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent'
import { useEffect } from 'react'
import { DoubleSide, Mesh, MeshBasicMaterial, PlaneGeometry, Quaternion, Vector3 } from 'three'
import { degToRad } from 'three/src/math/MathUtils'
import { DoubleSide, MathUtils, Mesh, MeshBasicMaterial, PlaneGeometry, Quaternion, Vector3 } from 'three'
import { onPointerDown, onPointerHover, onPointerMove, onPointerUp } from '../functions/gizmoHelper'
import { EditorHelperState } from '../services/EditorHelperState'
import { TransformGizmoVisualComponent } from './TransformGizmoVisualComponent'

export const TransformGizmoControlComponent = defineComponent({
name: 'TransformGizmoControl',

onInit(entity) {
//const control = new TransformControls()
const control = {
controlledEntities: [] as Entity[],
visualEntity: UndefinedEntity,
Expand Down Expand Up @@ -105,15 +117,45 @@ export const TransformGizmoControlComponent = defineComponent({
component.pivotEntity.set(UndefinedEntity)
},
reactor: function (props) {
const gizmoEntity = useEntityContext()
const gizmoControlComponent = useComponent(gizmoEntity, TransformGizmoControlComponent)
const gizmoControlEntity = useEntityContext()
const gizmoControlComponent = useComponent(gizmoControlEntity, TransformGizmoControlComponent)

//const gizmoEntity = createEntity()
const domElement = EngineRenderer.instance.renderer.domElement
domElement.style.touchAction = 'none' // disable touch scroll , hmm the editor window isnt scrollable anyways
EngineRenderer.instance.renderer.domElement.style.touchAction = 'none' // disable touch scroll , hmm the editor window isnt scrollable anyways

//temp variables
const editorHelperState = useHookstate(getMutableState(EditorHelperState))
useExecute(
() => {
const gizmoControlComponent = getComponent(gizmoControlEntity, TransformGizmoControlComponent)
if (!gizmoControlComponent.enabled) return
if (!gizmoControlComponent.visualEntity) return
if (!gizmoControlComponent.planeEntity) return

const visualComponent = getComponent(gizmoControlComponent.visualEntity, TransformGizmoVisualComponent)
const pickerInputSourceEntity = getComponent(visualComponent.picker[TransformMode.translate], InputComponent)
.inputSources[0]
const planeInputSourceEntity = getComponent(gizmoControlComponent.planeEntity, InputComponent).inputSources[0]
if (pickerInputSourceEntity === undefined && planeInputSourceEntity === undefined) {
onPointerUp(gizmoControlEntity)
return
}
onPointerHover(gizmoControlEntity)

const pickerButtons = getOptionalComponent(pickerInputSourceEntity, InputSourceComponent)?.buttons
const planeButtons = getOptionalComponent(planeInputSourceEntity, InputSourceComponent)?.buttons

if (!pickerButtons && !planeButtons) {
onPointerUp(gizmoControlEntity)
return
}

if (!pickerButtons?.PrimaryClick?.touched && !planeButtons?.PrimaryClick?.touched) return

onPointerMove(gizmoControlEntity)
if (planeButtons?.PrimaryClick?.up || pickerButtons?.PrimaryClick?.up) onPointerUp(gizmoControlEntity)
else if (pickerButtons?.PrimaryClick?.down) onPointerDown(gizmoControlEntity)
},
{ with: InputSystemGroup }
)

useEffect(() => {
const plane = new Mesh(
Expand All @@ -128,34 +170,10 @@ export const TransformGizmoControlComponent = defineComponent({
})
)

// create dummy object to attach gizmo to, we can only attach to three js objects
domElement.addEventListener('pointerdown', (event) => {
onPointerDown(event, gizmoEntity)
})
domElement.addEventListener('pointermove', (event) => {
onPointerHover(event, gizmoEntity)
})
domElement.addEventListener('pointerup', (event) => {
onPointerUp(event, gizmoEntity)
})

addObjectToGroup(gizmoControlComponent.planeEntity.value, plane)
setObjectLayers(plane, ObjectLayers.TransformGizmo)

return () => {
domElement.removeEventListener('pointerdown', (event) => {
onPointerDown(event, gizmoEntity)
})
domElement.removeEventListener('pointerhover', (event) => {
onPointerHover(event, gizmoEntity)
})
domElement.removeEventListener('pointermove', (event) => {
onPointerMove(event, gizmoEntity)
})
domElement.removeEventListener('pointerup', (event) => {
onPointerUp(event, gizmoEntity)
})
}
plane.layers.set(ObjectLayers.TransformGizmo)
setComponent(gizmoControlComponent.planeEntity.value, InputComponent)
setComponent(gizmoControlComponent.planeEntity.value, TransformGizmoTagComponent)
}, [])

useEffect(() => {
Expand All @@ -177,7 +195,7 @@ export const TransformGizmoControlComponent = defineComponent({
break
case SnapMode.Grid:
gizmoControlComponent.translationSnap.set(editorHelperState.translationSnap.value)
gizmoControlComponent.rotationSnap.set(degToRad(editorHelperState.rotationSnap.value))
gizmoControlComponent.rotationSnap.set(MathUtils.degToRad(editorHelperState.rotationSnap.value))
gizmoControlComponent.scaleSnap.set(editorHelperState.scaleSnap.value)
break
}
Expand All @@ -191,7 +209,9 @@ export const TransformGizmoControlComponent = defineComponent({

useEffect(() => {
gizmoControlComponent.rotationSnap.set(
editorHelperState.gridSnap.value === SnapMode.Grid ? degToRad(editorHelperState.rotationSnap.value) : 0
editorHelperState.gridSnap.value === SnapMode.Grid
? MathUtils.degToRad(editorHelperState.rotationSnap.value)
: 0
)
}, [editorHelperState.rotationSnap])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { TransformComponent } from '@etherealengine/spatial'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
import { EntityTreeComponent } from '@etherealengine/spatial/src/transform/components/EntityTree'
import { TransformGizmoTagComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent'
import { useHookstate } from '@hookstate/core'
import { useEffect } from 'react'
import { Box3, Vector3 } from 'three'
Expand Down Expand Up @@ -69,6 +70,8 @@ export const TransformGizmoControlledComponent = defineComponent({
setComponent(pivotEntity, TransformComponent)
setComponent(pivotEntity, VisibleComponent)
setComponent(pivotEntity, EntityTreeComponent)
setComponent(pivotEntity, TransformGizmoTagComponent)

/*addObjectToGroup(
pivotEntity,
new Mesh(new SphereGeometry(1.5, 32, 32), new MeshBasicMaterial({ color: 0xff0000 }))
Expand All @@ -89,13 +92,18 @@ export const TransformGizmoControlledComponent = defineComponent({
visualEntity: gizmoVisualEntity,
planeEntity: gizmoPlaneEntity
})
setComponent(gizmoControlEntity, TransformGizmoTagComponent)
setComponent(gizmoControlEntity, VisibleComponent)

transformGizmoControlledComponent.controller.set(gizmoControlEntity)

setComponent(gizmoVisualEntity, NameComponent, 'gizmoVisualEntity')
setComponent(gizmoVisualEntity, TransformGizmoVisualComponent)
setComponent(gizmoVisualEntity, TransformGizmoTagComponent)
setComponent(gizmoVisualEntity, VisibleComponent)

setComponent(gizmoPlaneEntity, NameComponent, 'gizmoPlaneEntity')
setComponent(gizmoPlaneEntity, TransformGizmoTagComponent)
setComponent(gizmoPlaneEntity, VisibleComponent) // needed for raycasting

return () => {
Expand Down
14 changes: 9 additions & 5 deletions packages/editor/src/classes/TransformGizmoVisualComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ import {
} from '@etherealengine/ecs'
import { TransformMode } from '@etherealengine/engine/src/scene/constants/transformConstants'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { InputComponent } from '@etherealengine/spatial/src/input/components/InputComponent'
import { addObjectToGroup, removeObjectFromGroup } from '@etherealengine/spatial/src/renderer/components/GroupComponent'
import { setObjectLayers } from '@etherealengine/spatial/src/renderer/components/ObjectLayerComponent'
import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
import { ObjectLayers } from '@etherealengine/spatial/src/renderer/constants/ObjectLayers'
import { TransformGizmoTagComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent'
import { useEffect } from 'react'
import {
BoxGeometry,
Expand Down Expand Up @@ -364,7 +365,7 @@ export const TransformGizmoVisualComponent = defineComponent({
tempGeometry.applyMatrix4(object.matrix)
object.geometry = tempGeometry
object.renderOrder = Infinity

object.layers.set(ObjectLayers.TransformGizmo)
object.position.set(0, 0, 0)
object.rotation.set(0, 0, 0)
object.scale.set(1, 1, 1)
Expand Down Expand Up @@ -393,22 +394,25 @@ export const TransformGizmoVisualComponent = defineComponent({
for (const mode in TransformMode) {
setComponent(gizmo[mode], NameComponent, `gizmo${mode}Entity`)
addObjectToGroup(gizmo[mode], gizmoObject[mode])
setComponent(gizmo[mode], TransformGizmoTagComponent)
setComponent(gizmo[mode], VisibleComponent)
setObjectLayers(gizmoObject[mode], ObjectLayers.TransformGizmo)

visualComponent.gizmo[mode].set(gizmo[mode])

setComponent(helper[mode], NameComponent, `gizmoHelper${mode}Entity`)
addObjectToGroup(helper[mode], helperObject[mode])
setComponent(helper[mode], TransformGizmoTagComponent)
setComponent(helper[mode], VisibleComponent)
setObjectLayers(helperObject[mode], ObjectLayers.TransformGizmo)

visualComponent.helper[mode].set(helper[mode])

setComponent(picker[mode], NameComponent, `gizmoPicker${mode}Entity`)
pickerObject[mode].visible = false
addObjectToGroup(picker[mode], pickerObject[mode])
setComponent(picker[mode], TransformGizmoTagComponent)
setComponent(picker[mode], VisibleComponent)
setObjectLayers(pickerObject[mode], ObjectLayers.TransformGizmo)
visualComponent.picker[mode].set(picker[mode])
setComponent(picker[mode], InputComponent)
}

return () => {
Expand Down
Loading

0 comments on commit 8cbdf53

Please sign in to comment.