From 4fdf9d6cfe37476bd791fc015dd448a3111ea660 Mon Sep 17 00:00:00 2001 From: HexaField Date: Sun, 4 May 2025 21:38:04 +1000 Subject: [PATCH 1/2] add dynamic authoring example --- src/examples/DynamicAuthoring.tsx | 86 +++++++++++++++++++++++++++++++ src/examplesRoute.tsx | 7 +++ 2 files changed, 93 insertions(+) create mode 100644 src/examples/DynamicAuthoring.tsx diff --git a/src/examples/DynamicAuthoring.tsx b/src/examples/DynamicAuthoring.tsx new file mode 100644 index 0000000..00c55b5 --- /dev/null +++ b/src/examples/DynamicAuthoring.tsx @@ -0,0 +1,86 @@ +import { + Entity, + Layers, + QueryReactor, + getAuthoringCounterpart, + loadEntitiesIntoAuthoring, + unloadEntitiesFromAuthoring, + useQuery +} from '@ir-engine/ecs' +import { AuthoringState } from '@ir-engine/engine/src/authoring/AuthoringState' +import { GLTFComponent } from '@ir-engine/engine/src/gltf/GLTFComponent' +import { SourceComponent } from '@ir-engine/engine/src/scene/components/SourceComponent' +import { getState } from '@ir-engine/hyperflux' +import Button from '@ir-engine/ui/src/primitives/tailwind/Button' +import React, { useCallback } from 'react' + +export default function DynamicAuthoring() { + // invoke authoring state + getState(AuthoringState) + + return ( + <> +
+ +
+ + ) +} + +const SourceLoaded = (props: { entity: Entity }) => { + const loaded = GLTFComponent.useSceneLoaded(props.entity) + if (!loaded) return null + return +} + +/** + * Contains a button and name of the entity to select and edit it. + */ +const SelectEditReactor = (props: { entity: Entity }) => { + const { entity } = props + const isInAuthoring = !!getAuthoringCounterpart(entity) + + useQuery([SourceComponent], Layers.Authoring) // trigger rerender + + // Handle loading entity into authoring + const handleLoadIntoAuthoring = useCallback(() => { + try { + const source = GLTFComponent.getInstanceID(entity) + const entities = SourceComponent.getEntitiesBySource(source) + loadEntitiesIntoAuthoring([entity, ...entities]) + console.log('Loaded entities into authoring:', [entity, ...entities]) + } catch (error) { + console.error('Failed to load entity into authoring:', error) + } + }, []) + + // Handle unloading entity from authoring + const handleUnloadFromAuthoring = useCallback(() => { + try { + const authoringEntity = getAuthoringCounterpart(entity) + const source = GLTFComponent.getInstanceID(authoringEntity) + const entities = SourceComponent.getEntitiesBySource(source, Layers.Authoring) + unloadEntitiesFromAuthoring([authoringEntity, ...entities]) + console.log('Unloaded entities from authoring:', [authoringEntity, ...entities]) + } catch (error) { + console.error('Failed to unload entity from authoring:', error) + } + }, []) + + return ( +
+
Entity ID: {entity}
+
+ {isInAuthoring ? ( + + ) : ( + + )} +
+
+ ) +} diff --git a/src/examplesRoute.tsx b/src/examplesRoute.tsx index f936fe8..566a37e 100644 --- a/src/examplesRoute.tsx +++ b/src/examplesRoute.tsx @@ -2,6 +2,7 @@ import React from 'react' import '@ir-engine/client/src/engine' +import DynamicAuthoring from './examples/DynamicAuthoring' import { gltfRoutes } from './examples/GLTFs' import InstanceConnection from './examples/InstanceConnection' import InstancedLODs from './examples/InstancedLODs' @@ -117,6 +118,12 @@ export const examples: RouteCategories = [ name: 'Multiple Canvases with different cameras', description: 'View the same scene from different cameras', entry: MultipleCanvasCameras + }, + { + name: 'Dynamic Authoring', + description: 'Allows you to use editor APIs to edit entities at runtime', + sceneKey: 'projects/ir-engine/default-project/public/scenes/apartment.gltf', + entry: DynamicAuthoring } ] }, From f62b988d082a04f8446f02865006673a84c21f24 Mon Sep 17 00:00:00 2001 From: HexaField Date: Sun, 18 May 2025 12:32:39 +1000 Subject: [PATCH 2/2] refactor: update entity handling in DynamicAuthoring to use UUIDComponent --- src/examples/DynamicAuthoring.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/examples/DynamicAuthoring.tsx b/src/examples/DynamicAuthoring.tsx index 00c55b5..e5c3f0d 100644 --- a/src/examples/DynamicAuthoring.tsx +++ b/src/examples/DynamicAuthoring.tsx @@ -2,6 +2,7 @@ import { Entity, Layers, QueryReactor, + UUIDComponent, getAuthoringCounterpart, loadEntitiesIntoAuthoring, unloadEntitiesFromAuthoring, @@ -9,7 +10,6 @@ import { } from '@ir-engine/ecs' import { AuthoringState } from '@ir-engine/engine/src/authoring/AuthoringState' import { GLTFComponent } from '@ir-engine/engine/src/gltf/GLTFComponent' -import { SourceComponent } from '@ir-engine/engine/src/scene/components/SourceComponent' import { getState } from '@ir-engine/hyperflux' import Button from '@ir-engine/ui/src/primitives/tailwind/Button' import React, { useCallback } from 'react' @@ -40,13 +40,13 @@ const SelectEditReactor = (props: { entity: Entity }) => { const { entity } = props const isInAuthoring = !!getAuthoringCounterpart(entity) - useQuery([SourceComponent], Layers.Authoring) // trigger rerender + useQuery([UUIDComponent], Layers.Authoring) // trigger rerender // Handle loading entity into authoring const handleLoadIntoAuthoring = useCallback(() => { try { - const source = GLTFComponent.getInstanceID(entity) - const entities = SourceComponent.getEntitiesBySource(source) + const source = GLTFComponent.getSourceID(entity) + const entities = UUIDComponent.getEntitiesBySource(source, Layers.Simulation) loadEntitiesIntoAuthoring([entity, ...entities]) console.log('Loaded entities into authoring:', [entity, ...entities]) } catch (error) { @@ -58,8 +58,8 @@ const SelectEditReactor = (props: { entity: Entity }) => { const handleUnloadFromAuthoring = useCallback(() => { try { const authoringEntity = getAuthoringCounterpart(entity) - const source = GLTFComponent.getInstanceID(authoringEntity) - const entities = SourceComponent.getEntitiesBySource(source, Layers.Authoring) + const source = GLTFComponent.getSourceID(authoringEntity) + const entities = UUIDComponent.getEntitiesBySource(source, Layers.Authoring) unloadEntitiesFromAuthoring([authoringEntity, ...entities]) console.log('Unloaded entities from authoring:', [authoringEntity, ...entities]) } catch (error) {