mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-12 04:42:16 +00:00
fbx to gltf working
This commit is contained in:
1 parent
39598c8080
commit
c76b40ede4
4 files changed
+153
-82
No files matched your search
@@ -492,10 +492,14 @@ class ApiConfig {
|
||||
}
|
||||
|
||||
// =============== Motion Capture / mocap ===============
|
||||
enqueueVideoMotionCapture(): string{
|
||||
return `${this.getApiOrigin()}/v1/mocap/mocapnet/create`
|
||||
enqueueVideoMotionCapture(): string {
|
||||
return `${this.getApiOrigin()}/v1/mocap/mocapnet/create`;
|
||||
}
|
||||
|
||||
// =============== Convert FBX to glTF ===============
|
||||
enqueueFbxToGltf(): string {
|
||||
return `${this.getApiOrigin()}/v1/conversion/enqueue_fbx_to_gltf`;
|
||||
}
|
||||
|
||||
// =============== Generic Model Downloads ===============
|
||||
|
||||
@@ -615,4 +619,4 @@ class ApiConfig {
|
||||
}
|
||||
}
|
||||
|
||||
export { ApiConfig };
|
||||
export { ApiConfig };
|
||||
@@ -0,0 +1,49 @@
|
||||
import { ApiConfig } from "../ApiConfig";
|
||||
|
||||
export interface EnqueueFbxToGltfRequest {
|
||||
media_file_token: string;
|
||||
uuid_idempotency_token: string;
|
||||
}
|
||||
|
||||
export interface EnqueueFbxToGltfResponse {
|
||||
success: boolean;
|
||||
inference_job_token?: string;
|
||||
}
|
||||
|
||||
const EnqueueFbxToGltfIsSuccess = (response: EnqueueFbxToGltfResponse) =>
|
||||
response.inference_job_token;
|
||||
const EnqueueFbxToGltfIsError = (response: EnqueueFbxToGltfResponse) =>
|
||||
!response.inference_job_token;
|
||||
|
||||
export { EnqueueFbxToGltfIsSuccess, EnqueueFbxToGltfIsError };
|
||||
|
||||
export async function EnqueueFbxToGltf(
|
||||
request: EnqueueFbxToGltfRequest
|
||||
): Promise<EnqueueFbxToGltfResponse> {
|
||||
const endpoint = new ApiConfig().enqueueFbxToGltf();
|
||||
|
||||
return await fetch(endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
credentials: "include",
|
||||
body: JSON.stringify(request),
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
if (!res) {
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
if (res && "success" in res) {
|
||||
return res;
|
||||
} else {
|
||||
return { success: false };
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
return { success: false };
|
||||
});
|
||||
}
|
||||
@@ -60,10 +60,7 @@ import { VoiceConversionModelUploadJob } from "@storyteller/components/src/jobs/
|
||||
import { VoiceConversionModelListItem } from "@storyteller/components/src/api/voice_conversion/ListVoiceConversionModels";
|
||||
import HttpBackend from "i18next-http-backend";
|
||||
|
||||
import {
|
||||
InferenceJobs,
|
||||
SessionProvider,
|
||||
} from "components/providers";
|
||||
import { InferenceJobs, SessionProvider } from "components/providers";
|
||||
|
||||
// NB: We're transitioning over to this instance of i18n-next that loads translations over HTTP from Json Files.
|
||||
// The old i18n-next instance (see below) bakes in translations into the compiled javascript blob.
|
||||
@@ -207,6 +204,7 @@ function initInferenceJobsByCategoryMap(): Map<
|
||||
);
|
||||
inferenceJobsByCategory.set(FrontendInferenceJobType.VoiceDesignerTts, []);
|
||||
inferenceJobsByCategory.set(FrontendInferenceJobType.VideoMotionCapture, []);
|
||||
inferenceJobsByCategory.set(FrontendInferenceJobType.ConvertFbxtoGltf, []);
|
||||
return inferenceJobsByCategory;
|
||||
}
|
||||
|
||||
@@ -404,11 +402,11 @@ class App extends React.Component<Props, State> {
|
||||
Accept: "application/json",
|
||||
},
|
||||
})
|
||||
.then((_raw_response) => {
|
||||
.then(_raw_response => {
|
||||
this.querySession();
|
||||
this.querySessionSubscriptions();
|
||||
})
|
||||
.catch((e) => {
|
||||
.catch(e => {
|
||||
/* Ignore. */
|
||||
});
|
||||
};
|
||||
@@ -451,7 +449,7 @@ class App extends React.Component<Props, State> {
|
||||
if (GetModelInferenceJobStatusIsOk(lookupResult)) {
|
||||
let updatedJobs: Array<InferenceJob> = [];
|
||||
|
||||
this.state.inferenceJobs.forEach((existingJob) => {
|
||||
this.state.inferenceJobs.forEach(existingJob => {
|
||||
if (
|
||||
existingJob.jobToken !== lookupResult.state!.job_token ||
|
||||
!jobStateCanChange(existingJob.jobState)
|
||||
@@ -511,8 +509,8 @@ class App extends React.Component<Props, State> {
|
||||
Accept: "application/json",
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((response) => {
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
const jobResponse: TtsInferenceJobStateResponsePayload = response;
|
||||
|
||||
if (jobResponse === undefined || jobResponse.state === undefined) {
|
||||
@@ -521,7 +519,7 @@ class App extends React.Component<Props, State> {
|
||||
|
||||
let updatedJobs: Array<TtsInferenceJob> = [];
|
||||
|
||||
this.state.ttsInferenceJobs.forEach((existingJob) => {
|
||||
this.state.ttsInferenceJobs.forEach(existingJob => {
|
||||
if (
|
||||
existingJob.jobToken !== jobResponse.state!.job_token ||
|
||||
!jobStateCanChange(existingJob.jobState)
|
||||
@@ -538,7 +536,7 @@ class App extends React.Component<Props, State> {
|
||||
ttsInferenceJobs: updatedJobs,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
.catch(e => {
|
||||
/* Ignore. */
|
||||
});
|
||||
};
|
||||
@@ -563,8 +561,8 @@ class App extends React.Component<Props, State> {
|
||||
Accept: "application/json",
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((response) => {
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
const jobResponse: TtsModelUploadJobStateResponsePayload = response;
|
||||
|
||||
if (jobResponse === undefined || jobResponse.state === undefined) {
|
||||
@@ -572,7 +570,7 @@ class App extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
let updatedJobs: Array<TtsModelUploadJob> = [];
|
||||
this.state.ttsModelUploadJobs.forEach((existingJob) => {
|
||||
this.state.ttsModelUploadJobs.forEach(existingJob => {
|
||||
if (
|
||||
existingJob.jobToken !== jobResponse.state!.job_token ||
|
||||
!jobStateCanChange(existingJob.jobState)
|
||||
@@ -589,7 +587,7 @@ class App extends React.Component<Props, State> {
|
||||
ttsModelUploadJobs: updatedJobs,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
.catch(e => {
|
||||
/* Ignore. */
|
||||
});
|
||||
};
|
||||
@@ -614,8 +612,8 @@ class App extends React.Component<Props, State> {
|
||||
Accept: "application/json",
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((response) => {
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
const jobResponse: W2lInferenceJobStateResponsePayload = response;
|
||||
|
||||
if (jobResponse === undefined || jobResponse.state === undefined) {
|
||||
@@ -623,7 +621,7 @@ class App extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
let updatedJobs: Array<W2lInferenceJob> = [];
|
||||
this.state.w2lInferenceJobs.forEach((existingJob) => {
|
||||
this.state.w2lInferenceJobs.forEach(existingJob => {
|
||||
if (
|
||||
existingJob.jobToken !== jobResponse.state!.job_token ||
|
||||
!jobStateCanChange(existingJob.jobState)
|
||||
@@ -640,7 +638,7 @@ class App extends React.Component<Props, State> {
|
||||
w2lInferenceJobs: updatedJobs,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
.catch(e => {
|
||||
/* Ignore. */
|
||||
});
|
||||
};
|
||||
@@ -665,8 +663,8 @@ class App extends React.Component<Props, State> {
|
||||
Accept: "application/json",
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((response) => {
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
const jobResponse: W2lTemplateUploadJobStateResponsePayload = response;
|
||||
|
||||
if (jobResponse === undefined || jobResponse.state === undefined) {
|
||||
@@ -675,7 +673,7 @@ class App extends React.Component<Props, State> {
|
||||
|
||||
let updatedJobs: Array<W2lTemplateUploadJob> = [];
|
||||
|
||||
this.state.w2lTemplateUploadJobs.forEach((existingJob) => {
|
||||
this.state.w2lTemplateUploadJobs.forEach(existingJob => {
|
||||
if (
|
||||
existingJob.jobToken !== jobResponse.state!.job_token ||
|
||||
!jobStateCanChange(existingJob.jobState)
|
||||
@@ -694,7 +692,7 @@ class App extends React.Component<Props, State> {
|
||||
w2lTemplateUploadJobs: updatedJobs,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
.catch(e => {
|
||||
/* Ignore. */
|
||||
});
|
||||
};
|
||||
@@ -714,7 +712,7 @@ class App extends React.Component<Props, State> {
|
||||
if (GetRemoteDownloadJobStatusIsOk(lookupResult)) {
|
||||
let updatedJobs: Array<VocoderUploadJob> = [];
|
||||
|
||||
this.state.vocoderUploadJobs.forEach((existingJob) => {
|
||||
this.state.vocoderUploadJobs.forEach(existingJob => {
|
||||
if (
|
||||
existingJob.jobToken !== lookupResult.state!.job_token ||
|
||||
!jobStateCanChange(existingJob.jobState)
|
||||
@@ -748,7 +746,7 @@ class App extends React.Component<Props, State> {
|
||||
if (GetRemoteDownloadJobStatusIsOk(lookupResult)) {
|
||||
let updatedJobs: Array<VocoderUploadJob> = [];
|
||||
|
||||
this.state.voiceConversionModelUploadJobs.forEach((existingJob) => {
|
||||
this.state.voiceConversionModelUploadJobs.forEach(existingJob => {
|
||||
if (
|
||||
existingJob.jobToken !== lookupResult.state!.job_token ||
|
||||
!jobStateCanChange(existingJob.jobState)
|
||||
@@ -770,37 +768,37 @@ class App extends React.Component<Props, State> {
|
||||
};
|
||||
|
||||
pollJobs = () => {
|
||||
this.state.inferenceJobs.forEach((job) => {
|
||||
this.state.inferenceJobs.forEach(job => {
|
||||
if (jobStateCanChange(job.jobState)) {
|
||||
this.checkInferenceJob(job.jobToken);
|
||||
}
|
||||
});
|
||||
this.state.ttsInferenceJobs.forEach((job) => {
|
||||
this.state.ttsInferenceJobs.forEach(job => {
|
||||
if (jobStateCanChange(job.jobState)) {
|
||||
this.checkTtsJob(job.jobToken);
|
||||
}
|
||||
});
|
||||
this.state.w2lInferenceJobs.forEach((job) => {
|
||||
this.state.w2lInferenceJobs.forEach(job => {
|
||||
if (jobStateCanChange(job.jobState)) {
|
||||
this.checkW2lJob(job.jobToken);
|
||||
}
|
||||
});
|
||||
this.state.ttsModelUploadJobs.forEach((job) => {
|
||||
this.state.ttsModelUploadJobs.forEach(job => {
|
||||
if (jobStateCanChange(job.jobState)) {
|
||||
this.checkTtsModelUploadJob(job.jobToken);
|
||||
}
|
||||
});
|
||||
this.state.w2lTemplateUploadJobs.forEach((job) => {
|
||||
this.state.w2lTemplateUploadJobs.forEach(job => {
|
||||
if (jobStateCanChange(job.jobState)) {
|
||||
this.checkW2lTemplateUploadJob(job.jobToken);
|
||||
}
|
||||
});
|
||||
this.state.vocoderUploadJobs.forEach((job) => {
|
||||
this.state.vocoderUploadJobs.forEach(job => {
|
||||
if (jobStateCanChange(job.jobState)) {
|
||||
this.checkVocoderUploadJob(job.jobToken);
|
||||
}
|
||||
});
|
||||
this.state.voiceConversionModelUploadJobs.forEach((job) => {
|
||||
this.state.voiceConversionModelUploadJobs.forEach(job => {
|
||||
if (jobStateCanChange(job.jobState)) {
|
||||
this.checkVoiceConversionModelUploadJob(job.jobToken);
|
||||
}
|
||||
@@ -843,7 +841,7 @@ class App extends React.Component<Props, State> {
|
||||
querySession: this.querySession,
|
||||
querySubscriptions: this.querySessionSubscriptions,
|
||||
sessionWrapper: this.state.sessionWrapper,
|
||||
sessionFetched: this.state.sessionFetched
|
||||
sessionFetched: this.state.sessionFetched,
|
||||
}}
|
||||
>
|
||||
<Switch>
|
||||
|
||||
@@ -14,6 +14,11 @@ import { v4 as uuidv4 } from "uuid";
|
||||
import { UploadMedia } from "@storyteller/components/src/api/media_files/UploadMedia";
|
||||
import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob";
|
||||
import FbxToGltfJobList from "./components/FbxToGltfJobList";
|
||||
import {
|
||||
EnqueueFbxToGltf,
|
||||
EnqueueFbxToGltfIsSuccess,
|
||||
EnqueueFbxToGltfIsError,
|
||||
} from "@storyteller/components/src/api/file_conversion/EnqueueFbxToGltf";
|
||||
|
||||
interface FbxToGltfPageProps {
|
||||
enqueueInferenceJob: (
|
||||
@@ -32,12 +37,16 @@ export default function FbxToGltfPage({
|
||||
mediaToken: mediaToken ?? undefined,
|
||||
});
|
||||
const fileProps = useFile({});
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [isWorking, setIsWorking] = useState(false);
|
||||
|
||||
const { inferenceJobs } = useInferenceJobs(
|
||||
FrontendInferenceJobType.VideoMotionCapture
|
||||
FrontendInferenceJobType.ConvertFbxtoGltf
|
||||
);
|
||||
const hasConversionJobs = inferenceJobs && inferenceJobs.length > 0;
|
||||
|
||||
console.log("inferenceJobs", inferenceJobs);
|
||||
|
||||
useEffect(() => {
|
||||
// If there's a mediaToken, automatically prepare the file for conversion
|
||||
if (mediaToken && presetFile) {
|
||||
@@ -50,14 +59,6 @@ export default function FbxToGltfPage({
|
||||
history.push("/fbx-to-gltf");
|
||||
};
|
||||
|
||||
async function EnqueueFbxToGltf(file: any) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
console.log("EnqueueFbxToGltf", file);
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
const makeFBXUploadRequest = () => ({
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
file: fileProps.file,
|
||||
@@ -69,57 +70,75 @@ export default function FbxToGltfPage({
|
||||
try {
|
||||
const res = await UploadMedia(makeFBXUploadRequest());
|
||||
if (res.success && res.media_file_token) {
|
||||
return { upload_token: res.upload_token };
|
||||
return { upload_token: res.media_file_token };
|
||||
}
|
||||
// Handle failure scenario - perhaps throw an error or return a specific result
|
||||
console.error("Upload failed:", res);
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error("Error in upload:", error);
|
||||
// Handle the error appropriately
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const EnqueueConvert = async (params: any) => {
|
||||
let request: any = {
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
file_source: undefined,
|
||||
upload_token: params.upload_token,
|
||||
};
|
||||
|
||||
const response = await EnqueueFbxToGltf(request);
|
||||
|
||||
console.log("Response: ", response);
|
||||
|
||||
// if (response.inference_job_token) {
|
||||
// enqueueInferenceJob(
|
||||
// response.inference_job_token,
|
||||
// FrontendInferenceJobType.ConvertFbxtoGltf
|
||||
// );
|
||||
// }
|
||||
};
|
||||
|
||||
const uploadAndConvert = async () => {
|
||||
const submit = async () => {
|
||||
if (isSubmitting) return;
|
||||
setIsSubmitting(true);
|
||||
setIsWorking(true);
|
||||
try {
|
||||
const uploadResponse = await handleUploadFBX();
|
||||
if (uploadResponse && uploadResponse.upload_token) {
|
||||
await EnqueueConvert({
|
||||
upload_token: uploadResponse.upload_token,
|
||||
});
|
||||
let uploadToken = mediaToken;
|
||||
|
||||
// If no media token, upload the file first
|
||||
if (!mediaToken && fileProps.file) {
|
||||
const uploadResponse = await handleUploadFBX();
|
||||
if (uploadResponse && uploadResponse.upload_token) {
|
||||
uploadToken = uploadResponse.upload_token;
|
||||
} else {
|
||||
console.error("Failed to upload file. Response:", uploadResponse);
|
||||
throw new Error("File upload failed");
|
||||
}
|
||||
}
|
||||
|
||||
// Enqueue the conversion job
|
||||
if (uploadToken) {
|
||||
await EnqueueConvert({ upload_token: uploadToken });
|
||||
} else {
|
||||
console.error("No upload token available for conversion");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error uploading file: ", error);
|
||||
// Handle upload error
|
||||
console.error("Error in submit process: ", error);
|
||||
} finally {
|
||||
setIsWorking(false);
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
if (mediaToken && presetFile) {
|
||||
EnqueueConvert({ upload_token: mediaToken });
|
||||
} else if (fileProps.file) {
|
||||
await uploadAndConvert();
|
||||
} else {
|
||||
const EnqueueConvert = async ({ upload_token }: any) => {
|
||||
if (!upload_token) return false;
|
||||
|
||||
try {
|
||||
let request = {
|
||||
uuid_idempotency_token: uuidv4(),
|
||||
file_source: undefined,
|
||||
media_file_token: upload_token,
|
||||
};
|
||||
|
||||
const response = await EnqueueFbxToGltf(request);
|
||||
|
||||
if (EnqueueFbxToGltfIsSuccess(response)) {
|
||||
console.log("Enqueue successful");
|
||||
|
||||
if (response && response.inference_job_token) {
|
||||
enqueueInferenceJob(
|
||||
response.inference_job_token,
|
||||
FrontendInferenceJobType.ConvertFbxtoGltf
|
||||
);
|
||||
}
|
||||
return true;
|
||||
} else if (EnqueueFbxToGltfIsError(response)) {
|
||||
throw new Error("Enqueue failed");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in enqueueing conversion: ", error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -179,7 +198,8 @@ export default function FbxToGltfPage({
|
||||
icon={faArrowRightArrowLeft}
|
||||
label="Convert to glTF"
|
||||
onClick={submit}
|
||||
disabled={!fileProps.file}
|
||||
disabled={!mediaToken && !fileProps.file}
|
||||
isLoading={isWorking}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user