consolidate code

This commit is contained in:
Brandon Thomas committed 2024-03-11 22:21:19 -04:00
1 parent 8b96b0bd87
commit 559a96fc5f
7 files changed
+40 -170

No files matched your search

@@ -1,53 +1,49 @@
import React, { useCallback, useEffect, useRef } from "react";
//import IframeResizer from "iframe-resizer-react";
import "./Scene3D.scss";
import { EngineMode } from "./EngineMode";
import { GetEngineUrl, LoadableAsset } from "./GetEngineUrl";
const CHECK_FRAME_URL = "https://engine.fakeyou.com";
// See the following page for Storyteller Engine's query param documentation:
// https://www.notion.so/storytellerai/Studio-Iframe-Query-Params-a748a9929ec3404780c3884e7fb89bdb
//
// You can supply either an `objectId` or a `sceneMediaFileToken` when loading in studio mode.
interface Scene3DProps {
mode: string;
skybox?: string;
fullScreen?: boolean;
urlParams?: string;
className?: string;
onSceneSavedCallback?: (mediaToken: string) => void;
// NB: The following parameters are mutally exclusive.
// We should use Typescript to enforce this.
objectId?: string; // built-in objects
sceneMediaFileToken?: string; // scn.ron native storyteller engine scenes
mixamoUrl?: string; // a mixamo animation
bvhUrl?: string; // a MocapNet animation in BVH format
sceneImportUrl?: string; // a generic (non-storyteller) scene: GLB, GLTF, etc.
interface Scene3DProps {
// The mode to open the engine in.
mode: EngineMode;
// A polymorphic asset type.
// See `GetEngineUrl()` for usage.
asset: LoadableAsset,
// A skybox to use.
skybox?: string;
// Whether the engine should be full screen
fullScreen?: boolean;
// CSS classes to apply to the engine
className?: string;
onSceneSavedCallback?: (mediaToken: string) => void;
}
export default function Scene3D({
mode,
asset,
skybox,
fullScreen = false,
className,
onSceneSavedCallback,
// NB: The following parameters are mutally exclusive.
// We should use Typescript to enforce this.
objectId,
sceneMediaFileToken,
mixamoUrl,
bvhUrl,
sceneImportUrl,
}: Scene3DProps) {
const engineBaseUrl = "https://engine.fakeyou.com";
const iframeRef = useRef<HTMLIFrameElement>(null);
const onMessage = useCallback((event: MessageEvent) => {
console.log("engine message received", event.data, event);
if (event.origin !== engineBaseUrl)
if (event.origin !== CHECK_FRAME_URL)
return;
if (event.data === "studio-ready") {
@@ -85,31 +81,7 @@ export default function Scene3D({
}, [onMessage]);
let engineUrl = `${engineBaseUrl}/?mode=${mode}`;
if (skybox) {
engineUrl += `&skybox=${skybox}`;
}
if (sceneMediaFileToken) {
// NB: Storyteller Engine makes the API call to load the scene.
// We don't need to pass the bucket path.
// The engine, does, however, need a `.scn.ron` file extension.
const sceneUrlRef = `remote://${sceneMediaFileToken}.scn.ron`;
engineUrl += `&scene=${sceneUrlRef}`;
} else if (objectId) {
// NB: This is an engine built-in, eg. `couch.gltf` or `sample-room.gltf`.
engineUrl += `&objectId=${objectId}`;
} else if (mixamoUrl) {
// NB: This should be a full bucket path to an asset.
engineUrl += `&mixamo=${mixamoUrl}`;
} else if (bvhUrl) {
// NB: This should be a full bucket path to an asset.
engineUrl += `&bvh=${bvhUrl}`;
} else if (sceneImportUrl) {
// TODO: Not sure what the format of this should be.
engineUrl += `&sceneImport=${sceneImportUrl}`;
}
let engineUrl = GetEngineUrl({mode: mode, asset: asset, skybox: skybox})
return (
<div
@@ -1,103 +0,0 @@
import React, { useCallback, useEffect, useRef } from "react";
//import IframeResizer from "iframe-resizer-react";
import "./Scene3D.scss";
import { EngineMode } from "./EngineMode";
import { GetEngineUrl, LoadableAsset } from "./GetEngineUrl";
const CHECK_FRAME_URL = "https://engine.fakeyou.com";
// See the following page for Storyteller Engine's query param documentation:
// https://www.notion.so/storytellerai/Studio-Iframe-Query-Params-a748a9929ec3404780c3884e7fb89bdb
interface Scene3dNextProps {
// The mode to open the engine in.
mode: EngineMode;
// A polymorphic asset type.
// See `GetEngineUrl()` for usage.
asset: LoadableAsset,
// A skybox to use.
skybox?: string;
// Whether the engine should be full screen
fullScreen?: boolean;
// CSS classes to apply to the engine
className?: string;
onSceneSavedCallback?: (mediaToken: string) => void;
}
export default function Scene3dNext({
mode,
asset,
skybox,
fullScreen = false,
className,
onSceneSavedCallback,
}: Scene3dNextProps) {
const iframeRef = useRef<HTMLIFrameElement>(null);
const onMessage = useCallback((event: MessageEvent) => {
console.log("engine message received", event.data, event);
if (event.origin !== CHECK_FRAME_URL)
return;
if (event.data === "studio-ready") {
console.log("studio-ready message (1)");
const studio = iframeRef.current?.contentWindow;
if (!studio) return;
console.log("studio-ready message (2)");
// NB: Example of how to call the API in the other direction:
// studio.postMessage("save-scene", engineBaseUrl);
} else if (
typeof event.data === "string"
&& event.data.startsWith("scene-saved:")
) {
const mediaToken = event.data.match(/scene-saved:(.+)/)?.[1];
console.log("saved scene media token:", mediaToken);
if (onSceneSavedCallback !== undefined && mediaToken !== undefined) {
onSceneSavedCallback(mediaToken);
}
} else if (event.data === "scene-save-failed") {
console.error("Failed to save the scene!");
}
}, [onSceneSavedCallback]);
useEffect(() => {
window.addEventListener("message", onMessage, false);
return () => {
window.removeEventListener("message", onMessage, false);
}
}, [onMessage]);
let engineUrl = GetEngineUrl({mode: mode, asset: asset, skybox: skybox})
return (
<div
className={`${
fullScreen ? "fy-scene-3d-fullscreen" : "fy-scene-3d-default"
} ${className ? className : ""}`.trim()}
>
{/* IframeResizer was causing some glitches passing messages. Need to test more. */}
{/*<IframeResizer src={engineUrl} width="100%" height="100%" id="" />*/}
<iframe
title="Storyteller Engine"
ref={iframeRef}
src={engineUrl}
width="100%"
height="100%"
/>
</div>
);
}
@@ -1 +0,0 @@
export { default } from "./Scene3D";
@@ -28,7 +28,7 @@ import NumberSliderV2 from "./NumberSliderV2";
import Pagination from "./Pagination";
import Panel from "./Panel";
import Radio from "./Radio";
import Scene3D from "./Scene3D";
import Scene3D from "./Scene3D/Scene3D";
import Searcher from "./Searcher";
import SegmentButtons from "./SegmentButtons";
import Select from "./Select";
@@ -1,6 +1,6 @@
import React from "react";
import { MediaFile } from "@storyteller/components/src/api/media_files/GetMediaFile";
import Scene3dNext from "components/common/Scene3D/Scene3dNext";
import Scene3D from "components/common/Scene3D/Scene3D";
import { EngineMode } from "components/common/Scene3D/EngineMode";
// Storyteller Engine parameters
@@ -17,7 +17,7 @@ export interface EngineMediaPanelArgs {
export function EngineMediaPanel({ mediaFile } : EngineMediaPanelArgs) {
return (
<Scene3dNext
<Scene3D
mode={EngineMode.Viewer}
skybox={SKYBOX}
fullScreen={false}
@@ -2,9 +2,10 @@ import React from "react";
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
import { StudioNotAvailable } from "v2/view/_common/StudioNotAvailable";
import { Scene3D } from "components/common";
import { usePrefixedDocumentTitle } from "common/UsePrefixedDocumentTitle";
import { useParams } from "react-router-dom";
import Scene3D from "components/common/Scene3D/Scene3D";
import { EngineMode } from "components/common/Scene3D/EngineMode";
interface Props {
sessionWrapper: SessionWrapper;
@@ -20,24 +21,25 @@ function StorytellerStudioListPage(props: Props) {
return <StudioNotAvailable />;
}
let engineParams = {};
let assetDescriptor;
if (mediaToken) {
engineParams = {
sceneMediaFileToken: mediaToken
assetDescriptor = {
storytellerSceneMediaFileToken: mediaToken
};
} else {
engineParams = {
assetDescriptor = {
objectId: "sample-room.gltf"
};
}
return (
<>
<Scene3D
<Scene3D
fullScreen={true}
mode="studio"
{...engineParams} />
mode={EngineMode.Studio}
asset={assetDescriptor}
/>
</>
);
}
@@ -10,7 +10,7 @@ import { EnqueueEngineCompositing } from "@storyteller/components/src/api/engine
import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob";
import { v4 as uuidv4 } from "uuid";
import "./StudioIntro.scss";
import Scene3dNext from "components/common/Scene3D/Scene3dNext";
import Scene3D from "components/common/Scene3D/Scene3D";
import { EngineMode } from "components/common/Scene3D/EngineMode";
interface Props {
@@ -70,7 +70,7 @@ function StudioIntroPage(props: Props) {
return (
<div className="studio-intro-page">
<Scene3dNext
<Scene3D
fullScreen={true}
mode={EngineMode.Studio}
asset={assetDescriptor}