diff --git a/.changeset/dull-dryers-relax.md b/.changeset/dull-dryers-relax.md new file mode 100644 index 00000000..22397dd4 --- /dev/null +++ b/.changeset/dull-dryers-relax.md @@ -0,0 +1,13 @@ +--- +"with-reactive": patch +--- + +# Logs + +## refactor(reactive): enhance `GLTF` serialization + +- Add GLTF transferable data to the worker + - animations (`AnimationClipJSON[]`) + - cameras (`Camera[]`) + - parser (`{ json: GLTFParser["json"] }`) + - scenes (`Group[]`) diff --git a/packages/reactive/package.json b/packages/reactive/package.json index a3b288f2..150a231d 100644 --- a/packages/reactive/package.json +++ b/packages/reactive/package.json @@ -66,6 +66,7 @@ "reflect-metadata": "^0.2.2", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", - "tsyringe": "^4.8.0" + "tsyringe": "^4.8.0", + "vite": "^6.0.3" } } diff --git a/packages/reactive/src/core/app/loader/loader.controller.ts b/packages/reactive/src/core/app/loader/loader.controller.ts index 7007843e..73666ebc 100644 --- a/packages/reactive/src/core/app/loader/loader.controller.ts +++ b/packages/reactive/src/core/app/loader/loader.controller.ts @@ -7,6 +7,8 @@ import { LoadedResourcePayload, LOADER_SERIALIZED_LOAD_TOKEN } from "../../../common"; +import { AnimationClip, AnimationClipJSON, Camera, Group } from "three"; +import { GLTF, GLTFParser } from "three/examples/jsm/loaders/GLTFLoader"; @scoped(Lifecycle.ResolutionScoped) export class LoaderController { @@ -28,12 +30,28 @@ export class LoaderController { const { payload } = event.data || {}; if (!!payload?.resource && payload.source.type === "gltfModel") { - const resource = payload.resource as any; - const scene = deserializeObject3D(resource?.scene as string); + const resource = payload.resource as unknown as { + animations?: AnimationClipJSON[]; + cameras?: string[]; + parser?: Partial & { json: GLTFParser["json"] }; + scene?: string; + scenes?: string[]; + userData?: GLTF["userData"]; + }; + const animations = resource.animations?.map((animation) => + AnimationClip.parse(animation) + ); + const cameras = resource.cameras?.map( + (camera) => deserializeObject3D(camera) as Camera + ); + const scene = deserializeObject3D(resource?.scene || "") as Group; + const scenes = resource.scenes?.map( + (scene) => deserializeObject3D(scene) as Group + ); return { ...payload, - resource: { ...resource, scene } + resource: { ...resource, animations, cameras, scene, scenes } } as LoadedResourcePayload; } diff --git a/packages/reactive/src/core/register/loader/loader.controller.ts b/packages/reactive/src/core/register/loader/loader.controller.ts index 71b095f9..2ca6f377 100644 --- a/packages/reactive/src/core/register/loader/loader.controller.ts +++ b/packages/reactive/src/core/register/loader/loader.controller.ts @@ -1,7 +1,7 @@ import { serializeObject3D } from "@quick-threejs/utils"; import { filter, map, Observable, share, Subject } from "rxjs"; import { GLTF } from "three/examples/jsm/loaders/GLTFLoader"; -import { VideoTexture } from "three"; +import { AnimationClipJSON, VideoTexture } from "three"; import { inject, singleton } from "tsyringe"; import { @@ -9,6 +9,7 @@ import { SerializedLoadedResourcePayload } from "../../../common/interfaces/loader.interface"; import { LoaderService } from "./loader.service"; +import { JsonSerializable } from "threads"; @singleton() export class LoaderController { @@ -37,8 +38,17 @@ export class LoaderController { const _resource = payload.resource as GLTF; resource = { - userData: _resource.userData, - scene: serializeObject3D(_resource.scene) + animations: (payload?.resource as GLTF).animations.map( + // @ts-ignore <> + (animation) => animation.toJSON() as AnimationClipJSON + ) as unknown as JsonSerializable, + cameras: _resource.cameras.map((camera) => + serializeObject3D(camera) + ), + parser: { json: _resource.parser.json }, + scene: serializeObject3D(_resource.scene), + scenes: _resource.scenes.map((scene) => serializeObject3D(scene)), + userData: _resource.userData }; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 685c624e..96da0235 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -167,6 +167,9 @@ importers: tsyringe: specifier: ^4.8.0 version: 4.8.0 + vite: + specifier: ^6.0.3 + version: 6.0.3(@types/node@22.10.2)(jiti@1.21.6)(yaml@2.6.1) samples/with-legacy: dependencies: @@ -7398,7 +7401,7 @@ snapshots: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2) '@typescript-eslint/parser': 7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2) eslint-config-prettier: 9.1.0(eslint@9.17.0(jiti@1.21.6)) - eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.17.0(jiti@1.21.6))) + eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.31.0) eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0)(eslint@9.17.0(jiti@1.21.6)) eslint-plugin-eslint-comments: 3.2.0(eslint@9.17.0(jiti@1.21.6)) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.17.0(jiti@1.21.6)) @@ -8304,7 +8307,7 @@ snapshots: eslint: 9.17.0(jiti@1.21.6) eslint-plugin-turbo: 2.3.3(eslint@9.17.0(jiti@1.21.6)) - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.17.0(jiti@1.21.6))): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0): dependencies: eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.17.0(jiti@1.21.6)) @@ -8322,7 +8325,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 9.17.0(jiti@1.21.6) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0)(eslint@9.17.0(jiti@1.21.6)))(eslint@9.17.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.17.0(jiti@1.21.6)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.3.0 @@ -8335,7 +8338,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0)(eslint@9.17.0(jiti@1.21.6)))(eslint@9.17.0(jiti@1.21.6)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@9.17.0(jiti@1.21.6))(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.17.0(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: