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

Commit

Permalink
Scene switching fix (#10767)
Browse files Browse the repository at this point in the history
* set scene asset id when changing scenes, don't render hierarchy while root entity is undefined during scene loading

* Don't set state during render
  • Loading branch information
MichaelEstes authored Jul 30, 2024
1 parent 19d407b commit b4c1ab2
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 29 deletions.
8 changes: 4 additions & 4 deletions packages/client-core/src/hooks/useEngineCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@ Ethereal Engine. All Rights Reserved.
*/

import { getComponent } from '@etherealengine/ecs'
import { getState, useHookstate, useImmediateEffect } from '@etherealengine/hyperflux'
import { getState, useHookstate } from '@etherealengine/hyperflux'
import { EngineState } from '@etherealengine/spatial/src/EngineState'
import { destroySpatialEngine, initializeSpatialEngine } from '@etherealengine/spatial/src/initializeEngine'
import { RendererComponent } from '@etherealengine/spatial/src/renderer/WebGLRendererSystem'
import { useEffect } from 'react'
import { useEffect, useLayoutEffect } from 'react'

export const useEngineCanvas = (ref: React.RefObject<HTMLElement>) => {
const lastRef = useHookstate(() => ref.current)

useImmediateEffect(() => {
useLayoutEffect(() => {
if (ref.current !== lastRef.value) {
lastRef.set(ref.current)
}
}, [ref.current])

useImmediateEffect(() => {
useLayoutEffect(() => {
if (!lastRef.value) return

const parent = lastRef.value as HTMLElement
Expand Down
4 changes: 2 additions & 2 deletions packages/editor/src/components/EditorContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,14 @@ const EditorContainer = () => {

projectName.set(scene.project!)
sceneName.set(scene.key.split('/').pop() ?? null)
sceneAssetID.set(sceneQuery[0].id)
sceneAssetID.set(scene.id)
}, [sceneQuery[0]?.key])

useEffect(() => {
const scene = sceneQuery[0]
if (!sceneAssetID.value || !scene || !viewerEntity) return

return setCurrentEditorScene(sceneQuery[0].url, sceneAssetID.value as EntityUUID)
return setCurrentEditorScene(scene.url, sceneAssetID.value as EntityUUID)
}, [viewerEntity, sceneAssetID, sceneQuery[0]?.url])

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import { getComponent, getMutableComponent, useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { getComponent, getMutableComponent, useOptionalComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { AllFileTypes } from '@etherealengine/engine/src/assets/constants/fileTypes'
import { getMutableState, getState, none, useHookstate, useMutableState } from '@etherealengine/hyperflux'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
Expand All @@ -39,7 +39,7 @@ import AutoSizer from 'react-virtualized-auto-sizer'
import { FixedSizeList } from 'react-window'

import { NotificationService } from '@etherealengine/client-core/src/common/services/NotificationService'
import { Engine, Entity, EntityUUID, UUIDComponent, entityExists } from '@etherealengine/ecs'
import { Engine, Entity, UUIDComponent, entityExists } from '@etherealengine/ecs'
import { CameraOrbitComponent } from '@etherealengine/spatial/src/camera/components/CameraOrbitComponent'

import { PopoverState } from '@etherealengine/client-core/src/common/services/PopoverState'
Expand Down Expand Up @@ -101,8 +101,8 @@ const didHierarchyChange = (prev: HierarchyTreeNodeType[], curr: HierarchyTreeNo
/**
* HierarchyPanel function component provides view for hierarchy tree.
*/
function HierarchyPanelContents(props: { sceneURL: string; rootEntityUUID: EntityUUID; index: number }) {
const { sceneURL, rootEntityUUID, index } = props
function HierarchyPanelContents(props: { sceneURL: string; rootEntity: Entity; index: number }) {
const { sceneURL, rootEntity, index } = props
const { t } = useTranslation()
const [contextSelectedItem, setContextSelectedItem] = React.useState<undefined | Entity>(undefined)
const [anchorEvent, setAnchorEvent] = React.useState<undefined | React.MouseEvent<HTMLDivElement>>(undefined)
Expand All @@ -117,10 +117,8 @@ function HierarchyPanelContents(props: { sceneURL: string; rootEntityUUID: Entit
const searchHierarchy = useHookstate('')
const selectionState = useMutableState(SelectionState)

const rootEntity = UUIDComponent.useEntityByUUID(rootEntityUUID)
const rootEntitySource = useComponent(rootEntity, SourceComponent)
const gltfState = useMutableState(GLTFSnapshotState)
const gltfSnapshot = gltfState[rootEntitySource.value].snapshots[props.index]
const gltfSnapshot = gltfState[sceneURL].snapshots[index]

const [showModelChildren] = useFeatureFlags([FeatureFlags.Studio.UI.Hierarchy.ShowModelChildren])

Expand Down Expand Up @@ -651,21 +649,18 @@ function HierarchyPanelContents(props: { sceneURL: string; rootEntityUUID: Entit
)
}

const GLTFHierarchySub = (props: { sourceID: string; rootEntity: Entity }) => {
const { sourceID, rootEntity } = props
const index = GLTFSnapshotState.useSnapshotIndex(sourceID)

if (index === undefined) return null
return <HierarchyPanelContents key={sourceID} sceneURL={sourceID} rootEntity={rootEntity} index={index.value} />
}

export default function HierarchyPanel() {
const sceneID = useHookstate(getMutableState(EditorState).scenePath).value
const gltfEntity = useMutableState(EditorState).rootEntity.value
if (!sceneID || !gltfEntity) return null

const GLTFHierarchySub = () => {
const rootEntityUUID = getComponent(gltfEntity, UUIDComponent)
const sourceID = getComponent(gltfEntity, SourceComponent)
const index = GLTFSnapshotState.useSnapshotIndex(sourceID)

if (index === undefined) return null
return (
<HierarchyPanelContents key={sourceID} rootEntityUUID={rootEntityUUID} sceneURL={sourceID} index={index.value} />
)
}
const { scenePath, rootEntity } = useMutableState(EditorState).value
const sourceID = useOptionalComponent(rootEntity, SourceComponent)?.value

return <GLTFHierarchySub />
if (!scenePath || !rootEntity || !sourceID) return null
return <GLTFHierarchySub sourceID={sourceID} rootEntity={rootEntity} />
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ export default function ScenesPanel() {
const scenesLoading = scenesQuery.status === 'pending'

const onClickScene = (scene: StaticResourceType) => {
getMutableState(EditorState).scenePath.set(scene.key)
const sceneName = scene.key.split('/').pop()

getMutableState(EditorState).merge({
sceneName,
scenePath: scene.key,
sceneAssetID: scene.id
})
}

useRealtime(fileBrowserPath, scenesQuery.refetch)
Expand Down

0 comments on commit b4c1ab2

Please sign in to comment.