mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-11 04:16:55 +00:00
consolidate code
This commit is contained in:
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";
|
||||
|
||||
+2
-2
@@ -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}
|
||||
|
||||
+10
-8
@@ -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}
|
||||
|
||||
Reference in new issue
Block a user