Skip to content
This repository was archived by the owner on Aug 21, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
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
12 changes: 0 additions & 12 deletions packages/editor/src/components/properties/CoreNodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
useOptionalComponent
} from '@etherealengine/engine/src/ecs/functions/ComponentFunctions'
import { EntityOrObjectUUID, getEntityNodeArrayFromEntities } from '@etherealengine/engine/src/ecs/functions/EntityTree'
import { PreventBakeTagComponent } from '@etherealengine/engine/src/scene/components/PreventBakeTagComponent'
import { SceneTagComponent } from '@etherealengine/engine/src/scene/components/SceneTagComponent'
import { VisibleComponent } from '@etherealengine/engine/src/scene/components/VisibleComponent'
import { dispatchAction, getMutableState } from '@etherealengine/hyperflux'
Expand Down Expand Up @@ -60,7 +59,6 @@ export const CoreNodeEditor: EditorComponentType = (props) => {
const editorState = useEditorState()

useOptionalComponent(props.entity, VisibleComponent)
useOptionalComponent(props.entity, PreventBakeTagComponent)

const onChangeVisible = (value) => {
const nodes = getEntityNodeArrayFromEntities(getMutableState(SelectionState).selectedEntities.value).filter(
Expand All @@ -69,13 +67,6 @@ export const CoreNodeEditor: EditorComponentType = (props) => {
EditorControlFunctions.addOrRemoveComponent(nodes, VisibleComponent, value)
}

const onChangeBakeStatic = (value) => {
const nodes = getEntityNodeArrayFromEntities(getMutableState(SelectionState).selectedEntities.value).filter(
(n) => typeof n === 'number'
) as EntityOrObjectUUID[]
EditorControlFunctions.addOrRemoveComponent(nodes, PreventBakeTagComponent, value)
}

const registeredComponents = Array.from(Engine.instance.sceneComponentRegistry.entries())

return (
Expand All @@ -87,9 +78,6 @@ export const CoreNodeEditor: EditorComponentType = (props) => {
<VisibleInputGroup name="Visible" label={t('editor:properties.lbl-visible')}>
<BooleanInput value={hasComponent(props.entity, VisibleComponent)} onChange={onChangeVisible} />
</VisibleInputGroup>
<VisibleInputGroup name="Prevent Baking" label={t('editor:properties.lbl-preventBake')}>
<BooleanInput value={hasComponent(props.entity, PreventBakeTagComponent)} onChange={onChangeBakeStatic} />
</VisibleInputGroup>
</>
)}
</NameInputGroupContainer>
Expand Down
1 change: 0 additions & 1 deletion packages/editor/src/components/properties/EnvMapEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { getComponent, useComponent } from '@etherealengine/engine/src/ecs/funct
import { EnvmapComponent, SCENE_COMPONENT_ENVMAP } from '@etherealengine/engine/src/scene/components/EnvmapComponent'
import { ErrorComponent, getEntityErrors } from '@etherealengine/engine/src/scene/components/ErrorComponent'
import { EnvMapSourceType, EnvMapTextureType } from '@etherealengine/engine/src/scene/constants/EnvMapEnum'
import { deserializeEnvMap } from '@etherealengine/engine/src/scene/functions/loaders/EnvMapFunctions'

import ColorInput from '../inputs/ColorInput'
import CompoundNumericInput from '../inputs/CompoundNumericInput'
Expand Down
23 changes: 6 additions & 17 deletions packages/editor/src/functions/EditorControlFunctions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,31 @@ import { Vector3 } from 'three'
import { destroyEngine, Engine } from '@etherealengine/engine/src/ecs/classes/Engine'
import {
addComponent,
createMappedComponent,
defineComponent,
getComponent,
hasComponent,
setComponent
} from '@etherealengine/engine/src/ecs/functions/ComponentFunctions'
import { createEntity, entityExists } from '@etherealengine/engine/src/ecs/functions/EntityFunctions'
import { createEntity } from '@etherealengine/engine/src/ecs/functions/EntityFunctions'
import { addEntityNodeChild, EntityTreeComponent } from '@etherealengine/engine/src/ecs/functions/EntityTree'
import { createEngine } from '@etherealengine/engine/src/initializeEngine'
import { GroupComponent, SCENE_COMPONENT_GROUP } from '@etherealengine/engine/src/scene/components/GroupComponent'
import { NameComponent } from '@etherealengine/engine/src/scene/components/NameComponent'
import { SCENE_COMPONENT_VISIBLE, VisibleComponent } from '@etherealengine/engine/src/scene/components/VisibleComponent'
import { SCENE_COMPONENT_VISIBLE } from '@etherealengine/engine/src/scene/components/VisibleComponent'
import { ScenePrefabs } from '@etherealengine/engine/src/scene/systems/SceneObjectUpdateSystem'
import {
SCENE_COMPONENT_TRANSFORM,
SCENE_COMPONENT_TRANSFORM_DEFAULT_VALUES,
TransformComponent
SCENE_COMPONENT_TRANSFORM_DEFAULT_VALUES
} from '@etherealengine/engine/src/transform/components/TransformComponent'
import { applyIncomingActions, getState } from '@etherealengine/hyperflux'

import { registerEditorReceptors, unregisterEditorReceptors } from '../services/EditorServicesReceptor'
import { registerEditorReceptors } from '../services/EditorServicesReceptor'
import { EditorControlFunctions } from './EditorControlFunctions'

import '@etherealengine/engine/src/patchEngineNode'

import { Entity } from '@etherealengine/engine/src/ecs/classes/Entity'
import { SceneState } from '@etherealengine/engine/src/ecs/classes/Scene'
import { deserializeGroup } from '@etherealengine/engine/src/scene/functions/loaders/GroupFunctions'

import { createTransformGizmo } from '../systems/EditorControlSystem'

class TempProp {
data: number
Expand Down Expand Up @@ -146,10 +141,7 @@ describe('EditorControlFunctions', () => {
])

Engine.instance.sceneComponentRegistry.set(GroupComponent.name, SCENE_COMPONENT_GROUP)
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_GROUP, {
deserialize: deserializeGroup,
serialize: () => undefined!
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_GROUP, {})

rootNode = world.sceneEntity
})
Expand Down Expand Up @@ -256,10 +248,7 @@ describe('EditorControlFunctions', () => {
{ name: SCENE_COMPONENT_GROUP, props: [] }
])
Engine.instance.sceneComponentRegistry.set(GroupComponent.name, SCENE_COMPONENT_GROUP)
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_GROUP, {
deserialize: deserializeGroup,
serialize: () => undefined!
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_GROUP, {})

const rootNode = world.sceneEntity
nodes = [createEntity(), createEntity()]
Expand Down
16 changes: 4 additions & 12 deletions packages/engine/src/audio/systems/MediaSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,24 +177,16 @@ export default async function MediaSystem() {
])

Engine.instance.sceneComponentRegistry.set(PositionalAudioComponent.name, SCENE_COMPONENT_POSITIONAL_AUDIO)
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_POSITIONAL_AUDIO, {
defaultData: {}
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_POSITIONAL_AUDIO, {})

Engine.instance.sceneComponentRegistry.set(VideoComponent.name, SCENE_COMPONENT_VIDEO)
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_VIDEO, {
defaultData: {}
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_VIDEO, {})

Engine.instance.sceneComponentRegistry.set(MediaComponent.name, SCENE_COMPONENT_MEDIA)
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_MEDIA, {
defaultData: {}
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_MEDIA, {})

Engine.instance.sceneComponentRegistry.set(VolumetricComponent.name, SCENE_COMPONENT_VOLUMETRIC)
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_VOLUMETRIC, {
defaultData: {}
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_VOLUMETRIC, {})

const audioState = getMutableState(AudioState)
const currentTime = audioState.audioContext.currentTime.value
Expand Down
128 changes: 123 additions & 5 deletions packages/engine/src/avatar/components/LoopAnimationComponent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import { AnimationAction } from 'three'
import { useEffect } from 'react'
import { AnimationAction, AnimationClip, AnimationMixer, Vector3 } from 'three'

import { defineComponent } from '../../ecs/functions/ComponentFunctions'
import {
addComponent,
ComponentType,
defineComponent,
getComponent,
hasComponent,
removeComponent,
useComponent,
useOptionalComponent
} from '../../ecs/functions/ComponentFunctions'
import { CallbackComponent, setCallback, StandardCallbacks } from '../../scene/components/CallbackComponent'
import { ModelComponent } from '../../scene/components/ModelComponent'
import { AnimationManager } from '../AnimationManager'
import { setupAvatarModel } from '../functions/avatarFunctions'
import { AnimationComponent } from './AnimationComponent'
import { AvatarAnimationComponent } from './AvatarAnimationComponent'

export const LoopAnimationComponent = defineComponent({
name: 'LoopAnimationComponent',
Expand All @@ -11,20 +27,122 @@ export const LoopAnimationComponent = defineComponent({
action: null as AnimationAction | null
}
},

onSet: (entity, component, json) => {
if (!json) return

if (typeof json.activeClipIndex === 'number') component.activeClipIndex.set(json.activeClipIndex)
if (typeof json.hasAvatarAnimations === 'boolean') component.hasAvatarAnimations.set(json.hasAvatarAnimations)
if (typeof json.action !== 'undefined') component.action.set(json.action as AnimationAction)
},

toJSON: (entity, component) => {
return {
activeClipIndex: component.activeClipIndex.value,
hasAvatarAnimations: component.hasAvatarAnimations.value,
action: component.action.value
hasAvatarAnimations: component.hasAvatarAnimations.value
}
},

reactor: function ({ root }) {
const entity = root.entity

const modelComponent = useOptionalComponent(entity, ModelComponent)

/**
* Callback functions
*/
useEffect(() => {
if (hasComponent(entity, CallbackComponent)) return
const play = () => {
playAnimationClip(getComponent(entity, AnimationComponent), getComponent(entity, LoopAnimationComponent))
}
const pause = () => {
const loopAnimationComponent = getComponent(entity, LoopAnimationComponent)
if (loopAnimationComponent.action) loopAnimationComponent.action.paused = true
}
const stop = () => {
const loopAnimationComponent = getComponent(entity, LoopAnimationComponent)
if (loopAnimationComponent.action) loopAnimationComponent.action.stop()
}
setCallback(entity, StandardCallbacks.PLAY, play)
setCallback(entity, StandardCallbacks.PAUSE, pause)
setCallback(entity, StandardCallbacks.STOP, stop)
}, [])

/**
* A model is required for LoopAnimationComponent.
*/
useEffect(() => {
if (!modelComponent?.scene?.value) return

const scene = modelComponent.scene.value

if (!hasComponent(entity, AnimationComponent)) {
addComponent(entity, AnimationComponent, {
mixer: new AnimationMixer(scene),
animationSpeed: 1,
animations: []
})
}

const loopComponent = getComponent(entity, LoopAnimationComponent)
const animationComponent = getComponent(entity, AnimationComponent)

const changedToAvatarAnimation =
loopComponent.hasAvatarAnimations && animationComponent.animations !== AnimationManager.instance._animations
const changedToObjectAnimation =
!loopComponent.hasAvatarAnimations && animationComponent.animations !== scene.animations

if (changedToAvatarAnimation) {
if (!hasComponent(entity, AvatarAnimationComponent)) {
addComponent(entity, AvatarAnimationComponent, {
animationGraph: {
states: {},
transitionRules: {},
currentState: null!,
stateChanged: null!
},
rootYRatio: 1,
locomotion: new Vector3()
})
const setupLoopableAvatarModel = setupAvatarModel(entity)
setupLoopableAvatarModel(scene)
}
}

if (changedToObjectAnimation) {
if (hasComponent(entity, AvatarAnimationComponent)) {
removeComponent(entity, AvatarAnimationComponent)
}
animationComponent.mixer = new AnimationMixer(scene)
animationComponent.animations = scene.animations
}

if (!loopComponent.action?.paused) playAnimationClip(animationComponent, loopComponent)
}, [modelComponent?.scene])

return null
}
})

export const SCENE_COMPONENT_LOOP_ANIMATION = 'loop-animation'

export const playAnimationClip = (
animationComponent: ComponentType<typeof AnimationComponent>,
loopAnimationComponent: ComponentType<typeof LoopAnimationComponent>
) => {
if (loopAnimationComponent.action) loopAnimationComponent.action.stop()
if (
loopAnimationComponent.activeClipIndex >= 0 &&
animationComponent.animations[loopAnimationComponent.activeClipIndex]
) {
animationComponent.mixer.stopAllAction()
loopAnimationComponent.action = animationComponent.mixer
.clipAction(
AnimationClip.findByName(
animationComponent.animations,
animationComponent.animations[loopAnimationComponent.activeClipIndex].name
)
)
.play()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ export const BehaveGraphActions = {
export default async function BehaveGraphSystem() {
Engine.instance.sceneComponentRegistry.set(BehaveGraphComponent.name, SCENE_COMPONENT_BEHAVE_GRAPH)
Engine.instance.scenePrefabRegistry.set(ScenePrefabs.behaveGraph, [{ name: SCENE_COMPONENT_BEHAVE_GRAPH, props: {} }])
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_BEHAVE_GRAPH, {
defaultData: {}
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_BEHAVE_GRAPH, {})

const graphQuery = defineQuery([BehaveGraphComponent])
const runtimeQuery = defineQuery([RuntimeGraphComponent])
Expand Down
3 changes: 1 addition & 2 deletions packages/engine/src/common/constants/PrefabFunctionType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ export type ComponentUpdateFunction = (entity: Entity) => void
export type ComponentShouldDeserializeFunction = () => boolean
export type ComponentPrepareForGLTFExportFunction = (object: Object3D) => void

/** @deprecated */
export type SceneLoaderType = {
/** @deprecated - use defineComponent API instead */
defaultData?: any
/**
* @deprecated An override function to specify custom transformations from ECS to JSON
* - if no function is set, data will be copied from the component via JSON serialization
Expand Down
5 changes: 4 additions & 1 deletion packages/engine/src/ecs/classes/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,10 @@ export class Engine {

/** @todo: merge sceneComponentRegistry and sceneLoadingRegistry when scene loader IDs use EE_ extension names*/

/** Registry map of scene loader components */
/**
* Registry map of scene loader components
* @todo replace with a Set once SceneLoaderType is removed
* */
sceneLoadingRegistry = new Map<string, SceneLoaderType>()

/** Scene component of scene loader components */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,3 @@ export const BoundingBoxComponent = defineComponent({
})

export const BoundingBoxDynamicTag = defineComponent({ name: 'BoundingBoxDynamicTag' })

export function setBoundingBoxComponent(entity: Entity) {
if (hasComponent(entity, BoundingBoxComponent)) return getComponent(entity, BoundingBoxComponent)
return setComponent(entity, BoundingBoxComponent)
}

export function setBoundingBoxDynamicTag(entity: Entity) {
return setComponent(entity, BoundingBoxDynamicTag, true)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
import { Entity } from '../../ecs/classes/Entity'
import { defineComponent, setComponent } from '../../ecs/functions/ComponentFunctions'
import { defineComponent } from '../../ecs/functions/ComponentFunctions'

export const InteractableComponent = defineComponent({ name: 'InteractableComponent' })

export function setInteractableComponent(entity: Entity) {
return setComponent(entity, InteractableComponent, true)
}
7 changes: 4 additions & 3 deletions packages/engine/src/interaction/systems/InteractiveSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
getComponent,
hasComponent,
removeComponent,
removeQuery
removeQuery,
setComponent
} from '../../ecs/functions/ComponentFunctions'
import { HighlightComponent } from '../../renderer/components/HighlightComponent'
import {
Expand All @@ -27,7 +28,7 @@ import { TransformComponent } from '../../transform/components/TransformComponen
import { createTransitionState } from '../../xrui/functions/createTransitionState'
import { createXRUI } from '../../xrui/functions/createXRUI'
import { ObjectFitFunctions } from '../../xrui/functions/ObjectFitFunctions'
import { InteractableComponent, setInteractableComponent } from '../components/InteractableComponent'
import { InteractableComponent } from '../components/InteractableComponent'
import { gatherAvailableInteractables } from '../functions/gatherAvailableInteractables'
import { createInteractUI } from '../functions/interactUI'

Expand Down Expand Up @@ -86,7 +87,7 @@ export const addInteractableUI = (
xrui: ReturnType<typeof createXRUI>,
update?: (entity: Entity, xrui: ReturnType<typeof createXRUI>) => void
) => {
setInteractableComponent(entity)
setComponent(entity, InteractableComponent)

if (!update) {
update = onInteractableUpdate
Expand Down
4 changes: 1 addition & 3 deletions packages/engine/src/interaction/systems/MountPointSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ export default async function MountPointSystem() {
])

Engine.instance.sceneComponentRegistry.set(MountPointComponent.name, SCENE_COMPONENT_MOUNT_POINT)
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_MOUNT_POINT, {
defaultData: {}
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_MOUNT_POINT, {})

if (getMutableState(EngineState).isEditor.value)
return {
Expand Down
4 changes: 1 addition & 3 deletions packages/engine/src/physics/systems/PhysicsSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ export function smoothVelocityBasedKinematicBody(entity: Entity, dt: number, sub

export default async function PhysicsSystem() {
Engine.instance.sceneComponentRegistry.set(ColliderComponent.name, SCENE_COMPONENT_COLLIDER)
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_COLLIDER, {
defaultData: {}
})
Engine.instance.sceneLoadingRegistry.set(SCENE_COMPONENT_COLLIDER, {})

Engine.instance.scenePrefabRegistry.set(PhysicsPrefabs.collider, [
{ name: SCENE_COMPONENT_TRANSFORM, props: SCENE_COMPONENT_TRANSFORM_DEFAULT_VALUES },
Expand Down
Loading