From bc975779d79724b04a7328589c3406663041b128 Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Thu, 22 Feb 2024 14:21:02 -0500 Subject: [PATCH 01/13] Animation Editor UI (#20) This PR adds a WIP timeline UI for animating elements in the scene. ### Implemented Features * The timeline can be panned with MMB and zoomed with Ctrl + Mouse Wheel * The timeline can be "scrubbed" by dragging the red "play-head" with LMB * The timeline sidebar (displaying the list of tracks) can be resized by dragging on the edge of the sidebar * Keyframes can be added by pressing the "Add Keyframe" CTA in the UI * Keyframes can be selected for editing by clicking the diamond-shaped markers in the timeline * Selected entities (including but not limited to keyframes) can be deleted by pressing the "Delete" key * Keyframes can be moved temporally by dragging the diamond-shaped markers in the timeline ### Known issues * Zooming the timeline in too far results in a soft-lock * When zooming the timeline, the "transform origin" is currently centered on the `00:00` timestamp. For ease of use, it should center on the mouse cursor position instead. * The timeline track-list is currently hard-coded to list the Camera and Camera Target. Clicking on these entries currently serves no useful purpose and may result in a crash. * Keyframe markers in the timeline are not currently associated with entries in the track-list and simply appear vertically centered in the timeline view. * Added keyframes currently record the position and orientation of the scene camera when added, and are rendered in the world with debug visualizations, but serve no useful purpose. Some design work is needed (both user-experience and architectural) to decide on a workflow for actually animating scene elements. * Entity deletion cannot currently be undone/redone --- Cargo.lock | 12 +- framework/src/index.ts | 1 + framework/src/lib/di/events.ts | 2 +- framework/src/lib/directives/drag.ts | 106 +++++ .../src/app/anim-editor.element.scss | 88 +++++ .../src/app/anim-editor.element.ts | 183 +++++++++ .../src/app/anim-timeline.element.scss | 120 ++++++ .../src/app/anim-timeline.element.ts | 372 ++++++++++++++++++ studio-frontend/src/app/app.element.scss | 11 +- studio-frontend/src/app/app.element.ts | 21 + studio-frontend/src/app/button.element.scss | 6 +- studio-frontend/src/app/help.element.ts | 7 +- studio-frontend/src/app/icon.element.ts | 18 +- studio-frontend/src/app/tree.element.scss | 17 +- studio-frontend/src/app/tree.element.ts | 23 +- studio-web/src/lib/canvas-provider.element.ts | 1 + studio/Cargo.toml | 1 + studio/src/anim/camera.rs | 208 ++++++++++ studio/src/anim/mod.rs | 34 +- studio/src/input.rs | 8 + studio/src/inspector/wasm.rs | 2 +- studio/src/interaction/selection.rs | 44 ++- studio/src/scene.rs | 2 +- studio/src/wasm/conv.rs | 41 ++ 24 files changed, 1297 insertions(+), 31 deletions(-) create mode 100644 framework/src/lib/directives/drag.ts create mode 100644 studio-frontend/src/app/anim-editor.element.scss create mode 100644 studio-frontend/src/app/anim-editor.element.ts create mode 100644 studio-frontend/src/app/anim-timeline.element.scss create mode 100644 studio-frontend/src/app/anim-timeline.element.ts create mode 100644 studio/src/anim/camera.rs diff --git a/Cargo.lock b/Cargo.lock index d6bb0a1..66bf9a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1483,7 +1483,7 @@ dependencies = [ "fxhash", "glam", "indexmap 2.0.0", - "itertools", + "itertools 0.11.0", "nalgebra", "parry3d", ] @@ -2991,6 +2991,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -4541,6 +4550,7 @@ dependencies = [ "futures-intrusive", "futures-lite 2.2.0", "image", + "itertools 0.12.1", "js-sys", "parking_lot", "serde", diff --git a/framework/src/index.ts b/framework/src/index.ts index 6b91947..7c8a3ee 100644 --- a/framework/src/index.ts +++ b/framework/src/index.ts @@ -1,3 +1,4 @@ export * from "./lib/decorators"; export * from "./lib/di"; export { default as spread } from "./lib/directives/spread"; +export { default as drag, type Props as DragProps } from "./lib/directives/drag"; diff --git a/framework/src/lib/di/events.ts b/framework/src/lib/di/events.ts index 629d5c8..dc02945 100644 --- a/framework/src/lib/di/events.ts +++ b/framework/src/lib/di/events.ts @@ -65,7 +65,7 @@ export class ProviderRemoval extends CustomEvent> { } declare global { - interface HTMLElementEventMap { + interface GlobalEventHandlersEventMap { [DIEvent.InjectionRequest]: InjectionRequest; [DIEvent.DependencyProvision]: DependencyProvision; [DIEvent.ProviderRemoval]: ProviderRemoval; diff --git a/framework/src/lib/directives/drag.ts b/framework/src/lib/directives/drag.ts new file mode 100644 index 0000000..586b9b8 --- /dev/null +++ b/framework/src/lib/directives/drag.ts @@ -0,0 +1,106 @@ +import { ElementPart, noChange, nothing } from "lit"; +import { directive, Directive } from "lit/directive.js"; + +export interface Props { + button?: number; + start?(event: PointerEvent): void; + move?(event: PointerEvent): void; + end?(event: PointerEvent): void; +} + +class Drag extends Directive { + #initialized = false; + #pointerButton = 0; + + #startHandler?: (event: PointerEvent) => void; + #moveHandler?: (event: PointerEvent) => void; + + #lastProps: Props = {}; + + override render(_: Props) { + return nothing; + } + + override update(part: ElementPart, [props]: [Props]) { + const element = part.element as HTMLElement; + const host = part.options?.host; + + // Disable the default drag-event handlers, which can interfere with this directive + if (!this.#initialized) { + element.addEventListener("dragstart", event => event.preventDefault()); + element.addEventListener("drag", event => event.preventDefault()); + + this.#initialized = true; + } + + // Return early if there are no changes in the passed props + if ( + this.#lastProps.button === props.button + && this.#lastProps.start === props.start + && this.#lastProps.move === props.move + && this.#lastProps.end === props.end + ) { + return noChange; + } + + // TODO: + // This makes it impossible to replace the move handler on an element with + // a different one on subsequent renders, but this may be the desired + // behavior? This allows the move handler to be bound as a lambda that + // will keep firing even after the DOM re-renders. See + // studio-frontend/src/app/anim-timeline.element.ts for the use case. + if (this.#moveHandler != null) + return noChange; + + this.#lastProps = { ...props }; + + // Clean up previous event handlers + if (this.#startHandler) + element.removeEventListener("pointerdown", this.#startHandler); + + if (this.#moveHandler) + // TODO: This statement is unreachable due to the early-return above + window.removeEventListener("pointermove", this.#moveHandler); + + // Set the pointer button which should activate dragging + this.#pointerButton = (props.button != null) ? props.button : 0; + + // Main event-handling behavior + // + // It's important to not bind any `window` events unconditionally here, + // because those handlers could easily outlive the element this directive + // is attached to (the "host" element), which would cause a memory leak. + // + // Instead, we add a single `pointerdown` listener to the host element, + // and inside that listener, we add the `pointermove` listener to the + // window. By removing the `pointermove` listener on `pointerup`, we + // shouldn't have any long-lived event listeners holding (potentially + // stale) references to the host element. + + this.#moveHandler = (event: PointerEvent) => { + props.move?.call(host ?? event, event); + } + + this.#startHandler = (event: PointerEvent) => { + if (event.button !== this.#pointerButton) + return; + + window.addEventListener("pointermove", this.#moveHandler!); + + window.addEventListener("pointerup", event => { + props.end?.call(host ?? event, event); + window.removeEventListener("pointermove", this.#moveHandler!); + }, { + once: true, + }); + + props.start?.call(host ?? event, event); + } + + element.addEventListener("pointerdown", this.#startHandler); + + return noChange; + } +} + +export default directive(Drag); diff --git a/studio-frontend/src/app/anim-editor.element.scss b/studio-frontend/src/app/anim-editor.element.scss new file mode 100644 index 0000000..a041364 --- /dev/null +++ b/studio-frontend/src/app/anim-editor.element.scss @@ -0,0 +1,88 @@ +:host { + display: flex; + border-radius: 8px; + background: #0006; + backdrop-filter: blur(16px); +} + +.sidebar, .timeline { padding: 8px; } +.sidebar { padding-inline-end: 0; } +.timeline { padding-inline-start: 0; } + +.sidebar { + flex: 0 0 auto; + width: 256px; + display: flex; + flex-direction: column; + gap: 8px; + overflow: hidden; +} + +.btn-keyframe { + width: 40px; + height: 36px; + border-radius: 4px; + padding: 0; + justify-content: center; + + background: #7A2C34E3; + color: #FFF; + + &:hover { + background: #90363F; + } +} + +.timeline-nav { + gap: 0; + margin-top: 2px; + + sts-button { + width: 32px; + height: 32px; + padding: 0; + justify-content: center; + background: transparent !important; + backdrop-filter: initial; + color: #FFFC; + font-size: 14px; + + &:hover { + color: #FFFF; + } + + &.play { + font-size: 20px; + } + } +} + +.divider { + position: relative; + flex: 0 0 8px; + margin: { + right: -3px; + left: -3px; + } + cursor: ew-resize; + + &::before { + content: ""; + position: absolute; + top: 0; + right: 3px; + bottom: 0; + left: 3px; + background: #FFF2; + opacity: 0; + transition: opacity 66.666ms linear; + } + + &:hover::before { + opacity: 1; + } +} + +.timeline { + flex: 1 0 0; +} diff --git a/studio-frontend/src/app/anim-editor.element.ts b/studio-frontend/src/app/anim-editor.element.ts new file mode 100644 index 0000000..b108990 --- /dev/null +++ b/studio-frontend/src/app/anim-editor.element.ts @@ -0,0 +1,183 @@ +import * as studio from "@storyteller/studio"; +import { type CameraKeyframesEvent } from "@storyteller/studio"; +import { drag, on } from "@storyteller/framework"; +import { LitElement, type PropertyValues, html, unsafeCSS } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { styleMap } from "lit/directives/style-map.js"; + +import "./anim-timeline.element"; +import "./button.element"; +import "./toolbar.element"; +import "./tree.element"; + +import styles from "./anim-editor.element.scss?inline"; + +@customElement("sts-anim-editor") +export class AnimEditorElement extends LitElement { + static override styles = unsafeCSS(styles); + + @state() sidebarWidth = 256; + + @state() timelineStart = 0; + @state() timelineEnd = 5_000; + + @state() clipStart = 0; + @state() clipEnd = 15_000; + + @state() playHead = 0; + @state() keyframes: Record = {}; + + protected override update(changes: PropertyValues): void { + if (changes.has("playHead")) + studio.seekTime(this.playHead); + + super.update(changes); + } + + @on("window:camera-keyframes") + onCameraKeyframeChanges({ detail: keyframes }: CameraKeyframesEvent): void { + this.keyframes = keyframes; + } + + onSidebarResize(event: PointerEvent): void { + this.sidebarWidth = Math.max(Math.min(this.sidebarWidth + event.movementX, 512), 128); + } + + addKeyframe(): void { + studio.addCameraKeyframe(this.playHead); + } + + jumpToStart(): void { + this.playHead = this.clipStart; + } + + prevKeyframe(): void { + let pos = this.playHead; + + const keyframes = Array.from(Object.values(this.keyframes)).sort((a, b) => b - a); + for (let keyframe of keyframes) { + pos = keyframe; + if (keyframe < this.playHead) + break; + } + + this.playHead = pos; + } + + nextKeyframe(): void { + let pos = this.playHead; + + const keyframes = Array.from(Object.values(this.keyframes)).sort((a, b) => a - b); + for (let keyframe of keyframes) { + pos = keyframe; + if (keyframe > this.playHead) + break; + } + + this.playHead = pos; + } + + jumpToEnd(): void { + this.playHead = this.clipEnd; + } + + #onTimelineStartChange(event: CustomEvent): void { + this.timelineStart = event.detail; + } + + #onTimelineEndChange(event: CustomEvent): void { + this.timelineEnd = event.detail; + } + + #onPlayHeadChange(event: CustomEvent): void { + this.playHead = event.detail; + } + + #onKeyframesChange(event: CustomEvent>): void { + this.keyframes = event.detail; + } + + protected override render = () => html` + + +
+ + + `; +} diff --git a/studio-frontend/src/app/anim-timeline.element.scss b/studio-frontend/src/app/anim-timeline.element.scss new file mode 100644 index 0000000..fa1b681 --- /dev/null +++ b/studio-frontend/src/app/anim-timeline.element.scss @@ -0,0 +1,120 @@ +:host { + position: relative; + overflow: hidden; +} + +*:focus-visible { + outline: none; +} + +.wrapper { + position: absolute; + inset: 0; + + &.panning { + cursor: grabbing; + } +} + +.clip-region { + position: absolute; + top: 0; + bottom: 0; + background: #0004; +} + +.hash { + position: absolute; + top: 0; + bottom: 0; + width: 2px; + background: #FFF1; + + &.strong { + background: #FFF3; + } +} + +.timestamp { + position: absolute; + top: 8px; + color: #FFF6; + font: { + family: "Fira Sans", sans-serif; + size: 14px; + } + user-select: none; + pointer-events: none; + z-index: 1; + + .frac { + color: #FFF3; + } +} + +.playhead { + position: absolute; + top: 0; + bottom: 0; + width: 8px; + transform: translateX(-3px); + cursor: ew-resize; + color: #7A2C34E3; + transition: color 66.667ms linear; + + &:hover { + color: #90363F; + } + + .head { + position: absolute; + top: 0; + left: 0; + width: 8px; + height: 32px; + background: currentColor; + + &::after { + content: ""; + box-sizing: border-box; + position: absolute; + bottom: -12px; + display: block; + width: 8px; + height: 12px; + border: 4px solid transparent { + top: 8px solid currentColor; + } + } + } + + .bar { + position: absolute; + top: 36px; + bottom: 0; + left: 3px; + right: 3px; + background: currentColor; + } +} + +.keyframe { + position: absolute; + top: 50%; + transform: translateX(-4.5px) translateY(-4.5px); + + &::before { + content: ""; + display: block; + width: 9px; + height: 9px; + background: #AAA; + transform: rotate(45deg) { + origin: center center; + } + } + + &.selected::before { + background: #0FF; // TODO + } +} diff --git a/studio-frontend/src/app/anim-timeline.element.ts b/studio-frontend/src/app/anim-timeline.element.ts new file mode 100644 index 0000000..3d95fdd --- /dev/null +++ b/studio-frontend/src/app/anim-timeline.element.ts @@ -0,0 +1,372 @@ +import * as studio from "@storyteller/studio"; +import { type EntitySelectEvent } from "@storyteller/studio"; +import { drag, on } from "@storyteller/framework"; +import { LitElement, PropertyValues, html, nothing, unsafeCSS } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { repeat } from "lit/directives/repeat.js"; +import { styleMap } from "lit/directives/style-map.js"; + +import styles from "./anim-timeline.element.scss?inline"; + +// TODO: This is basically a [signal](https://www.solidjs.com/tutorial/introduction_signals) +// that requires manual dependency tracking. Given that requirement, it's +// questionable whether this is even a valuable abstraction to have. +// +// We should either make it more obviously valuable (e.g. by coming up +// with a way to automatically handle dependencies) and move it to +// `@storyteller/framework`, or just get rid of it. +// +// We could maybe add a decorator that could automatically override the +// `update` method to invalidate the cache when dependencies are changed, +// which would look something like: +// ``` +// @memo(["rangeStart", "rangeEnd", "_renderWidth"]) +// msPerPx = new Computed(() => (this.rangeEnd - this.rangeStart) / this._renderWidth); +// ``` +// But that feels a little obtuse and overengineered. In this particular +// case we're probably only saving on the order of nanoseconds, so I'm +// leaning toward just nuking the idea. +class Computed extends Number { + #value?: number; + #compute: () => number; + + constructor (compute: () => number) { + const value = compute(); + super(value); + this.#compute = compute; + } + + override valueOf(): number { + return this.#value ??= this.#compute(); + } + + get(): number { + return this.valueOf(); + } + + invalidate(): void { + this.#value = undefined; + } +} + +@customElement("sts-anim-timeline") +export class AnimTimelineElement extends LitElement { + static override styles = unsafeCSS(styles); + + /** The time (in ms) at the left edge of the timeline view */ + @property({ type: Number }) rangeStart = 0; + /** The time (in ms) at the right edge of the timeline view */ + @property({ type: Number }) rangeEnd = 5_000; + + /** The time (in ms) at the beginning of the active clip range */ + @property({ type: Number }) clipStart = 0; + /** The time (in ms) at the end of the active clip range */ + @property({ type: Number }) clipEnd = 15_000; + + /** The time (in ms) of the current play-head position */ + @property({ type: Number }) playHead = 0; + /** Keyframe positions (in ms) */ + @property({ attribute: false }) keyframes: Record = {}; + + @state() _selectedKeyframe: string | null = null; + + /** The width (in px) of the timeline view */ + @state() _renderWidth!: number; + + /** The offset from 0ms of the left edge of the timeline view, in px */ + @state() _offsetX = 0; + /** The vertical scroll offset (in px) */ + @state() _offsetY = 0; + + /** + * `true` when the timeline is being mouse-panned. Primarily useful for + * setting the cursor style to the grabby hand. + */ + @state() _panning = false; + + /** How many ms are represented by each px of horizontal space. */ + msPerPx = new Computed(() => (this.rangeEnd - this.rangeStart) / this._renderWidth); + + #resizeObserver: ResizeObserver; + + constructor () { + super(); + this.#resizeObserver = new ResizeObserver(() => this.#updateRenderWidth()); + this.#resizeObserver.observe(this); + } + + override connectedCallback(): void { + super.connectedCallback(); + this.#updateRenderWidth(); + } + + override disconnectedCallback(): void { + super.disconnectedCallback(); + this.#resizeObserver.disconnect(); + } + + protected override update(changes: PropertyValues): void { + if ( + changes.has("rangeStart") + || changes.has("rangeEnd") + || changes.has("_renderWidth") + ) { + this.msPerPx.invalidate(); + } + + super.update(changes); + } + + @on("wheel") + onWheel(event: WheelEvent): void { + event.preventDefault(); + event.stopImmediatePropagation(); + + if (event.ctrlKey) { + this.#zoomTimeline(event.offsetX, event.deltaY); + } else if (event.deltaX) { + this.#pan(-event.deltaX); + } else if (event.shiftKey && event.deltaY) { + this.#pan(-event.deltaY); + } + } + + @on("window:entity-select") + onEntitySelected({ detail: id }: EntitySelectEvent): void { + if (!id) { + this._selectedKeyframe = null; + return; + } + + if (Array.from(Object.keys(this.keyframes)).includes(id)) { + this._selectedKeyframe = id; + this.dispatchEvent(new CustomEvent("playHeadChange", { detail: this.keyframes[id]! })); + } else { + this._selectedKeyframe = null; + } + } + + selectKeyframe(id: string): void { + studio.select(id); + } + + #zoomTimeline(origin: number, delta: number): void { + const currentRange = this.rangeEnd - this.rangeStart; + const deltaRange = delta * 4; + + // FIXME: When zooming the timeline, the transform origin should be + // centered on the mouse cursor. Currently this does not work as + // intended, always centering on the 00:00 timestamp instead. + const t = ((this._offsetX + origin) * this.msPerPx.get()) / currentRange; + console.log(`t: ${t}`); + console.log(`deltaStart: ${-deltaRange * t}`); + console.log(`deltaEnd: ${deltaRange * (1 - t)}`); + const rangeStart = this.rangeStart - deltaRange * t; + const rangeEnd = this.rangeEnd + deltaRange * (1 - t); + + this.dispatchEvent(new CustomEvent("rangeStartChange", { detail: rangeStart })); + this.dispatchEvent(new CustomEvent("rangeEndChange", { detail: rangeEnd })); + } + + #onDragStart(): void { + this._panning = true; + } + + #onDragEnd(): void { + this._panning = false; + } + + #onDrag(event: PointerEvent): void { + this.#pan(event.movementX); + } + + #pan(deltaPx: number): void { + this._offsetX += deltaPx; + + const msPerPx = this.msPerPx.get(); + const rangeStart = this.rangeStart - deltaPx * msPerPx; + const rangeEnd = this.rangeEnd - deltaPx * msPerPx; + + this.dispatchEvent(new CustomEvent("rangeStartChange", { detail: rangeStart })); + this.dispatchEvent(new CustomEvent("rangeEndChange", { detail: rangeEnd })); + } + + #onPlayheadDrag(event: PointerEvent): void { + const deltaMs = event.movementX * this.msPerPx.get(); + const updated = this.playHead + deltaMs; + + this.dispatchEvent(new CustomEvent("playHeadChange", { detail: updated })); + } + + #onKeyframeDrag(id: string, event: PointerEvent): void { + const deltaMs = event.movementX * this.msPerPx.get(); + const updated = this.keyframes[id] + deltaMs; + + studio.updateKeyframe(id, updated); + + const updatedKeyframes = Object.fromEntries( + Object + .entries(this.keyframes) + .map(entry => entry[0] === id + ? [id, updated] + : entry + ) + ); + this.dispatchEvent(new CustomEvent("keyframesChange", { detail: updatedKeyframes })); + } + + #updateRenderWidth(): void { + this._renderWidth = this.getBoundingClientRect().width; + } + + /** + * Format a time value (in ms) for displaying in the timeline view + */ + #timestamp(ms: number) { + const sign = ms < 0 ? "-" : ""; + ms = Math.abs(ms); + + let s = Math.floor(ms / 1000); + let frac = Math.round(ms % 1000); + if (frac === 1000) { + frac = 0; + s += 1; + } + + let m = 0; + if (s >= 60) { + m = Math.floor(s / 60); + s %= 60; + } + + return html`${ + sign + }${ + m.toString(10).padStart(2, "0") + }:${ + s.toString(10).padStart(2, "0") + }`; + } + + /** + * Convert a time value (in ms) to a px offset from the left edge of the view + */ + #msToPx(ms: number): number { + return this._offsetX + ms / this.msPerPx.get(); + } + + protected override render = () => { + const msPerPx = this.msPerPx.get(); + const range = this.rangeEnd - this.rangeStart; + + let subdivsPerSec = 32; + let subdivsCount = (range / 1000) * subdivsPerSec; + let pxPerSubdiv = this._renderWidth / subdivsCount; + + while (pxPerSubdiv < 64) { + subdivsPerSec /= 2; + subdivsCount = (range / 1000) * subdivsPerSec; + pxPerSubdiv = this._renderWidth / subdivsCount; + } + + const msPerSubdiv = msPerPx * pxPerSubdiv; + const subdivs = new Array(Math.ceil(subdivsCount) + 2).fill(null); + + const fracPxOffset = this._offsetX % pxPerSubdiv; + + let startingIdx = -Math.floor(this._offsetX / pxPerSubdiv); + if (fracPxOffset < 0) + startingIdx -= 2; + else + startingIdx -= 1; + + return html` +
+
+ + ${subdivs.map((_, idx) => { + const pxOffset = (idx - 1) * pxPerSubdiv + fracPxOffset; + const ms = (startingIdx + idx) * msPerSubdiv; + + const msFrac = Math.abs(Math.round(ms) % 1000); + const strong = msFrac === 0; + + return html` +
+ ${strong ? html` + + ${this.#timestamp(ms)} + + ` : nothing} + `; + })} + +
+
+
+
+ + ${repeat( + Object.entries(this.keyframes), + ([id]) => id, + ([id, keyframe]) => html` +
this.#onKeyframeDrag(id, event), + })} + @click=${() => this.selectKeyframe(id)} + >
+ ` + )} +
+ `; + } +} diff --git a/studio-frontend/src/app/app.element.scss b/studio-frontend/src/app/app.element.scss index 640c3d6..fc4a85b 100644 --- a/studio-frontend/src/app/app.element.scss +++ b/studio-frontend/src/app/app.element.scss @@ -1,3 +1,5 @@ +$hierarchy-width: 290px; + .app-root { position: fixed; inset: 0; @@ -8,12 +10,19 @@ position: absolute; top: 16px; } +.v-end { + position: absolute; + bottom: 16px; +} .v-after-toolbar { position: absolute; top: 60px; } .h-start { left: 16px } .h-end { right: 16px } +.h-before-hierarchy { + right: $hierarchy-width + 32px; +} .h-center { left: 50%; transform: translateX(-50%); @@ -29,7 +38,7 @@ sts-button.active { overflow: auto; box-sizing: border-box; - width: 290px; + width: $hierarchy-width; max-height: calc(100vh - 32px); padding: 10px 15px; diff --git a/studio-frontend/src/app/app.element.ts b/studio-frontend/src/app/app.element.ts index 989d64f..2bc2427 100644 --- a/studio-frontend/src/app/app.element.ts +++ b/studio-frontend/src/app/app.element.ts @@ -22,6 +22,7 @@ import "@storyteller/studio-web/canvas-provider"; import "@storyteller/studio-web/viewer"; import "@storyteller/studio-web/bvh-viewer"; import "@storyteller/studio-web/mixamo-viewer"; +import "./anim-editor.element"; import "./button.element"; import "./help.element"; import "./icon.element"; @@ -77,6 +78,8 @@ export class AppElement extends LitElement { "viewer": () => StudioMode.Viewer, _: () => StudioMode.Viewer, }); + + this.#redirectBodyFocus(); } protected override createRenderRoot(): Element | ShadowRoot { @@ -189,6 +192,20 @@ export class AppElement extends LitElement { console.log("Hierarchy:", this.sceneObjects); } + #redirectBodyFocus(): void { + // If user focus lands on the `document.body`, neither the frontend app + // nor the Bevy app will properly handle keyboard events. Thie function + // runs every tick to ensure that user focus never becomes "stranded" in + // this way. + if (document.activeElement === document.body) { + const canvasId = this.#canvasProvider.value?.canvasId; + if (canvasId) + document.getElementById(canvasId)?.focus(); + } + + requestAnimationFrame(() => this.#redirectBodyFocus()); + } + protected override render = () => html` ` : nothing} + ${this.mode === StudioMode.Editor ? html` + + ` : nothing} + ${this.showHelp ? html` ` : nothing} diff --git a/studio-frontend/src/app/button.element.scss b/studio-frontend/src/app/button.element.scss index fc79cde..085f9a9 100644 --- a/studio-frontend/src/app/button.element.scss +++ b/studio-frontend/src/app/button.element.scss @@ -19,7 +19,11 @@ background: #0006; color: #FFF; backdrop-filter: blur(16px); - transition: background 0.1s linear; + transition: { + property: background, color; + duration: 0.1s; + timing-function: linear; + } } :host(:hover) { diff --git a/studio-frontend/src/app/help.element.ts b/studio-frontend/src/app/help.element.ts index 4cbef5c..dbf609c 100644 --- a/studio-frontend/src/app/help.element.ts +++ b/studio-frontend/src/app/help.element.ts @@ -13,7 +13,7 @@ export class HelpElement extends LitElement { ${section("Navigation", [ { name: "Pan View", controls: "MMB" }, { name: "Orbit around point", controls: "Alt + LMB" }, - { name: "Zoom", controls: ["Alt + RMB", "Mouse Wheel"]}, + { name: "Zoom", controls: ["Alt + RMB", "Scroll"]}, { name: "Free fly", controls: "W, A, S, D, E, Q" }, { name: "Free look", controls: ["RMB", "Shift"] }, ])} @@ -21,6 +21,11 @@ export class HelpElement extends LitElement { { name: "Select", controls: "LMB" }, { name: "Clear selection", controls: "Esc" }, { name: "Focus selection", controls: "F" }, + { name: "Delete selection", controls: "Delete" }, + ])} + ${section("Animation Timeline", [ + { name: "Pan", controls: ["MMB", "Scroll"] }, + { name: "Zoom", controls: "Ctrl + Scroll" }, ])} ${isDevEnvironment() ? section("Developer", [ diff --git a/studio-frontend/src/app/icon.element.ts b/studio-frontend/src/app/icon.element.ts index 9788b68..668a344 100644 --- a/studio-frontend/src/app/icon.element.ts +++ b/studio-frontend/src/app/icon.element.ts @@ -4,10 +4,18 @@ import { LitElement, TemplateResult, html, nothing, unsafeCSS } from "lit"; import { customElement, property } from "lit/decorators.js"; import { unsafeSVG } from "lit/directives/unsafe-svg.js"; +import farCrosshairs from "@fortawesome/fontawesome-pro/svgs/regular/crosshairs.svg?raw"; +import farVideo from "@fortawesome/fontawesome-pro/svgs/regular/video.svg?raw"; import fasCircleInfo from "@fortawesome/fontawesome-pro/svgs/regular/circle-info.svg?raw"; +import fasKey from "@fortawesome/fontawesome-pro/svgs/solid/key.svg?raw"; import fasCube from "@fortawesome/fontawesome-pro/svgs/regular/cube.svg?raw"; import fasGlobe from "@fortawesome/fontawesome-pro/svgs/regular/globe.svg?raw"; import fasUpDownLeftRight from "@fortawesome/fontawesome-pro/svgs/regular/arrows-up-down-left-right.svg?raw"; +import fasPlay from "@fortawesome/fontawesome-pro/svgs/solid/play.svg?raw"; +import fasFwdStep from "@fortawesome/fontawesome-pro/svgs/solid/forward-step.svg?raw"; +import fasFwdFast from "@fortawesome/fontawesome-pro/svgs/solid/forward-fast.svg?raw"; +import fasBwdStep from "@fortawesome/fontawesome-pro/svgs/solid/backward-step.svg?raw"; +import fasBwdFast from "@fortawesome/fontawesome-pro/svgs/solid/backward-fast.svg?raw"; import fasRotate from "@fortawesome/fontawesome-pro/svgs/regular/arrows-rotate.svg?raw"; import fasScale from "@fortawesome/fontawesome-pro/svgs/regular/arrow-up-right-and-arrow-down-left-from-center.svg?raw"; import fasCaretRight from "@fortawesome/fontawesome-pro/svgs/solid/caret-right.svg?raw"; @@ -37,13 +45,21 @@ function renderSvg(iconId: string) { return RENDER_RESULTS.get(iconId)!; const svgSrc = match (iconId, { + "bwd-fast": () => fasBwdFast, + "bwd-step": () => fasBwdStep, "circle-info": () => fasCircleInfo, "caret-right": () => fasCaretRight, + "crosshairs": () => farCrosshairs, "cube": () => fasCube, + "fwd-fast": () => fasFwdFast, + "fwd-step": () => fasFwdStep, + "key": () => fasKey, "globe": () => fasGlobe, - "up-down-left-right": () => fasUpDownLeftRight, + "play": () => fasPlay, "rotate": () => fasRotate, "scale": () => fasScale, + "up-down-left-right": () => fasUpDownLeftRight, + "video": () => farVideo, _: () => null, }); diff --git a/studio-frontend/src/app/tree.element.scss b/studio-frontend/src/app/tree.element.scss index c5a2d87..82f5558 100644 --- a/studio-frontend/src/app/tree.element.scss +++ b/studio-frontend/src/app/tree.element.scss @@ -1,3 +1,5 @@ +$item-height: 24px; + :host, .children { display: flex; flex-direction: column; @@ -31,7 +33,7 @@ header { timing-function: linear; } - &:hover:not(:has(.toggle-expanded:hover)) { + &.selectable:hover:not(:has(.toggle-expanded:hover)) { background: #0000001F; } @@ -52,7 +54,7 @@ header { justify-content: center; flex: 0 0 auto; width: 16px; - height: 24px; + height: $item-height; margin-block: -5px; padding-inline-start: 4px; @@ -72,12 +74,13 @@ header { transform: rotate(90deg); } -.name { +.label { + display: flex; flex: 1 0 0; - padding: { - block: 5px; - inline: 5px 10px; - } + height: $item-height; + align-items: center; + gap: 8px; + padding-inline-start: 5px; } .children { diff --git a/studio-frontend/src/app/tree.element.ts b/studio-frontend/src/app/tree.element.ts index 64008d0..3911fcc 100644 --- a/studio-frontend/src/app/tree.element.ts +++ b/studio-frontend/src/app/tree.element.ts @@ -4,6 +4,7 @@ import { type EntitySelectEvent } from "@storyteller/studio"; import { LitElement, html, nothing, unsafeCSS } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { classMap } from "lit/directives/class-map.js"; +import { ifDefined } from "lit/directives/if-defined.js"; import "./icon.element"; @@ -20,8 +21,9 @@ export class TreeElement extends LitElement { static override styles = unsafeCSS(styles); @property() name = ""; - @property() treeChildren?: Tree[]; - @property() expanded = false; + @property() icon?: string; + @property({ attribute: false }) treeChildren?: Tree[]; + @property({ type: Boolean }) expanded = false; @state() selected = false; @@ -35,12 +37,18 @@ export class TreeElement extends LitElement { } selectEntity(): void { - studio.select(this.id); + if (this.id) + studio.select(this.id); } // TODO: A11y protected override render = () => html` -
+
${this.treeChildren?.length ? html` ` : nothing} - + ${this.icon ? html` + + ` : nothing} ${this.name}
@@ -66,7 +77,7 @@ export class TreeElement extends LitElement {
${this.treeChildren?.map(tree => html` diff --git a/studio-web/src/lib/canvas-provider.element.ts b/studio-web/src/lib/canvas-provider.element.ts index 9a56fed..a8a18c9 100644 --- a/studio-web/src/lib/canvas-provider.element.ts +++ b/studio-web/src/lib/canvas-provider.element.ts @@ -80,6 +80,7 @@ export class CanvasProviderElement const canvas = document.createElement("canvas"); canvas.id = this.#canvasId; canvas.slot = "canvas"; + canvas.tabIndex = -1; this.appendChild(canvas); diff --git a/studio/Cargo.toml b/studio/Cargo.toml index 7387d17..62dd252 100644 --- a/studio/Cargo.toml +++ b/studio/Cargo.toml @@ -24,6 +24,7 @@ bevy_mod_outline = "0.6.0" bevy_web_asset = "0.7.0" bitflags = "2.4.0" console_error_panic_hook = { version = "0.1.7", optional = true } +itertools = "0.12.1" js-sys = { version = "0.3.65", optional = true } parking_lot = "0.12.1" serde = { version = "1.0.192", optional = true } diff --git a/studio/src/anim/camera.rs b/studio/src/anim/camera.rs new file mode 100644 index 0000000..eab3be6 --- /dev/null +++ b/studio/src/anim/camera.rs @@ -0,0 +1,208 @@ +use bevy::prelude::*; +use itertools::Itertools; +use space_editor::space_prefab::editor_registry::EditorRegistryExt; + +use crate::math::{InvLerp, Lerp}; + +use super::GlobalSeekTime; + +pub struct CameraAnimPlugin; +impl Plugin for CameraAnimPlugin { + fn build(&self, app: &mut App) { + app.register_type::() + .editor_registry::() + .register_type::() + .editor_registry::(); + + app.add_systems(Update, draw_camera_keyframes); + + #[cfg(feature = "wasm")] + app.add_systems( + Update, + ( + wasm::spawn_camera_keyframes, + wasm::notify_keyframe_changes.map(bevy::utils::error), + wasm::process_update_keyframe, + ), + ); + } +} + +#[derive(Component, Clone, Copy, Debug, Default, Deref, DerefMut, Reflect)] +#[reflect(Component)] +pub struct CameraKeyframe(pub f32); + +#[derive(Component, Clone, Copy, Debug, Default, Deref, DerefMut, Reflect)] +#[reflect(Component)] +pub struct CameraTargetKeyframe(pub f32); + +fn draw_camera_keyframes( + mut gizmos: Gizmos, + r_seek_time: Res, + q_cam_keyframe_xforms: Query<&GlobalTransform, With>, + q_cam_target_keyframe_xforms: Query<&GlobalTransform, With>, + q_cam_keyframes: Query<(&CameraKeyframe, &GlobalTransform)>, +) { + if q_cam_keyframes.is_empty() { + return; + } + + for world_xform in q_cam_keyframe_xforms + .iter() + .chain(q_cam_target_keyframe_xforms.iter()) + { + let origin = world_xform.translation(); + let x_axis = world_xform.right() * 0.25; + let y_axis = world_xform.up() * 0.25; + let z_axis = world_xform.back() * 0.25; + + gizmos.line(origin, origin + x_axis, Color::RED); + gizmos.line(origin, origin + y_axis, Color::GREEN); + gizmos.line(origin, origin + z_axis, Color::BLUE); + } + + let seek_time = **r_seek_time; + let keyframes_sorted = q_cam_keyframes + .iter() + .sorted_by(|(a, _), (b, _)| a.partial_cmp(&b.0).unwrap()) + .collect_vec(); + + let (timestamp_first, xform_first) = keyframes_sorted.first().unwrap(); + let (timestamp_last, xform_last) = keyframes_sorted.last().unwrap(); + + if seek_time <= timestamp_first.0 { + let (_, rot, pos) = xform_first.to_scale_rotation_translation(); + gizmos.sphere(pos, rot, 0.25, Color::WHITE); + } else if seek_time >= timestamp_last.0 { + let (_, rot, pos) = xform_last.to_scale_rotation_translation(); + gizmos.sphere(pos, rot, 0.25, Color::WHITE); + } else if let Some(((timestamp_a, xform_a), (timestamp_b, xform_b))) = keyframes_sorted + .iter() + .tuple_windows() + .find(|((a, _), (b, _))| a.0 <= seek_time && b.0 >= seek_time) + { + let t = seek_time.inv_lerp(timestamp_a.0, timestamp_b.0); + let (_, rot_a, pos_a) = xform_a.to_scale_rotation_translation(); + let (_, rot_b, pos_b) = xform_b.to_scale_rotation_translation(); + let pos = t.lerp(pos_a, pos_b); + let rot = Quat::slerp(rot_a, rot_b, t); + + gizmos.sphere(pos, rot, 0.25, Color::WHITE); + } +} + +#[cfg(feature = "wasm")] +mod wasm { + use std::sync::Arc; + + use bevy::{prelude::*, window::PrimaryWindow}; + use space_editor::prelude::space_undo::{self, AddedEntity}; + use wasm_bindgen::prelude::*; + + use crate::{ + camera_controller::CameraController, + wasm::{self, FromStr, StaticBuffer, WasmMessageBuffer}, + }; + + use super::{CameraKeyframe, CameraTargetKeyframe}; + + static ADD_KEYFRAME: WasmMessageBuffer = WasmMessageBuffer::new(); + static UPDATE_KEYFRAME: WasmMessageBuffer<(Entity, f32)> = WasmMessageBuffer::new(); + + #[wasm_bindgen(js_name = addCameraKeyframe)] + pub fn add_camera_keyframe(timestamp: f32) { + ADD_KEYFRAME.write_message(timestamp); + } + + pub(super) fn spawn_camera_keyframes( + mut cmd: Commands, + mut ew_changes: EventWriter, + q_camera: Query<(&CameraController, &GlobalTransform)>, + ) { + if let Some(timestamp) = ADD_KEYFRAME.take_message() { + let Ok((cam_controller, world_xform)) = q_camera.get_single() else { + return; + }; + + let entity = cmd + .spawn(( + Name::new("Camera Target Keyframe"), + TransformBundle::from_transform(Transform::from_translation( + cam_controller.focus, + )), + CameraTargetKeyframe(timestamp), + )) + .id(); + ew_changes.send(space_undo::NewChange { + change: Arc::new(AddedEntity { entity }), + }); + + let entity = cmd + .spawn(( + Name::new("Camera Keyframe"), + TransformBundle::from_transform(Transform::from(*world_xform)), + CameraKeyframe(timestamp), + )) + .id(); + ew_changes.send(space_undo::NewChange { + change: Arc::new(AddedEntity { entity }), + }); + } + } + + #[wasm_bindgen(js_name = updateKeyframe)] + pub fn update_keyframe(entity: &str, timestamp: f32) { + let entity = Entity::from_str(entity).unwrap(); + UPDATE_KEYFRAME.write_message((entity, timestamp)); + } + + pub(super) fn process_update_keyframe( + mut q_camera_keyframes: Query<&mut CameraKeyframe>, + mut q_camera_target_keyframes: Query<&mut CameraTargetKeyframe>, + ) { + if let Some((ent, timestamp)) = UPDATE_KEYFRAME.take_message() { + if let Ok(mut keyframe) = q_camera_keyframes.get_mut(ent) { + **keyframe = timestamp; + } else if let Ok(mut keyframe) = q_camera_target_keyframes.get_mut(ent) { + **keyframe = timestamp; + } else { + warn!("No matching keyframe found for entity: {ent:?}"); + } + } + } + + #[wasm_bindgen(typescript_custom_section)] + const CAMERA_KEYFRAMES_EVENT: &str = r#" +export interface CameraKeyframesEvent extends CustomEvent { + type: "camera-keyframes"; + detail: Record; +} + +declare global { + export interface GlobalEventHandlersEventMap { + "camera-keyframes": CameraKeyframesEvent; + } +} + "#; + + pub(super) fn notify_keyframe_changes( + mut l_notified: Local>, + q_keyframes: Query<(Entity, &CameraKeyframe)>, + q_window: Query<&Window, With>, + ) -> Result<(), String> { + if l_notified.len() == q_keyframes.iter().count() { + return Ok(()); + } + + let Ok(window) = q_window.get_single() else { + return Ok(()); + }; + + l_notified.clear(); + for (ent, timestamp) in q_keyframes.iter() { + l_notified.insert(format!("{ent:?}"), timestamp.0.into()); + } + + wasm::dispatch_to_js(window, "camera-keyframes", &*l_notified) + } +} diff --git a/studio/src/anim/mod.rs b/studio/src/anim/mod.rs index 1f03b7c..6c512fb 100644 --- a/studio/src/anim/mod.rs +++ b/studio/src/anim/mod.rs @@ -9,6 +9,7 @@ use space_editor::space_prefab::editor_registry::EditorRegistryExt; use crate::hierarchy; pub use retargeting::*; +mod camera; mod retargeting; pub struct AnimPlugin; @@ -28,11 +29,19 @@ impl Plugin for AnimPlugin { .editor_registry::(); app.add_systems(Update, process_skinned_meshes); + app.insert_resource(GlobalSeekTime(0.)); - app.add_plugins(retargeting::RetargetingPlugin); + app.add_plugins((retargeting::RetargetingPlugin, camera::CameraAnimPlugin)); + + #[cfg(feature = "wasm")] + app.add_systems(Update, wasm::update_global_seek_time); } } +#[derive(Resource, Clone, Copy, Debug, Default, Deref, DerefMut, Reflect)] +#[reflect(Resource)] +pub struct GlobalSeekTime(pub f32); + #[derive(Component, Clone, Copy, Debug, Default, Reflect)] #[reflect(Component)] pub struct Skeleton; @@ -139,3 +148,26 @@ fn process_skinned_meshes( } } } + +#[cfg(feature = "wasm")] +mod wasm { + use bevy::prelude::*; + use wasm_bindgen::prelude::*; + + use crate::wasm::{StaticBuffer, WasmMessageBuffer}; + + use super::GlobalSeekTime; + + static SEEK_TIME: WasmMessageBuffer = WasmMessageBuffer::new(); + + #[wasm_bindgen(js_name = seekTime)] + pub fn seek_time(timestamp: f32) { + SEEK_TIME.write_message(timestamp); + } + + pub(super) fn update_global_seek_time(mut r_seek_time: ResMut) { + if let Some(timestamp) = SEEK_TIME.take_message() { + **r_seek_time = timestamp; + } + } +} diff --git a/studio/src/input.rs b/studio/src/input.rs index 30add81..32882e2 100644 --- a/studio/src/input.rs +++ b/studio/src/input.rs @@ -79,6 +79,8 @@ pub enum Selection { Clear, /// Focus the camera on the currently selected entity Focus, + /// Delete the currently selected entity and its descendants + Delete, } impl From for Action { fn from(value: Selection) -> Self { @@ -100,6 +102,12 @@ fn translate_selection_events(keyboard: Res>, mut input: EventWri } else if keyboard.just_released(KeyCode::F) { input.send(InputAction(Lifecycle::Stop, Selection::Focus.into())); } + + if keyboard.just_pressed(KeyCode::Delete) { + input.send(InputAction(Lifecycle::Start, Selection::Delete.into())); + } else if keyboard.just_released(KeyCode::Delete) { + input.send(InputAction(Lifecycle::Stop, Selection::Delete.into())); + } } fn translate_debug_toggle(keyboard: Res>, mut input: EventWriter) { diff --git a/studio/src/inspector/wasm.rs b/studio/src/inspector/wasm.rs index 6622087..66c2548 100644 --- a/studio/src/inspector/wasm.rs +++ b/studio/src/inspector/wasm.rs @@ -52,7 +52,7 @@ export interface EntityMultiSpawnEvent extends CustomEvent { } declare global { - export interface HTMLElementEventMap { + export interface GlobalEventHandlersEventMap { "entity-spawn": EntitySpawnEvent; "entity-despawn": EntityDespawnEvent; "entity-multi-spawn": EntityMultiSpawnEvent; diff --git a/studio/src/interaction/selection.rs b/studio/src/interaction/selection.rs index f73a138..3c42ae9 100644 --- a/studio/src/interaction/selection.rs +++ b/studio/src/interaction/selection.rs @@ -1,8 +1,11 @@ +use std::sync::Arc; + use bevy::{prelude::*, render::mesh::skinning::SkinnedMesh}; use bevy_mod_outline::{ AutoGenerateOutlineNormalsPlugin, OutlineBundle, OutlinePlugin, OutlineVolume, }; use bevy_mod_picking::{prelude::Pointer, selection::Select, PickableBundle}; +use space_editor::prelude::space_undo::{self, NewChange, RemovedEntity}; use crate::{ input::{self, Action, InputAction, Lifecycle}, @@ -13,7 +16,13 @@ pub struct SelectionPlugin; impl Plugin for SelectionPlugin { fn build(&self, app: &mut App) { app.add_plugins((OutlinePlugin, AutoGenerateOutlineNormalsPlugin)) - .add_systems(Update, update_selection) + .add_systems( + Update, + ( + update_selection, + process_delete_inputs.run_if(resource_exists::()), + ), + ) .add_systems( PostUpdate, draw_selection_outline.run_if(resource_changed_or_removed::()), @@ -149,6 +158,28 @@ fn update_selection( } } +fn process_delete_inputs( + mut cmd: Commands, + mut er_input: EventReader, + mut ew_changes: EventWriter, + r_selection: Res, +) { + if er_input.read().any(|action| { + matches!( + action, + InputAction(Lifecycle::Stop, Action::Selection(input::Selection::Delete)) + ) + }) { + let entity = **r_selection; + + cmd.entity(entity).despawn_recursive(); + cmd.remove_resource::(); + ew_changes.send(NewChange { + change: Arc::new(RemovedEntity { entity }), + }); + } +} + fn draw_selection_outline( mut cmd: Commands, q_selected: Query<&Children, With>, @@ -193,7 +224,7 @@ mod wasm { use wasm_bindgen::prelude::*; use super::{Selected, Selection}; - use crate::wasm::{self, StaticBuffer, WasmMessageBuffer}; + use crate::wasm::{self, FromStr, StaticBuffer, WasmMessageBuffer}; #[wasm_bindgen(typescript_custom_section)] const EVENT_DECLARATION: &str = r#" @@ -207,7 +238,7 @@ export interface EntitySelectEvent extends CustomEvent { } declare global { - export interface HTMLElementEventMap { + export interface GlobalEventHandlersEventMap { "entity-select": EntitySelectEvent; } } @@ -225,12 +256,7 @@ declare global { #[wasm_bindgen] pub fn select(entity: &str) { - let mut split = entity.split('v'); - let index = split.next().unwrap().parse::().unwrap(); - let generation = split.next().unwrap().parse::().unwrap(); - let bits = (generation as u64) << 32 | index as u64; - - let entity = Entity::from_bits(bits); + let entity = Entity::from_str(entity).unwrap(); SELECTION_REQUEST.write_message(entity); } diff --git a/studio/src/scene.rs b/studio/src/scene.rs index 6649c4d..2f04039 100644 --- a/studio/src/scene.rs +++ b/studio/src/scene.rs @@ -460,7 +460,7 @@ export interface SceneStateEvent extends CustomEvent { } declare global { - export interface HTMLElementEventMap { + export interface GlobalEventHandlersEventMap { "scene-state": SceneStateEvent; } } diff --git a/studio/src/wasm/conv.rs b/studio/src/wasm/conv.rs index e7587dd..b7c4af3 100644 --- a/studio/src/wasm/conv.rs +++ b/studio/src/wasm/conv.rs @@ -83,6 +83,12 @@ impl AsJson for GlobalTransform { } } +impl AsJson for serde_json::Map { + fn as_json(&self) -> JsonValue { + JsonValue::Object(self.clone()) + } +} + impl AsJsValue for T where T: AsJson, @@ -138,3 +144,38 @@ impl AsJsValue for u32 { Ok(JsValue::from_f64(*self as f64)) } } + +/// A crate-local version of `std::str::FromStr` that can be implemented for +/// foreign types +pub trait FromStr: Sized { + type Err; + + fn from_str(s: &str) -> Result; +} + +impl FromStr for Entity { + type Err = String; + + fn from_str(s: &str) -> Result { + let fmt_err = + || format!("Expected a string with format 'v', found '{s}'"); + + let mut split = s.split('v'); + + let index = split + .next() + .unwrap() + .parse::() + .map_err(|_| fmt_err())?; + + let generation = split + .next() + .unwrap() + .parse::() + .map_err(|_| fmt_err())?; + + let bits = (generation as u64) << 32 | index as u64; + + Ok(Entity::from_bits(bits)) + } +} From 3258292980cbfc478b014329d1bc2006c017c7fa Mon Sep 17 00:00:00 2001 From: Brooks Palin Date: Fri, 23 Feb 2024 14:18:20 -0700 Subject: [PATCH 02/13] Adding Mixamo Animations to Studio Headless (#50) This PR adds the ability to render out mixamo animations from the headless mode. In addition to that, there were some bugs that have been managed and some readability changes. Let me know if you have any questions! --- studio/src/lib.rs | 64 ++++++++++++++++++++++++----- studio/src/main-headless.rs | 38 +++++++++++++++++ studio/src/scene.rs | 18 ++++++--- studio/src/screenshot.rs | 81 +++++++++++++++++++++---------------- 4 files changed, 151 insertions(+), 50 deletions(-) diff --git a/studio/src/lib.rs b/studio/src/lib.rs index 62ee32d..a449892 100644 --- a/studio/src/lib.rs +++ b/studio/src/lib.rs @@ -244,6 +244,7 @@ pub fn start_internal( let mut app = App::new(); + app.insert_resource(HeadlessMode::None); app.insert_resource(studio_mode); app.add_plugins(( @@ -284,9 +285,12 @@ pub fn start_internal( app } +#[derive(Debug, Resource, Clone)] pub enum HeadlessMode { Bvh(String, String), Scene(String, String), + Mixamo(String, String), + None, } pub fn start_headless( @@ -298,9 +302,10 @@ pub fn start_headless( ) -> App { let mut app = App::new(); + app.insert_resource(mode.clone()); app.insert_resource(StudioMode::Headless); app.insert_resource(HeadlessSettings { - frames_to_capture, + max_frames: frames_to_capture, output_dims: image_res, output_dir: outout_dir.to_string(), }); @@ -330,7 +335,7 @@ pub fn start_headless( }, ); - app.add_systems(PostUpdate, check_for_capture_complete); + app.add_systems(PostUpdate, check_for_bvh_capture_complete); } HeadlessMode::Scene(scene, skybox) => { app.add_systems( @@ -341,6 +346,23 @@ pub fn start_headless( }, ); } + HeadlessMode::Mixamo(mixamo_path, skybox) => { + app.add_plugins(MixamoPlugin); + app.add_systems( + Startup, + move |mut commands: Commands, + mut ew: EventWriter, + mut load_scene_event: EventWriter| { + ew.send(MixamoImportEvent(mixamo_path.clone())); + load_scene_event.send(LoadSceneEvent("Mannequin.gltf".to_string())); + commands.insert_resource(SkyboxId(skybox.clone())); + }, + ); + app.add_systems(PostUpdate, check_for_mixamo_capture_complete); + + app.run(); + } + HeadlessMode::None => {} } app @@ -358,7 +380,7 @@ pub fn is_not_headless(studio_state: Res) -> bool { pub struct HeadlessSettings { pub output_dims: Extent3d, pub output_dir: String, - pub frames_to_capture: u32, + pub max_frames: u32, } impl Default for HeadlessSettings { @@ -370,23 +392,45 @@ impl Default for HeadlessSettings { depth_or_array_layers: 1, }, output_dir: "./screen_shots/".to_string(), - frames_to_capture: 1, + max_frames: u32::MAX, } } } -fn check_for_capture_complete( - mut commands: Commands, +fn check_for_bvh_capture_complete( mut close_app: EventWriter, - main_camera: Query<(Entity, &ScreenCapture), With>, + mut main_camera: Query<&mut ScreenCapture, With>, bvh_event_reader: EventReader, ) { - let Ok((entity, screen_capture)) = main_camera.get_single() else { + let Ok(mut screen_capture) = main_camera.get_single_mut() else { return; }; - if screen_capture.is_complete() || !bvh_event_reader.is_empty() { - commands.entity(entity).remove::(); + println!("Frames captured {}", screen_capture.frames_captured()); + if !screen_capture.should_capture() || !bvh_event_reader.is_empty() { + screen_capture.stop_capturing(); close_app.send(AppExit); } } + +fn check_for_mixamo_capture_complete( + mut close_app: EventWriter, + mut main_camera: Query<&mut ScreenCapture, With>, + mixamo_anims: Query<&AnimationPlayer>, +) { + let Ok(mut capture) = main_camera.get_single_mut() else { + return; + }; + + for anim in mixamo_anims.iter() { + println!( + "Time elapsed {} | Frames Captured : {}", + anim.elapsed(), + capture.frames_captured() + ); + if anim.completions() != 0 { + capture.stop_capturing(); + close_app.send(AppExit); + } + } +} diff --git a/studio/src/main-headless.rs b/studio/src/main-headless.rs index e8edcc0..da01023 100644 --- a/studio/src/main-headless.rs +++ b/studio/src/main-headless.rs @@ -43,6 +43,19 @@ enum Subcommands { #[arg(long, value_parser = clap::value_parser!(u32).range(1..))] frames: Option, }, + Mixamo { + mixamo_dir: String, + #[arg(long, short = 'o', short)] + out: Option, + #[arg(long)] + skybox: Option, + #[arg(long = "res", value_parser = extent3d_parser)] + output_resolution: Option, + #[arg(long, value_parser = clap::value_parser!(u32).range(1..))] + fps: Option, + #[arg(long, value_parser = clap::value_parser!(u32).range(1..))] + frames: Option, + }, } #[derive(Args, Clone)] @@ -102,6 +115,31 @@ fn main() { output_res, ) } + Subcommands::Mixamo { + mixamo_dir, + out, + skybox, + output_resolution, + fps, + frames, + } => { + let output_dir = out.unwrap_or("./screen_shots/".to_string()); + let output_res = output_resolution.unwrap_or(Extent3d { + width: 1280, + height: 720, + depth_or_array_layers: 1, + }); + let fps = fps.unwrap_or(24); + let frames = frames.unwrap_or(u32::MAX); + let skybox = skybox.unwrap_or("gum_trees_4k".to_string()); + start_headless( + HeadlessMode::Mixamo(mixamo_dir, skybox), + fps, + &output_dir, + frames, + output_res, + ) + } }; app.run(); diff --git a/studio/src/scene.rs b/studio/src/scene.rs index 2f04039..ed32e68 100644 --- a/studio/src/scene.rs +++ b/studio/src/scene.rs @@ -48,7 +48,12 @@ impl Plugin for ScenePlugin { .add_systems(Update, init_scene_loading.in_set(SceneSpawnerSystem)) .add_systems( OnEnter(SceneState::Active), - (tag_scene_elements, frame_scene_in_view).in_set(SceneSpawnerSystem), + ( + tag_scene_elements, + frame_scene_in_view, + start_capture.run_if(is_headless), + ) + .in_set(SceneSpawnerSystem), ); app.add_systems(Update, tag_scene_elements); @@ -261,10 +266,7 @@ fn initialiaze_headless( ..default() }, CameraControllerBundle::new(focus, camera_xform.translation), - ScreenCapture::number_of_frames( - headless_settings.frames_to_capture, - &headless_settings.output_dir, - ), + ScreenCapture::from_out(&headless_settings.output_dir), )); } @@ -429,6 +431,12 @@ fn frame_scene_in_view( cam_xform.translation = cam.focus + cam_xform.back() * radius; } +fn start_capture(mut captures: Query<&mut ScreenCapture>) { + for mut capture in captures.iter_mut() { + capture.start_capturing(); + } +} + #[cfg(feature = "wasm")] mod wasm { use bevy::{prelude::*, window::PrimaryWindow}; diff --git a/studio/src/screenshot.rs b/studio/src/screenshot.rs index 001691c..f773d13 100644 --- a/studio/src/screenshot.rs +++ b/studio/src/screenshot.rs @@ -30,8 +30,7 @@ impl Plugin for ScreenShotPlugin { fn build(&self, app: &mut App) { app.add_systems( Update, - (test_system, update_screen_capture_on_extract_step) - .run_if(in_state(SceneState::Active)), + (update_screen_capture_on_extract_step).run_if(in_state(SceneState::Active)), ); let Ok(render_world) = app.get_sub_app_mut(bevy::render::RenderApp) else { @@ -65,60 +64,73 @@ impl Plugin for ScreenShotPlugin { } } -fn test_system( - mut commands: Commands, - camera: Query>, - input: Res>, -) { - if input.just_pressed(KeyCode::F10) { - for entity in camera.iter() { - commands - .entity(entity) - .insert(ScreenCapture::number_of_frames(16, "./scrnshot/")); - } - } -} - //============================================================================== // Sceen Shot Component //============================================================================== #[derive(Component, Clone)] pub struct ScreenCapture { - number_of_frames: u32, + frames: u32, + max_frames: u32, to_directory: String, capture_depth: bool, + currently_captureing: bool, } impl ScreenCapture { - pub fn number_of_frames(frames: u32, output_dir: &str) -> Self { + pub fn from_out(output_dir: &str) -> Self { ScreenCapture { - number_of_frames: frames, + frames: 0, to_directory: output_dir.to_string(), capture_depth: false, + currently_captureing: false, + max_frames: u32::MAX, } } + pub fn with_max_frames(mut self, max_frames: u32) -> Self { + self.max_frames = max_frames; + self + } + pub fn capture_depth(mut self) -> Self { self.capture_depth = true; self } - pub fn is_complete(&self) -> bool { - println!("Number of Frames Left: {}", self.number_of_frames); - self.number_of_frames == 1 + pub fn is_capturing(&self) -> bool { + self.currently_captureing + } + + pub fn stop_capturing(&mut self) { + self.currently_captureing = false; + } + + pub fn start_capturing(&mut self) { + self.currently_captureing = true; + } + + pub fn should_capture(&self) -> bool { + self.frames < self.max_frames && self.is_capturing() + } + + pub fn frames_captured(&self) -> u32 { + self.frames + } + + pub fn max_frames(&self) -> u32 { + self.max_frames } } fn update_screen_capture_on_extract_step( - mut commands: Commands, - mut screen_captures: Query<(Entity, &mut ScreenCapture)>, + mut screen_captures: Query<&mut ScreenCapture>, ) { - for (entity, mut screen_capture) in screen_captures.iter_mut() { - screen_capture.number_of_frames -= 1; - if screen_capture.number_of_frames == 0 { - commands.entity(entity).remove::(); - } + for mut screen_capture in screen_captures.iter_mut() { + screen_capture.frames += 1; + // if screen_capture.number_of_frames == 0 { + // commands.entity(entity).remove::(); + // } } } @@ -128,7 +140,9 @@ fn extract_screen_capture_components( screen_capure_comps: Extract>>, ) { for (entity, screen_capture) in screen_capure_comps.iter() { - commands.get_or_spawn(entity).insert(screen_capture.clone()); + if screen_capture.should_capture() { + commands.get_or_spawn(entity).insert(screen_capture.clone()); + } } } @@ -152,7 +166,7 @@ fn prepare_screen_capture_buffers( device: Res, ) { for (entity, view_target, screen_capture) in views.iter() { - if screen_capture.number_of_frames > 0 { + if screen_capture.frames > 0 { let texture = view_target.main_texture(); let size = texture.size(); let format = texture.format(); @@ -174,8 +188,6 @@ fn prepare_screen_capture_buffers( main_bytes_per_row: bytes_per_row, main_padded_bytes_per_row: padded_bytes_per_row, }); - - println!("Buffers Created!"); } } } @@ -219,7 +231,6 @@ impl ViewNode for ScreenCaptureNode { }, view_query.1.main_texture().size(), ); - println!("Saved to buffer!"); Ok(()) } } @@ -255,7 +266,7 @@ fn save_buffer_to_file( let path = format!( "{}img_{:0.5}.png", - screen_capture.to_directory, screen_capture.number_of_frames + screen_capture.to_directory, screen_capture.frames ); save_buffer::>(&main_image_values, &buffers.main_buffer_extent, &path); From fffcb38ec6dae8bb1249a2124c1fa6b5f7005f21 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Fri, 23 Feb 2024 20:52:59 -0500 Subject: [PATCH 03/13] Emit build dependency versions (#52) --- ci.sh | 8 +++++++- studio/src/screenshot.rs | 4 +--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ci.sh b/ci.sh index c4acb51..bd8c910 100755 --- a/ci.sh +++ b/ci.sh @@ -2,8 +2,14 @@ set -euxo pipefail -# Install dependencies +# Install build dependencies rustup target add wasm32-unknown-unknown + +# Emit versions +rustup show +npm version + +# Install project dependencies npm ci # Build projects diff --git a/studio/src/screenshot.rs b/studio/src/screenshot.rs index f773d13..832db0c 100644 --- a/studio/src/screenshot.rs +++ b/studio/src/screenshot.rs @@ -123,9 +123,7 @@ impl ScreenCapture { } } -fn update_screen_capture_on_extract_step( - mut screen_captures: Query<&mut ScreenCapture>, -) { +fn update_screen_capture_on_extract_step(mut screen_captures: Query<&mut ScreenCapture>) { for mut screen_capture in screen_captures.iter_mut() { screen_capture.frames += 1; // if screen_capture.number_of_frames == 0 { From 6ca2a992e5509739e1d3e3cbb0c7e4318a1d604a Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Fri, 23 Feb 2024 21:05:32 -0500 Subject: [PATCH 04/13] Storyteller.ai API integration (#49) This PR integrates asset retrieval from the Storyteller.ai back-end API, and begins implementing long-term scene saving and storage. ### Media retrieval Instead of fetching raw asset URLs, going forward, media files from remote sources (e.g., in URL parameters) should be specified with a path like the following: ``` remote://. ``` where * `token` is a media token (e.g., "m_70b77neq9jsgmy5v31mekzchcbd223") * `filetype` is a file extension appropriate for the type of file being fetched (e.g., "gltf") The `remote` protocol will be recognized by a [custom asset reader](https://github.com/storytold/storyteller-bevy/blob/70726db111f6ccafd47feb055c5546540fef1786/studio/src/remote/reader.rs) which will retrieve the file by calling a Storyteller API endpoint. ### Scene storage Additionally, this PR begins laying the groundwork for storing/retrieving Bevy scenes to/from the backend instead of solely in-memory. This work is still incomplete -- as of this PR, a button has been added to the web UI allowing the user to download the scene file locally for testing/debugging purposes. ### Test URL Media retrieval from the backend can be tested by [visiting this URL](https://deploy-preview-49--storyteller-studio.netlify.app/?mode=viewer&mixamo=remote://m_70b77neq9jsgmy5v31mekzchcbd223.gltf) in Chrome with the `--disable-web-security` flag (to bypass CORS errors) --- Cargo.lock | 399 +++++++++++++++++++- studio-frontend/src/app/app.element.ts | 33 +- studio-frontend/src/app/button.element.scss | 9 +- studio-frontend/src/app/icon.element.ts | 28 +- studio/Cargo.toml | 14 +- studio/src/lib.rs | 3 + studio/src/persistance/mod.rs | 68 ++++ studio/src/remote/mod.rs | 22 ++ studio/src/remote/reader.rs | 114 ++++++ studio/src/remote/response.rs | 107 ++++++ 10 files changed, 770 insertions(+), 27 deletions(-) create mode 100644 studio/src/remote/mod.rs create mode 100644 studio/src/remote/reader.rs create mode 100644 studio/src/remote/response.rs diff --git a/Cargo.lock b/Cargo.lock index 66bf9a1..c46c87c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2063,7 +2063,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2", + "socket2 0.4.9", "winapi", ] @@ -2277,6 +2277,16 @@ dependencies = [ "serde", ] +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "error-code" version = "2.3.1" @@ -2783,6 +2793,25 @@ dependencies = [ "svg_fmt", ] +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.0.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.3.1" @@ -2867,6 +2896,66 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "idna" version = "0.4.0" @@ -2955,6 +3044,12 @@ dependencies = [ "mach2", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "isahc" version = "1.7.2" @@ -3219,6 +3314,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "lock_api" version = "0.4.10" @@ -3420,6 +3521,24 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk" version = "0.7.0" @@ -3731,6 +3850,32 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.4.0", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "openssl-probe" version = "0.1.5" @@ -3739,9 +3884,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.99" +version = "0.9.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" dependencies = [ "cc", "libc", @@ -3755,7 +3900,7 @@ version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8378ac0dfbd4e7895f2d2c1f1345cab3836910baf3a300b000d04250f0c8428f" dependencies = [ - "redox_syscall", + "redox_syscall 0.3.5", ] [[package]] @@ -3797,7 +3942,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", "windows-targets 0.48.5", ] @@ -4097,6 +4242,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.9.5" @@ -4147,6 +4301,48 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" +[[package]] +name = "reqwest" +version = "0.11.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" +dependencies = [ + "base64 0.21.4", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "winreg", +] + [[package]] name = "robust" version = "1.1.0" @@ -4196,6 +4392,28 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.4", +] + [[package]] name = "ruzstd" version = "0.4.0" @@ -4246,6 +4464,29 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys 0.8.4", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys 0.8.4", + "libc", +] + [[package]] name = "semver" version = "1.0.21" @@ -4294,6 +4535,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -4385,6 +4638,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "space_bevy_xpbd_plugin" version = "0.3.1" @@ -4553,6 +4816,7 @@ dependencies = [ "itertools 0.12.1", "js-sys", "parking_lot", + "reqwest", "serde", "serde-wasm-bindgen", "serde_json", @@ -4601,6 +4865,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "sysinfo" version = "0.29.10" @@ -4615,6 +4885,27 @@ dependencies = [ "winapi", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys 0.8.4", + "libc", +] + [[package]] name = "taffy" version = "0.3.13" @@ -4633,6 +4924,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand 2.0.1", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "termcolor" version = "1.3.0" @@ -4718,6 +5022,45 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2 0.5.4", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml_datetime" version = "0.6.5" @@ -4746,6 +5089,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.37" @@ -4830,6 +5179,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "ttf-parser" version = "0.19.2" @@ -4958,6 +5313,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -5030,6 +5394,19 @@ version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +[[package]] +name = "wasm-streams" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wayland-scanner" version = "0.29.5" @@ -5519,7 +5896,7 @@ dependencies = [ "orbclient", "percent-encoding", "raw-window-handle", - "redox_syscall", + "redox_syscall 0.3.5", "wasm-bindgen", "wayland-scanner", "web-sys", @@ -5536,6 +5913,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "wyz" version = "0.2.0" diff --git a/studio-frontend/src/app/app.element.ts b/studio-frontend/src/app/app.element.ts index 2bc2427..5b2158f 100644 --- a/studio-frontend/src/app/app.element.ts +++ b/studio-frontend/src/app/app.element.ts @@ -5,6 +5,7 @@ import { type EntityMultiSpawnEvent, type EntitySelectEvent, type EntitySpawnEvent, + type SceneSavedEvent, type SceneStateEvent, TransformSpace, TransformType, @@ -150,6 +151,22 @@ export class AppElement extends LitElement { this.#updateHierarchy(); } + @on("window:scene-saved") + onSceneSaved({ detail: scene }: SceneSavedEvent): void { + const fileBlob = new Blob([scene], { type: "text/ron" }); + const url = URL.createObjectURL(fileBlob); + + const anchor = document.createElement("a"); + anchor.href = url; + anchor.download = "scene.scn.ron"; + anchor.click(); + + setTimeout(() => { + URL.revokeObjectURL(url); + anchor.remove(); + }); + } + toggleHelp(): void { this.showHelp = !this.showHelp; } @@ -211,6 +228,7 @@ export class AppElement extends LitElement { class="app-root" ${ref(this.#canvasProvider as any)} > + ${this.bvhPath ? html` `} + + ${this.mode === StudioMode.Editor ? html` + studio.saveScene()} + > + Save + + ` : nothing} Help @@ -245,6 +272,7 @@ export class AppElement extends LitElement { ${this.mode === StudioMode.Editor ? html` + +
${this.sceneObjects.map(obj => html` ` : nothing} + ${this.mode === StudioMode.Editor ? html` ` : nothing} + ${this.showHelp ? html` ` : nothing} diff --git a/studio-frontend/src/app/button.element.scss b/studio-frontend/src/app/button.element.scss index 085f9a9..2939af9 100644 --- a/studio-frontend/src/app/button.element.scss +++ b/studio-frontend/src/app/button.element.scss @@ -1,8 +1,8 @@ :host { display: inline-flex; align-items: center; - gap: 0.5rem; - padding: 10px 20px; + gap: 0.75rem; + padding: 0.5rem 1rem; border-radius: 0.5rem; font: { @@ -10,14 +10,14 @@ size: 15px; weight: 500; } - line-height: 1; + line-height: 1.5; pointer-events: auto; cursor: pointer; user-select: none; background: #0006; - color: #FFF; + color: #FFFC; backdrop-filter: blur(16px); transition: { property: background, color; @@ -28,6 +28,7 @@ :host(:hover) { background: #0008; + color: #FFFF; } .icon { diff --git a/studio-frontend/src/app/icon.element.ts b/studio-frontend/src/app/icon.element.ts index 668a344..5921924 100644 --- a/studio-frontend/src/app/icon.element.ts +++ b/studio-frontend/src/app/icon.element.ts @@ -6,19 +6,21 @@ import { unsafeSVG } from "lit/directives/unsafe-svg.js"; import farCrosshairs from "@fortawesome/fontawesome-pro/svgs/regular/crosshairs.svg?raw"; import farVideo from "@fortawesome/fontawesome-pro/svgs/regular/video.svg?raw"; -import fasCircleInfo from "@fortawesome/fontawesome-pro/svgs/regular/circle-info.svg?raw"; +import fasCircleQuestion from "@fortawesome/fontawesome-pro/svgs/solid/circle-question.svg?raw"; import fasKey from "@fortawesome/fontawesome-pro/svgs/solid/key.svg?raw"; -import fasCube from "@fortawesome/fontawesome-pro/svgs/regular/cube.svg?raw"; -import fasGlobe from "@fortawesome/fontawesome-pro/svgs/regular/globe.svg?raw"; -import fasUpDownLeftRight from "@fortawesome/fontawesome-pro/svgs/regular/arrows-up-down-left-right.svg?raw"; +import farCube from "@fortawesome/fontawesome-pro/svgs/regular/cube.svg?raw"; +import farGlobe from "@fortawesome/fontawesome-pro/svgs/regular/globe.svg?raw"; +import farUpDownLeftRight from "@fortawesome/fontawesome-pro/svgs/regular/arrows-up-down-left-right.svg?raw"; import fasPlay from "@fortawesome/fontawesome-pro/svgs/solid/play.svg?raw"; import fasFwdStep from "@fortawesome/fontawesome-pro/svgs/solid/forward-step.svg?raw"; import fasFwdFast from "@fortawesome/fontawesome-pro/svgs/solid/forward-fast.svg?raw"; import fasBwdStep from "@fortawesome/fontawesome-pro/svgs/solid/backward-step.svg?raw"; import fasBwdFast from "@fortawesome/fontawesome-pro/svgs/solid/backward-fast.svg?raw"; -import fasRotate from "@fortawesome/fontawesome-pro/svgs/regular/arrows-rotate.svg?raw"; -import fasScale from "@fortawesome/fontawesome-pro/svgs/regular/arrow-up-right-and-arrow-down-left-from-center.svg?raw"; +import fasQuestion from "@fortawesome/fontawesome-pro/svgs/solid/question.svg?raw"; +import farRotate from "@fortawesome/fontawesome-pro/svgs/regular/arrows-rotate.svg?raw"; +import farScale from "@fortawesome/fontawesome-pro/svgs/regular/arrow-up-right-and-arrow-down-left-from-center.svg?raw"; import fasCaretRight from "@fortawesome/fontawesome-pro/svgs/solid/caret-right.svg?raw"; +import fasFloppyDisk from "@fortawesome/fontawesome-pro/svgs/solid/floppy-disk.svg?raw"; import styles from "./icon.element.scss?inline"; @@ -47,18 +49,20 @@ function renderSvg(iconId: string) { const svgSrc = match (iconId, { "bwd-fast": () => fasBwdFast, "bwd-step": () => fasBwdStep, - "circle-info": () => fasCircleInfo, + "circle-question": () => fasCircleQuestion, "caret-right": () => fasCaretRight, "crosshairs": () => farCrosshairs, - "cube": () => fasCube, + "cube": () => farCube, + "floppy-disk": () => fasFloppyDisk, "fwd-fast": () => fasFwdFast, "fwd-step": () => fasFwdStep, "key": () => fasKey, - "globe": () => fasGlobe, + "globe": () => farGlobe, "play": () => fasPlay, - "rotate": () => fasRotate, - "scale": () => fasScale, - "up-down-left-right": () => fasUpDownLeftRight, + "question": () => fasQuestion, + "rotate": () => farRotate, + "scale": () => farScale, + "up-down-left-right": () => farUpDownLeftRight, "video": () => farVideo, _: () => null, }); diff --git a/studio/Cargo.toml b/studio/Cargo.toml index 62dd252..3daa843 100644 --- a/studio/Cargo.toml +++ b/studio/Cargo.toml @@ -27,9 +27,9 @@ console_error_panic_hook = { version = "0.1.7", optional = true } itertools = "0.12.1" js-sys = { version = "0.3.65", optional = true } parking_lot = "0.12.1" -serde = { version = "1.0.192", optional = true } +serde = "1.0.192" serde-wasm-bindgen = { version = "0.6.1", optional = true } -serde_json = { version = "1.0.108", optional = true } +serde_json = "1.0.108" studio-bvh = { path = "../studio-bvh" } wasm-bindgen = "0.2.84" web-sys = { version = "0.3.65", optional = true, features = [ @@ -49,12 +49,18 @@ bytemuck = "1.14.1" space_editor = {git = "https://github.com/rewin123/space_editor", rev = "ce83f86dc902787ab16213f3209276a784654df6"} anyhow.workspace = true +[dependencies.reqwest] +version = "0.11.24" +features = [ + "default", + "json", + "stream", +] + [features] wasm = [ "dep:console_error_panic_hook", "dep:js-sys", - "dep:serde", - "dep:serde_json", "dep:serde-wasm-bindgen", "dep:web-sys", "bevy_rapier3d/wasm-bindgen", diff --git a/studio/src/lib.rs b/studio/src/lib.rs index a449892..3641593 100644 --- a/studio/src/lib.rs +++ b/studio/src/lib.rs @@ -28,6 +28,7 @@ mod interaction; pub mod math; mod mixamo; mod persistance; +mod remote; mod scene; pub mod screenshot; mod skybox; @@ -46,6 +47,7 @@ pub use crate::{ math::InterpolationPlugin, mixamo::{MixamoImportEvent, MixamoPlugin}, persistance::PersistancePlugin, + remote::RemoteAssetPlugin, scene::{LoadSceneEvent, ScenePlugin}, skybox::{SkyboxId, SkyboxPlugin}, ui::UiLayerPlugin, @@ -251,6 +253,7 @@ pub fn start_internal( #[cfg(feature = "wasm")] viewport::wasm::ViewportPlugin, WebAssetPlugin, + RemoteAssetPlugin, DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { resolution: viewport_size.into(), diff --git a/studio/src/persistance/mod.rs b/studio/src/persistance/mod.rs index 6f5842c..d1ea77e 100644 --- a/studio/src/persistance/mod.rs +++ b/studio/src/persistance/mod.rs @@ -10,6 +10,13 @@ impl Plugin for PersistancePlugin { EditorTabName::Other("Persistance".to_string()), DebugPersistanceTab::default(), ); + + #[cfg(feature = "wasm")] + app.add_systems(Update, wasm::forward_save_scene_events) + .add_systems( + OnEnter(SaveState::Idle), + wasm::on_scene_saved.map(bevy::utils::warn), + ); } } @@ -43,3 +50,64 @@ impl EditorTab for DebugPersistanceTab { "Persistance".into() } } + +#[cfg(feature = "wasm")] +mod wasm { + use bevy::{prelude::*, window::PrimaryWindow}; + use space_editor::prelude::{EditorEvent, EditorPrefabPath, PrefabMemoryCache}; + use wasm_bindgen::prelude::*; + + use crate::wasm::{self, StaticBuffer, WasmMessageBuffer}; + + static SAVE_SCENE: WasmMessageBuffer<()> = WasmMessageBuffer::new(); + + #[wasm_bindgen(js_name = saveScene)] + pub fn save_scene() { + SAVE_SCENE.write_message(()); + } + + pub(super) fn forward_save_scene_events(mut ew_editor_events: EventWriter) { + if SAVE_SCENE.take_message().is_some() { + ew_editor_events.send(EditorEvent::Save(EditorPrefabPath::MemoryCahce)); + } + } + + #[wasm_bindgen(typescript_custom_section)] + const SCENE_SAVED_EVENT: &str = r#" +export interface SceneSavedEvent extends CustomEvent { + type: "scene-saved"; + detail: string; +} + +declare global { + export interface GlobalEventHandlersEventMap { + "scene-saved": SceneSavedEvent; + } +} + "#; + + pub(super) fn on_scene_saved( + r_scene_cache: Res, + r_type_registry: Res, + ra_scenes: Res>, + q_window: Query<&Window, With>, + ) -> Result<(), String> { + let handle = r_scene_cache + .scene + .as_ref() + .ok_or_else(|| "Scene cache is empty!".to_string())?; + + let serialized = match ra_scenes.get(handle) { + Some(scene) => scene + .serialize_ron(&r_type_registry) + .map_err(|err| format!("{err}")), + None => Err("No scene found for cached handle!".into()), + }?; + + let Ok(window) = q_window.get_single() else { + return Ok(()); + }; + + wasm::dispatch_to_js(window, "scene-saved", &serialized) + } +} diff --git a/studio/src/remote/mod.rs b/studio/src/remote/mod.rs new file mode 100644 index 0000000..99ce463 --- /dev/null +++ b/studio/src/remote/mod.rs @@ -0,0 +1,22 @@ +use bevy::{ + asset::io::{AssetSource, AssetSourceId}, + prelude::*, +}; + +use self::reader::RemoteAssetReader; + +mod reader; +mod response; + +pub struct RemoteAssetPlugin; + +impl Plugin for RemoteAssetPlugin { + fn build(&self, app: &mut App) { + app.register_asset_source( + AssetSourceId::Name("remote".into()), + AssetSource::build() + .with_reader(|| Box::new(RemoteAssetReader)) + .with_writer(|| None), + ); + } +} diff --git a/studio/src/remote/reader.rs b/studio/src/remote/reader.rs new file mode 100644 index 0000000..1753860 --- /dev/null +++ b/studio/src/remote/reader.rs @@ -0,0 +1,114 @@ +use std::{io::ErrorKind, path::Path}; + +use bevy::{ + asset::io::{AssetReader, AssetReaderError, PathStream, Reader, VecReader}, + utils::BoxedFuture, +}; +use reqwest::StatusCode; + +use super::response::GetMediaFileSuccessResponse; + +pub struct RemoteAssetReader; + +impl RemoteAssetReader { + const API_BASE_URL: &'static str = "https://api.fakeyou.com/v1/media_files/file"; + const BUCKET_BASE_URL: &'static str = "https://storage.googleapis.com/vocodes-public"; +} + +impl AssetReader for RemoteAssetReader { + fn read<'a>( + &'a self, + path: &'a Path, + ) -> BoxedFuture<'a, Result>, AssetReaderError>> { + Box::pin(async move { + let token = path + .file_stem() + .ok_or_else(|| { + AssetReaderError::Io(std::io::Error::new( + ErrorKind::Other, + format!("Failed to parse token from '{path:?}'"), + )) + })? + .to_str() + .unwrap(); + + let response = reqwest::get(format!("{}/{token}", &Self::API_BASE_URL)) + .await + .map_err(IntoError::::into)?; + + let response = match response.status() { + StatusCode::OK => response + .json::() + .await + .map_err(IntoError::::into), + other => Err(AssetReaderError::Io(std::io::Error::new( + ErrorKind::Other, + format!("Status Code from endpoint: {other}"), + ))), + }?; + + let url = format!( + "{}{}", + &Self::BUCKET_BASE_URL, + &response.media_file.public_bucket_path + ); + + let response = reqwest::get(url) + .await + .map_err(IntoError::::into)?; + + let bytes = match response.status() { + // TODO: This is not thread-safe, but some variation of this + // would be better than the current solution once Bevy + // WASM becomes multi-threaded: + // StatusCode::OK => Ok(response.bytes_stream().map(|result| { + // result.map_err(|err| std::io::Error::new(ErrorKind::Other, format!("{err}"))) + // })), + StatusCode::OK => Ok(response + .bytes() + .await + .map_err(IntoError::::into)? + .into_iter() + .collect::>()), + other => Err(AssetReaderError::Io(std::io::Error::new( + ErrorKind::Other, + format!("Status Code from bucket URL: {other}"), + ))), + }?; + + let reader: Box = Box::new(VecReader::new(bytes)); + Ok(reader) + }) + } + + fn read_meta<'a>( + &'a self, + path: &'a Path, + ) -> BoxedFuture<'a, Result>, AssetReaderError>> { + // TODO: Do we want to try to read .meta files? + Box::pin(async { Err(AssetReaderError::NotFound(path.into())) }) + } + + fn read_directory<'a>( + &'a self, + path: &'a Path, + ) -> BoxedFuture<'a, Result, AssetReaderError>> { + // We won't have to deal with directories + Box::pin(async { Err(AssetReaderError::NotFound(path.into())) }) + } + + fn is_directory<'a>(&'a self, _: &'a Path) -> BoxedFuture<'a, Result> { + // We won't have to deal with directories + Box::pin(async { Ok(false) }) + } +} + +trait IntoError { + fn into(self) -> Output; +} + +impl IntoError for reqwest::Error { + fn into(self) -> AssetReaderError { + AssetReaderError::Io(std::io::Error::new(ErrorKind::Other, format!("{self}"))) + } +} diff --git a/studio/src/remote/response.rs b/studio/src/remote/response.rs new file mode 100644 index 0000000..7225b9b --- /dev/null +++ b/studio/src/remote/response.rs @@ -0,0 +1,107 @@ +//! Response types copy/pasted straight from the backend source code. + +use serde::Deserialize; + +#[derive(Deserialize, Debug)] +pub struct GetMediaFileSuccessResponse { + pub success: bool, + pub media_file: MediaFileInfo, +} + +#[derive(Deserialize, Debug)] +pub struct MediaFileInfo { + pub token: String, + + /// Type of media will dictate which fields are populated and what + /// the frontend should display (eg. video player vs audio player). + pub media_type: String, + + /// If the file was generated as part of a batch, this is the token for the batch. + pub maybe_batch_token: Option, + + /// URL to the media file + pub public_bucket_path: String, + + //// Provenance Data + //pub origin_product: MediaFileOriginProductCategory, + //pub origin_category: MediaFileOriginCategory, + //pub maybe_origin_model_type: Option, + //pub maybe_origin_model_token: Option, + //pub maybe_origin_filename: Option, + /// Possible model info (if generated by inference) + pub maybe_model_weight_info: Option, + + /// User info + pub maybe_creator_user: Option, + + pub creator_set_visibility: String, + + /// Text transcripts for TTS, etc. + pub maybe_text_transcript: Option, + + /// We can simulate media files for "tts_results" records. + /// If this is set as true, this informs the frontend and API callers not to treat + /// the token as a media file and improperly assume it can be used with the rest of + /// the media file APIs. + pub is_emulated_media_file: bool, + + /// Statistics about the media file + pub stats: SimpleEntityStats, + + pub created_at: String, + pub updated_at: String, + //pub maybe_moderator_fields: Option, +} + +#[derive(Deserialize, Debug)] +pub struct GetMediaFileModelInfo { + pub weight_token: String, + pub weight_type: String, + pub weight_category: String, + pub title: String, + + /// Cover images are small descriptive images that can be set for any model. + /// If a cover image is set, this is the path to the asset. + pub maybe_cover_image_public_bucket_path: Option, + + /// NB: Technically this shouldn't be a nullable field, but since there are so many + /// joins we'll relax that this must exist (for now). + pub maybe_weight_creator: Option, +} + +#[derive(Deserialize, Debug)] +pub struct UserDetailsLight { + /// The token for the user + pub user_token: String, + + /// The unique username someone logs in with + /// As of 2023-08-23, this is always lowercase + pub username: String, + + /// As of 2023-08-23, this is the username with capitalization + /// (In the future, a display name can be customized by the user.) + pub display_name: String, + + /// Email hash for Gravatar + /// Always set for now since login is email/username+password. + /// In the future this will need to become an optional *OR* be filled with a bogus hash. + pub gravatar_hash: String, + + /// For users without a gravatar, we show one of our own avatars. + pub default_avatar: DefaultAvatarInfo, + // In the future, we'll also support user-uploaded avatars that we store on our servers. +} + +#[derive(Deserialize, Debug)] +pub struct DefaultAvatarInfo { + pub image_index: u8, + pub color_index: u8, +} + +#[derive(Deserialize, Debug)] +pub struct SimpleEntityStats { + /// Number of positive ratings (or "likes") for this item + pub positive_rating_count: u32, + /// Number of bookmarks for this item + pub bookmark_count: u32, +} From 7b06d48c5d64a90c3a6211d10f70fc4846676c6e Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Fri, 23 Feb 2024 22:04:06 -0500 Subject: [PATCH 05/13] Scene storage backend integration (#51) This PR adds Storyteller.ai API integration for saving and loading Storyteller Studio scenes to/from the backend. ### Known issues * The skybox is not currently stored in the serialized scene format --- .github/workflows/pr-validation.yml | 8 ++- ci.sh | 2 +- package-lock.json | 11 +++- package.json | 4 +- rust-toolchain.toml | 2 +- studio-frontend/src/app/app.element.ts | 39 ++++++++---- studio-web/src/index.ts | 2 + studio-web/src/lib/editor.element.ts | 28 +++++++++ studio/src/lib.rs | 87 +++++++++++++++++--------- studio/src/main.rs | 12 ++-- studio/src/path.rs | 40 ++++++++++++ studio/src/remote/reader.rs | 6 +- studio/src/scene.rs | 64 ++++++++++++++++--- tsconfig.base.json | 1 + 14 files changed, 244 insertions(+), 62 deletions(-) create mode 100644 studio-web/src/lib/editor.element.ts create mode 100644 studio/src/path.rs diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index b23ccaa..cbb9e65 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -15,7 +15,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@1.76.0 + with: + components: rustfmt - name: Check Rust formatting run: cargo fmt --all -- --check @@ -35,7 +37,9 @@ jobs: ~/.cargo/git/db/ target/ key: ${{ runner.os }}-cargo-lint-and-test-${{ hashFiles('**/Cargo.toml') }} - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@1.76 + with: + components: clippy - name: Install Linux dependencies run: | sudo apt-get update diff --git a/ci.sh b/ci.sh index bd8c910..5c97c09 100755 --- a/ci.sh +++ b/ci.sh @@ -6,7 +6,7 @@ set -euxo pipefail rustup target add wasm32-unknown-unknown # Emit versions -rustup show +rustup show active-toolchain npm version # Install project dependencies diff --git a/package-lock.json b/package-lock.json index 964117b..9d13de8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,8 @@ "lodash": "^4.17.21", "react": "18.2.0", "react-dom": "18.2.0", - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "uuid": "^9.0.1" }, "devDependencies": { "@nx/js": "16.9.1", @@ -29,6 +30,7 @@ "@types/node": "18.14.2", "@types/react": "18.2.14", "@types/react-dom": "18.2.6", + "@types/uuid": "^9.0.8", "@types/which": "^3.0.2", "@vitejs/plugin-react": "~4.0.0", "@vitest/coverage-c8": "~0.32.0", @@ -4410,6 +4412,12 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.4.tgz", "integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==" }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true + }, "node_modules/@types/which": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.2.tgz", @@ -10194,7 +10202,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" diff --git a/package.json b/package.json index b1c0857..65ddb8a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@types/node": "18.14.2", "@types/react": "18.2.14", "@types/react-dom": "18.2.6", + "@types/uuid": "^9.0.8", "@types/which": "^3.0.2", "@vitejs/plugin-react": "~4.0.0", "@vitest/coverage-c8": "~0.32.0", @@ -45,6 +46,7 @@ "lodash": "^4.17.21", "react": "18.2.0", "react-dom": "18.2.0", - "tslib": "^2.3.0" + "tslib": "^2.3.0", + "uuid": "^9.0.1" } } diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 292fe49..624eb0e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "stable" +channel = "1.76.0" diff --git a/studio-frontend/src/app/app.element.ts b/studio-frontend/src/app/app.element.ts index 5b2158f..f2ad003 100644 --- a/studio-frontend/src/app/app.element.ts +++ b/studio-frontend/src/app/app.element.ts @@ -18,10 +18,12 @@ import { LitElement, html, nothing } from "lit"; import { customElement, state } from "lit/decorators.js"; import { classMap } from "lit-html/directives/class-map.js"; import { Ref, createRef, ref } from "lit-html/directives/ref.js"; +import { v4 as uuid } from "uuid"; import "@storyteller/studio-web/canvas-provider"; import "@storyteller/studio-web/viewer"; import "@storyteller/studio-web/bvh-viewer"; +import "@storyteller/studio-web/editor"; import "@storyteller/studio-web/mixamo-viewer"; import "./anim-editor.element"; import "./button.element"; @@ -50,6 +52,7 @@ export class AppElement extends LitElement { @state() bvhPath?: string; @state() mixamoPath?: string; + @state() scenePath?: string; @state() mode?: StudioMode; #sceneObjects: studio.SceneObject[] = []; @@ -74,6 +77,9 @@ export class AppElement extends LitElement { if (params.has("mixamo")) this.mixamoPath = params.get("mixamo")!; + if (params.has("scene")) + this.scenePath = params.get("scene")!; + this.mode = match (params.get("mode"), { "studio": () => StudioMode.Editor, "viewer": () => StudioMode.Viewer, @@ -152,19 +158,25 @@ export class AppElement extends LitElement { } @on("window:scene-saved") - onSceneSaved({ detail: scene }: SceneSavedEvent): void { - const fileBlob = new Blob([scene], { type: "text/ron" }); - const url = URL.createObjectURL(fileBlob); + async onSceneSaved({ detail: scene }: SceneSavedEvent): Promise { + const file = new File([scene], "scene.scn.ron", { type: "text/ron" }); + const formData = new FormData(); - const anchor = document.createElement("a"); - anchor.href = url; - anchor.download = "scene.scn.ron"; - anchor.click(); + formData.append("uuid_idempotency_token", uuid()); + formData.append("file", file); - setTimeout(() => { - URL.revokeObjectURL(url); - anchor.remove(); - }); + try { + const response = await fetch("https://api.fakeyou.com/v1/engine/create_scene", { + method: "POST", + credentials: "include", + headers: { "Accept": "text/plain" }, + body: formData, + }); + console.log(response); + } + catch (err) { + console.error(err); + } } toggleHelp(): void { @@ -241,6 +253,11 @@ export class AppElement extends LitElement { skyboxId="test_scene" @scene-state=${this.onSceneStateChange} > + ` : this.scenePath ? html` + ` : html` ): void { + if (changes.has("scenePath") && !!this.scenePath) { + // TODO + } + } +} diff --git a/studio/src/lib.rs b/studio/src/lib.rs index 3641593..da30fb8 100644 --- a/studio/src/lib.rs +++ b/studio/src/lib.rs @@ -27,6 +27,7 @@ mod inspector; mod interaction; pub mod math; mod mixamo; +mod path; mod persistance; mod remote; mod scene; @@ -48,7 +49,7 @@ pub use crate::{ mixamo::{MixamoImportEvent, MixamoPlugin}, persistance::PersistancePlugin, remote::RemoteAssetPlugin, - scene::{LoadSceneEvent, ScenePlugin}, + scene::{LoadLibraryObjectEvent, LoadSceneEvent, ScenePlugin}, skybox::{SkyboxId, SkyboxPlugin}, ui::UiLayerPlugin, viewport::ViewportSize, @@ -120,8 +121,10 @@ pub fn start_viewer( viewport_size: ViewportSize, ) { start_internal( - object_id, - skybox_id, + InitSeed::FromLibrary { + object_id: object_id.into(), + skybox_id: skybox_id.into(), + }, canvas_selector, canvas_alt, viewport_size, @@ -132,15 +135,13 @@ pub fn start_viewer( #[cfg_attr(feature = "wasm", wasm_bindgen(js_name = startEditor))] pub fn start_editor( - object_id: &str, - skybox_id: &str, + scene_id: &str, canvas_selector: &str, canvas_alt: &str, viewport_size: ViewportSize, ) { start_internal( - object_id, - skybox_id, + InitSeed::FromScene(scene_id.into()), canvas_selector, canvas_alt, viewport_size, @@ -158,8 +159,10 @@ pub fn start_bvh_viewer( viewport_size: ViewportSize, ) { let mut app = start_internal( - "Mannequin.gltf", - skybox_id, + InitSeed::FromLibrary { + object_id: "Mannequin.gltf".into(), + skybox_id: skybox_id.into(), + }, canvas_selector, canvas_alt, viewport_size, @@ -188,8 +191,10 @@ pub fn start_mixamo_viewer( viewport_size: ViewportSize, ) { let mut app = start_internal( - "Mannequin.gltf", - skybox_id, + InitSeed::FromLibrary { + object_id: "Mannequin.gltf".into(), + skybox_id: skybox_id.into(), + }, canvas_selector, canvas_alt, viewport_size, @@ -216,8 +221,10 @@ pub fn start( studio_mode: StudioMode, ) { start_internal( - object_id, - skybox_id, + InitSeed::FromLibrary { + object_id: object_id.into(), + skybox_id: skybox_id.into(), + }, canvas_selector, canvas_alt, viewport_size, @@ -226,13 +233,24 @@ pub fn start( .run(); } -// TODO: These `start_` functiions should be refactored to better support the -// needs of the "reaodnly viewer" vs "full studio editor" use cases. See -// notes in `studio-web/src/lib/viewer.element.ts` for more info. +pub enum InitSeed { + /// Initialize the application from assets in the "bundled" asset library. + FromLibrary { + /// A filename, including the extension, that can be found under + /// `studio/assets/gltf` (e.g., "Mannequin.gltf") + object_id: String, + /// A skybox name that corresponds to a matching set of assets under + /// `studio/assets/skyboxes`, _not_ including file extensions or + /// "diffuse"/"specular" qualifiers (e.g., "gum_trees_4k") + skybox_id: String, + }, + /// Initialize the application by loading a previously saved `*.scn.ron` + /// scene file. + FromScene(String), +} pub fn start_internal( - object_id: &str, - skybox_id: &str, + seed: InitSeed, canvas_selector: &str, canvas_alt: &str, viewport_size: ViewportSize, @@ -241,9 +259,6 @@ pub fn start_internal( #[cfg(feature = "wasm")] console_error_panic_hook::set_once(); - let object_id = object_id.to_string(); - let skybox_id = skybox_id.to_string(); - let mut app = App::new(); app.insert_resource(HeadlessMode::None); @@ -274,13 +289,25 @@ pub fn start_internal( app.auto_reflected_undo::(); } - app.add_systems( - Startup, - move |mut cmd: Commands, mut ew: EventWriter| { - cmd.insert_resource(SkyboxId(skybox_id.clone())); - ew.send(LoadSceneEvent(object_id.clone())); - }, - ); + match seed { + InitSeed::FromLibrary { + object_id, + skybox_id, + } => { + app.add_systems( + Startup, + move |mut cmd: Commands, mut ew: EventWriter| { + cmd.insert_resource(SkyboxId(skybox_id.clone())); + ew.send(LoadLibraryObjectEvent(object_id.clone())); + }, + ); + } + InitSeed::FromScene(scene) => { + app.add_systems(Startup, move |mut ew: EventWriter| { + ew.send(LoadSceneEvent(scene.clone())); + }); + } + } #[cfg(feature = "wasm")] wasm::initialize(); @@ -331,10 +358,10 @@ pub fn start_headless( Startup, move |mut cmd: Commands, asset_server: Res, - mut ew: EventWriter| { + mut ew: EventWriter| { cmd.insert_resource(SkyboxId(skybox.clone())); cmd.insert_resource(TestBvh(asset_server.load(bvh_dir.clone()))); - ew.send(LoadSceneEvent("Mannequin.gltf".to_string())); + ew.send(LoadLibraryObjectEvent("Mannequin.gltf".to_string())); }, ); diff --git a/studio/src/main.rs b/studio/src/main.rs index 4007aa7..8ef44f3 100644 --- a/studio/src/main.rs +++ b/studio/src/main.rs @@ -1,6 +1,6 @@ use bevy::{app::Update, window::close_on_esc}; use clap::Parser; -use studio::{screenshot::ScreenShotPlugin, StudioMode, ViewportSize}; +use studio::{screenshot::ScreenShotPlugin, InitSeed, StudioMode, ViewportSize}; #[derive(Parser)] #[command(name = "StorytellerStudio")] @@ -16,13 +16,15 @@ struct StudioArgs { fn main() { let args = StudioArgs::parse(); - let model_path = args.model.unwrap_or("Mannequin.gltf".to_string()); - let skybox_path = args.skybox.unwrap_or("gum_trees_4k".to_string()); + let object_id = args.model.unwrap_or("Mannequin.gltf".to_string()); + let skybox_id = args.skybox.unwrap_or("gum_trees_4k".to_string()); // Edit the arguments here to change the default startup scene or skybox let mut app = studio::start_internal( - model_path.as_str(), - skybox_path.as_str(), + InitSeed::FromLibrary { + object_id, + skybox_id, + }, "", // ignored for non-WASM "Storyteller Studio", ViewportSize::default(), diff --git a/studio/src/path.rs b/studio/src/path.rs new file mode 100644 index 0000000..b266cbb --- /dev/null +++ b/studio/src/path.rs @@ -0,0 +1,40 @@ +use std::{ffi::OsStr, path::Path}; + +pub trait PathExtras { + /// See [std::path::Path::file_prefix] + #[must_use] + fn ext_file_prefix(&self) -> Option<&OsStr>; +} + +impl PathExtras for Path { + fn ext_file_prefix(&self) -> Option<&OsStr> { + self.file_name() + .map(split_file_at_dot) + .map(|(before, _after)| before) + } +} + +/// Note: Copied from private fn `std::path::split_file_at_dot` +fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) { + let slice = file.as_encoded_bytes(); + if slice == b".." { + return (file, None); + } + + // The unsafety here stems from converting between &OsStr and &[u8] + // and back. This is safe to do because (1) we only look at ASCII + // contents of the encoding and (2) new &OsStr values are produced + // only from ASCII-bounded slices of existing &OsStr values. + let i = match slice[1..].iter().position(|b| *b == b'.') { + Some(i) => i + 1, + None => return (file, None), + }; + let before = &slice[..i]; + let after = &slice[i + 1..]; + unsafe { + ( + OsStr::from_encoded_bytes_unchecked(before), + Some(OsStr::from_encoded_bytes_unchecked(after)), + ) + } +} diff --git a/studio/src/remote/reader.rs b/studio/src/remote/reader.rs index 1753860..f45d933 100644 --- a/studio/src/remote/reader.rs +++ b/studio/src/remote/reader.rs @@ -2,11 +2,13 @@ use std::{io::ErrorKind, path::Path}; use bevy::{ asset::io::{AssetReader, AssetReaderError, PathStream, Reader, VecReader}, + prelude::*, utils::BoxedFuture, }; use reqwest::StatusCode; use super::response::GetMediaFileSuccessResponse; +use crate::path::PathExtras; pub struct RemoteAssetReader; @@ -22,7 +24,7 @@ impl AssetReader for RemoteAssetReader { ) -> BoxedFuture<'a, Result>, AssetReaderError>> { Box::pin(async move { let token = path - .file_stem() + .ext_file_prefix() .ok_or_else(|| { AssetReaderError::Io(std::io::Error::new( ErrorKind::Other, @@ -32,6 +34,8 @@ impl AssetReader for RemoteAssetReader { .to_str() .unwrap(); + info!("Loading asset from media token: '{token}'"); + let response = reqwest::get(format!("{}/{token}", &Self::API_BASE_URL)) .await .map_err(IntoError::::into)?; diff --git a/studio/src/scene.rs b/studio/src/scene.rs index ed32e68..1faaa8c 100644 --- a/studio/src/scene.rs +++ b/studio/src/scene.rs @@ -13,7 +13,10 @@ use bevy::{ scene::InstanceId, }; -use space_editor::{prelude::PrefabMarker, space_prefab::component::SceneAutoChild}; +use space_editor::{ + prelude::{EditorEvent, EditorPrefabPath, PrefabMarker}, + space_prefab::component::SceneAutoChild, +}; #[cfg(feature = "wasm")] use wasm_bindgen::prelude::wasm_bindgen; use wgpu::{TextureDescriptor, TextureUsages}; @@ -37,6 +40,7 @@ impl Plugin for ScenePlugin { app.insert_resource(ClearColor(Color::hsl(0.0, 0.0, 0.25))) .insert_resource(Msaa::Off) .add_state::() + .add_event::() .add_event::() .add_systems( Startup, @@ -45,7 +49,10 @@ impl Plugin for ScenePlugin { initialiaze_headless.run_if(is_headless), ), ) - .add_systems(Update, init_scene_loading.in_set(SceneSpawnerSystem)) + .add_systems( + Update, + (init_object_loading, init_scene_loading).in_set(SceneSpawnerSystem), + ) .add_systems( OnEnter(SceneState::Active), ( @@ -78,7 +85,7 @@ impl Plugin for ScenePlugin { app.add_systems( Update, ( - wasm::dispatch_scene_request, + wasm::dispatch_object_load_request, wasm::notify_state_changes .map(bevy::utils::error) .run_if(resource_changed::>()), @@ -172,6 +179,33 @@ fn auto_add_handle( } } +/// Request the application to load a `gltf`/`glb` scene from the "bundled" +/// asset library in `assets/gltf/`. Expects a filename including the extension. +/// +/// ```ignore +/// fn main() { +/// App::new() +/// .add_plugins(( +/// DefaultPlugins, +/// CommonPlugins, +/// )) +/// .add_systems(Startup, load_mannequin) +/// } +/// +/// fn load_mannequin(mut ew_load_object: EventWriter) { +/// ew_load_object.send(LoadLibraryObjectEvent("Mannequin.gltf".into())); +/// } +/// ``` +#[derive(Event, Deref)] +pub struct LoadLibraryObjectEvent(pub String); + +/// Request the application to load a previously saved `*.scn.ron` dynamic scene +/// file. +/// +/// Expects a full, resolvable path to the file (e.g. `scenes/my-scene.scn.ron` +/// for a local file saved under `studio/assets/scenes`, or +/// `remote://.scn.ron` for a scene saved to the Storyteller.ai +/// backend). #[derive(Event, Deref)] pub struct LoadSceneEvent(pub String); @@ -270,9 +304,9 @@ fn initialiaze_headless( )); } -fn init_scene_loading(mut cmd: Commands, mut er: EventReader) { +fn init_object_loading(mut cmd: Commands, mut er: EventReader) { if let Some(id) = er.read().last() { - info!("Loading scene: {}", id.0); + info!("Loading library asset: {}", id.0); cmd.spawn(( SpatialBundle::default(), space_editor::prelude::GltfPrefab { @@ -285,6 +319,18 @@ fn init_scene_loading(mut cmd: Commands, mut er: EventReader) { } } +fn init_scene_loading( + mut er_load_scene: EventReader, + mut ew_editor: EventWriter, +) { + if let Some(scene_path) = er_load_scene.read().last() { + info!("Loading scene: {}", scene_path.0); + ew_editor.send(EditorEvent::Load(EditorPrefabPath::File( + scene_path.0.clone(), + ))); + } +} + #[derive(Component)] pub struct NoMeshElement; @@ -442,7 +488,7 @@ mod wasm { use bevy::{prelude::*, window::PrimaryWindow}; use wasm_bindgen::prelude::*; - use super::{LoadSceneEvent, SceneState}; + use super::{LoadLibraryObjectEvent, SceneState}; use crate::wasm::{self, StaticBuffer, WasmMessageBuffer}; static OBJECT_LOAD_REQUEST: WasmMessageBuffer = WasmMessageBuffer::new(); @@ -454,9 +500,11 @@ mod wasm { // FIXME: Is it an object or a scene? Inconsistent terminology is // unnecessarily confusing - pub(super) fn dispatch_scene_request(mut ew_load_scene: EventWriter) { + pub(super) fn dispatch_object_load_request( + mut ew_load_scene: EventWriter, + ) { if let Some(id) = OBJECT_LOAD_REQUEST.take_message() { - ew_load_scene.send(LoadSceneEvent(id)); + ew_load_scene.send(LoadLibraryObjectEvent(id)); } } diff --git a/tsconfig.base.json b/tsconfig.base.json index 34d4b4f..2d911b3 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -21,6 +21,7 @@ "@storyteller/studio-web/canvas-provider": ["studio-web/src/lib/canvas-provider.element.ts"], "@storyteller/studio-web/viewer": ["studio-web/src/lib/viewer.element.ts"], "@storyteller/studio-web/bvh-viewer": ["studio-web/src/lib/bvh-viewer.element.ts"], + "@storyteller/studio-web/editor": ["studio-web/src/lib/editor.element.ts"], "@storyteller/studio-web/mixamo-viewer": ["studio-web/src/lib/mixamo-viewer.element.ts"], "@storyteller/utility": ["utility/src/index.ts"] } From d51eec52c3c762b380203c456b49b9069d322856 Mon Sep 17 00:00:00 2001 From: Brooks Palin Date: Mon, 26 Feb 2024 15:13:07 -0700 Subject: [PATCH 06/13] Bootstrap Image Generator application (#53) This PR begins scaffolding the Stable Diffusion Turbo application (title TBD), which is a separate frontend for Storyteller Engine which focuses on image generation. ### Design Overview * The application renders a "split-screen" view, with Storyteller Studio on the left, and the Stable Diffusion Turbo output on the right * When changes are made in the Studio editor: - A screenshot is taken from the Bevy application - Screenshot is piped into Stable Diffusion Turbo model - Model output is rendered to the screen * This all happens in as close to real-time as possible ### Work completed in this PR * The `studio-frontend` project has been (somewhat crudely) refactored to split most of its components into reusable libraries - `studio-ui` is a use-case-agnostic design system library for core UI components. These are "dumb" components which are controlled via `@property` inputs and send `CustomEvent`s in response to user input. - `studio-frontend` is a collection of reusable Storyteller Studio widgets. These are "smart" components which depend on `@storyteller/studio` directly, manage their own state, and require very little configuration or styling. They are designed to be drop-in building blocks that can be reused between various frontends. * The new application has been bootstrapped as `image-generator-demo` - Currently, this simply grabs screenshots from the Bevy application and renders those screenshots on the right side of the split-screen view. A future PR will wire up to the Storyteller.ai backend to pipe these screenshots through Stable Diffusion Turbo, and render that model's output instead. ### Testing * Install dependencies as described in the repo's README * Run `npx nx serve image-generator-demo` * Open [localhost:4200](http://localhost:4200) in your browser - Use the camera controller in the left side of the view to manipulate the Bevy scene - Verify the right side of the view updates with a fresh screenshot at a rate of ~5 fps * Toggle the "Realtime Capture" checkbox - Verify the right side view no longer updates while the user is actively manipulating the editor - This should allow the app to run smoother on lower-spec hardware --------- Co-authored-by: Danny McGee --- .vscode/settings.json | 3 +- editor.ron | 2 +- image-generator-demo/.swcrc | 8 + image-generator-demo/index.html | 19 ++ image-generator-demo/project.json | 71 +++++ image-generator-demo/public/favicon.ico | Bin 0 -> 15086 bytes image-generator-demo/src/app/app.element.scss | 72 +++++ image-generator-demo/src/app/app.element.ts | 135 ++++++++++ image-generator-demo/src/main.ts | 1 + image-generator-demo/src/styles.scss | 10 + image-generator-demo/tsconfig.app.json | 15 ++ image-generator-demo/tsconfig.json | 34 +++ image-generator-demo/typings/scss.d.ts | 4 + image-generator-demo/typings/svg.d.ts | 4 + image-generator-demo/vite.config.ts | 29 +++ .../vite-plugins/multiple-assets/build.ts | 25 -- .../vite-plugins/multiple-assets/index.ts | 26 -- .../vite-plugins/multiple-assets/server.ts | 91 ------- react-frontend/vite.config.ts | 3 +- .../src/app/anim-editor.element.ts | 6 +- studio-frontend/src/app/app.element.scss | 24 -- studio-frontend/src/app/app.element.ts | 246 +++--------------- .../vite-plugins/multiple-assets/build.ts | 25 -- .../vite-plugins/multiple-assets/index.ts | 23 -- .../vite-plugins/multiple-assets/server.ts | 93 ------- studio-frontend/vite.config.ts | 3 +- studio-ui/README.md | 12 + studio-ui/package.json | 12 + studio-ui/project.json | 30 +++ studio-ui/src/index.ts | 4 + .../src/lib}/button.element.scss | 0 .../src/lib}/button.element.ts | 0 .../src/lib}/icon.element.scss | 0 .../app => studio-ui/src/lib}/icon.element.ts | 0 .../src/lib}/toolbar-group.element.scss | 0 .../src/lib}/toolbar.element.scss | 0 .../src/lib}/toolbar.element.ts | 0 .../src/lib}/tree.element.scss | 0 .../app => studio-ui/src/lib}/tree.element.ts | 2 +- studio-ui/tsconfig.json | 22 ++ studio-ui/tsconfig.lib.json | 10 + studio-ui/tsconfig.spec.json | 25 ++ studio-ui/vite.config.ts | 58 +++++ studio-web/src/index.ts | 3 + studio-web/src/lib/canvas-provider.element.ts | 31 ++- .../src/lib/scene-hierarchy.element.scss | 24 ++ studio-web/src/lib/scene-hierarchy.element.ts | 77 ++++++ studio-web/src/lib/studio-base.element.scss | 1 + studio-web/src/lib/studio-base.element.ts | 19 ++ .../src/lib}/transform-toolbar.element.scss | 0 .../src/lib}/transform-toolbar.element.ts | 42 ++- studio-web/src/lib/url-params.ts | 20 ++ studio/Cargo.toml | 1 + studio/project.json | 14 +- studio/scripts/build-web.mjs | 9 +- studio/src/camera_controller.rs | 35 +-- studio/src/change_tracking.rs | 77 ++++++ studio/src/lib.rs | 3 + studio/src/scene.rs | 25 +- studio/src/wasm/mod.rs | 4 + studio/src/wasm/screenshot.rs | 161 ++++++++++++ tsconfig.base.json | 7 + vite-multiple-assets/README.md | 5 + vite-multiple-assets/package.json | 6 + vite-multiple-assets/project.json | 8 + vite-multiple-assets/src/index.ts | 16 ++ vite-multiple-assets/src/lib/build.ts | 25 ++ vite-multiple-assets/src/lib/server.ts | 93 +++++++ vite-multiple-assets/tsconfig.json | 22 ++ vite-multiple-assets/tsconfig.lib.json | 10 + vite-multiple-assets/tsconfig.spec.json | 25 ++ 71 files changed, 1331 insertions(+), 579 deletions(-) create mode 100644 image-generator-demo/.swcrc create mode 100644 image-generator-demo/index.html create mode 100644 image-generator-demo/project.json create mode 100644 image-generator-demo/public/favicon.ico create mode 100644 image-generator-demo/src/app/app.element.scss create mode 100644 image-generator-demo/src/app/app.element.ts create mode 100644 image-generator-demo/src/main.ts create mode 100644 image-generator-demo/src/styles.scss create mode 100644 image-generator-demo/tsconfig.app.json create mode 100644 image-generator-demo/tsconfig.json create mode 100644 image-generator-demo/typings/scss.d.ts create mode 100644 image-generator-demo/typings/svg.d.ts create mode 100644 image-generator-demo/vite.config.ts delete mode 100644 react-frontend/vite-plugins/multiple-assets/build.ts delete mode 100644 react-frontend/vite-plugins/multiple-assets/index.ts delete mode 100644 react-frontend/vite-plugins/multiple-assets/server.ts delete mode 100644 studio-frontend/vite-plugins/multiple-assets/build.ts delete mode 100644 studio-frontend/vite-plugins/multiple-assets/index.ts delete mode 100644 studio-frontend/vite-plugins/multiple-assets/server.ts create mode 100644 studio-ui/README.md create mode 100644 studio-ui/package.json create mode 100644 studio-ui/project.json create mode 100644 studio-ui/src/index.ts rename {studio-frontend/src/app => studio-ui/src/lib}/button.element.scss (100%) rename {studio-frontend/src/app => studio-ui/src/lib}/button.element.ts (100%) rename {studio-frontend/src/app => studio-ui/src/lib}/icon.element.scss (100%) rename {studio-frontend/src/app => studio-ui/src/lib}/icon.element.ts (100%) rename {studio-frontend/src/app => studio-ui/src/lib}/toolbar-group.element.scss (100%) rename {studio-frontend/src/app => studio-ui/src/lib}/toolbar.element.scss (100%) rename {studio-frontend/src/app => studio-ui/src/lib}/toolbar.element.ts (100%) rename {studio-frontend/src/app => studio-ui/src/lib}/tree.element.scss (100%) rename {studio-frontend/src/app => studio-ui/src/lib}/tree.element.ts (97%) create mode 100644 studio-ui/tsconfig.json create mode 100644 studio-ui/tsconfig.lib.json create mode 100644 studio-ui/tsconfig.spec.json create mode 100644 studio-ui/vite.config.ts create mode 100644 studio-web/src/lib/scene-hierarchy.element.scss create mode 100644 studio-web/src/lib/scene-hierarchy.element.ts rename {studio-frontend/src/app => studio-web/src/lib}/transform-toolbar.element.scss (100%) rename {studio-frontend/src/app => studio-web/src/lib}/transform-toolbar.element.ts (72%) create mode 100644 studio-web/src/lib/url-params.ts create mode 100644 studio/src/change_tracking.rs create mode 100644 studio/src/wasm/screenshot.rs create mode 100644 vite-multiple-assets/README.md create mode 100644 vite-multiple-assets/package.json create mode 100644 vite-multiple-assets/project.json create mode 100644 vite-multiple-assets/src/index.ts create mode 100644 vite-multiple-assets/src/lib/build.ts create mode 100644 vite-multiple-assets/src/lib/server.ts create mode 100644 vite-multiple-assets/tsconfig.json create mode 100644 vite-multiple-assets/tsconfig.lib.json create mode 100644 vite-multiple-assets/tsconfig.spec.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 645d66b..4f9b6e6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,7 +5,8 @@ "*.tsx": "${capture}.module.scss, ${capture}.spec.tsx", }, "rust-analyzer.cargo.features": [ - "wasm" + "wasm", + "wasm_screenshot" ], "files.associations": { "*.meta": "ron" diff --git a/editor.ron b/editor.ron index 2f5962d..5ec76bc 100644 --- a/editor.ron +++ b/editor.ron @@ -1,6 +1,6 @@ { + "space_editor_core::hotkeys::HotkeySet": "{\"space_editor_core::hotkeys::HotkeySet\":(bindings:{Rotate:[R],Translate:[G],Scale:[S],Multiple:[ShiftLeft],Clone:[AltLeft],Delete:[X]},name:\"GizmoHotkey\")}", "space_undo::ChangeChainSettings": "{\"space_undo::ChangeChainSettings\":(max_change_chain_size:200)}", "space_persistence::PersistenceSettings": "{\"space_persistence::PersistenceSettings\":(load_on_startup:true,save_on_close:true)}", - "space_editor_core::hotkeys::HotkeySet": "{\"space_editor_core::hotkeys::HotkeySet\":(bindings:{Rotate:[R],Translate:[G],Scale:[S],Multiple:[ShiftLeft],Clone:[AltLeft],Delete:[X]},name:\"GizmoHotkey\")}", "space_editor_ui::settings::NewWindowSettings": "{\"space_editor_ui::settings::NewWindowSettings\":(new_tab:SameNode)}", } \ No newline at end of file diff --git a/image-generator-demo/.swcrc b/image-generator-demo/.swcrc new file mode 100644 index 0000000..f83e5db --- /dev/null +++ b/image-generator-demo/.swcrc @@ -0,0 +1,8 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript" + }, + "target": "ES2020" + } +} diff --git a/image-generator-demo/index.html b/image-generator-demo/index.html new file mode 100644 index 0000000..190aac3 --- /dev/null +++ b/image-generator-demo/index.html @@ -0,0 +1,19 @@ + + + + + Image Generator Demo + + + + + + + + + + + + + + diff --git a/image-generator-demo/project.json b/image-generator-demo/project.json new file mode 100644 index 0000000..719f5b8 --- /dev/null +++ b/image-generator-demo/project.json @@ -0,0 +1,71 @@ +{ + "name": "image-generator-demo", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "sourceRoot": "image-generator-demo/src", + "tags": [], + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": [ + "{options.outputPath}" + ], + "defaultConfiguration": "production", + "options": { + "outputPath": "dist/image-generator-demo" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "serve": { + "executor": "@nx/vite:dev-server", + "defaultConfiguration": "development", + "dependsOn": [ + { + "projects": ["studio"], + "target": "build:image-generator" + } + ], + "options": { + "buildTarget": "image-generator-demo:build" + }, + "configurations": { + "development": { + "buildTarget": "image-generator-demo:build:development", + "hmr": true + }, + "production": { + "buildTarget": "image-generator-demo:build:production", + "hmr": false + } + } + }, + "preview": { + "executor": "@nx/vite:preview-server", + "defaultConfiguration": "production", + "dependsOn": [ + { + "projects": ["studio"], + "target": "build:image-generator" + } + ], + "options": { + "buildTarget": "image-generator-demo:build" + }, + "configurations": { + "development": { + "buildTarget": "image-generator-demo:build:development" + }, + "production": { + "buildTarget": "image-generator-demo:build:production" + } + } + } + } +} diff --git a/image-generator-demo/public/favicon.ico b/image-generator-demo/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..317ebcb2336e0833a22dddf0ab287849f26fda57 GIT binary patch literal 15086 zcmeI332;U^%p|z7g|#(P)qFEA@4f!_@qOK2 z_lJl}!lhL!VT_U|uN7%8B2iKH??xhDa;*`g{yjTFWHvXn;2s{4R7kH|pKGdy(7z!K zgftM+Ku7~24TLlh(!g)gz|foI94G^t2^IO$uvX$3(OR0<_5L2sB)lMAMy|+`xodJ{ z_Uh_1m)~h?a;2W{dmhM;u!YGo=)OdmId_B<%^V^{ovI@y`7^g1_V9G}*f# zNzAtvou}I!W1#{M^@ROc(BZ! z+F!!_aR&Px3_reO(EW+TwlW~tv*2zr?iP7(d~a~yA|@*a89IUke+c472NXM0wiX{- zl`UrZC^1XYyf%1u)-Y)jj9;MZ!SLfd2Hl?o|80Su%Z?To_=^g_Jt0oa#CT*tjx>BI z16wec&AOWNK<#i0Qd=1O$fymLRoUR*%;h@*@v7}wApDl^w*h}!sYq%kw+DKDY)@&A z@9$ULEB3qkR#85`lb8#WZw=@})#kQig9oqy^I$dj&k4jU&^2(M3q{n1AKeGUKPFbr z1^<)aH;VsG@J|B&l>UtU#Ejv3GIqERzYgL@UOAWtW<{p#zy`WyJgpCy8$c_e%wYJL zyGHRRx38)HyjU3y{-4z6)pzb>&Q1pR)B&u01F-|&Gx4EZWK$nkUkOI|(D4UHOXg_- zw{OBf!oWQUn)Pe(=f=nt=zkmdjpO^o8ZZ9o_|4tW1ni+Un9iCW47*-ut$KQOww!;u z`0q)$s6IZO!~9$e_P9X!hqLxu`fpcL|2f^I5d4*a@Dq28;@2271v_N+5HqYZ>x;&O z05*7JT)mUe&%S0@UD)@&8SmQrMtsDfZT;fkdA!r(S=}Oz>iP)w=W508=Rc#nNn7ym z1;42c|8($ALY8#a({%1#IXbWn9-Y|0eDY$_L&j{63?{?AH{);EzcqfydD$@-B`Y3<%IIj7S7rK_N}je^=dEk%JQ4c z!tBdTPE3Tse;oYF>cnrapWq*o)m47X1`~6@(!Y29#>-#8zm&LXrXa(3=7Z)ElaQqj z-#0JJy3Fi(C#Rx(`=VXtJ63E2_bZGCz+QRa{W0e2(m3sI?LOcUBx)~^YCqZ{XEPX)C>G>U4tfqeH8L(3|pQR*zbL1 zT9e~4Tb5p9_G}$y4t`i*4t_Mr9QYvL9C&Ah*}t`q*}S+VYh0M6GxTTSXI)hMpMpIq zD1ImYqJLzbj0}~EpE-aH#VCH_udYEW#`P2zYmi&xSPs_{n6tBj=MY|-XrA;SGA_>y zGtU$?HXm$gYj*!N)_nQ59%lQdXtQZS3*#PC-{iB_sm+ytD*7j`D*k(P&IH2GHT}Eh z5697eQECVIGQAUe#eU2I!yI&%0CP#>%6MWV z@zS!p@+Y1i1b^QuuEF*13CuB zu69dve5k7&Wgb+^s|UB08Dr3u`h@yM0NTj4h7MnHo-4@xmyr7(*4$rpPwsCDZ@2be zRz9V^GnV;;?^Lk%ynzq&K(Aix`mWmW`^152Hoy$CTYVehpD-S1-W^#k#{0^L`V6CN+E z!w+xte;2vu4AmVNEFUOBmrBL>6MK@!O2*N|2=d|Y;oN&A&qv=qKn73lDD zI(+oJAdgv>Yr}8(&@ZuAZE%XUXmX(U!N+Z_sjL<1vjy1R+1IeHt`79fnYdOL{$ci7 z%3f0A*;Zt@ED&Gjm|OFTYBDe%bbo*xXAQsFz+Q`fVBH!N2)kaxN8P$c>sp~QXnv>b zwq=W3&Mtmih7xkR$YA)1Yi?avHNR6C99!u6fh=cL|KQ&PwF!n@ud^n(HNIImHD!h87!i*t?G|p0o+eelJ?B@A64_9%SBhNaJ64EvKgD&%LjLCYnNfc; znj?%*p@*?dq#NqcQFmmX($wms@CSAr9#>hUR^=I+=0B)vvGX%T&#h$kmX*s=^M2E!@N9#m?LhMvz}YB+kd zG~mbP|D(;{s_#;hsKK9lbVK&Lo734x7SIFJ9V_}2$@q?zm^7?*XH94w5Qae{7zOMUF z^?%F%)c1Y)Q?Iy?I>knw*8gYW#ok|2gdS=YYZLiD=CW|Nj;n^x!=S#iJ#`~Ld79+xXpVmUK^B(xO_vO!btA9y7w3L3-0j-y4 z?M-V{%z;JI`bk7yFDcP}OcCd*{Q9S5$iGA7*E1@tfkyjAi!;wP^O71cZ^Ep)qrQ)N z#wqw0_HS;T7x3y|`P==i3hEwK%|>fZ)c&@kgKO1~5<5xBSk?iZV?KI6&i72H6S9A* z=U(*e)EqEs?Oc04)V-~K5AUmh|62H4*`UAtItO$O(q5?6jj+K^oD!04r=6#dsxp?~}{`?&sXn#q2 zGuY~7>O2=!u@@Kfu7q=W*4egu@qPMRM>(eyYyaIE<|j%d=iWNdGsx%c!902v#ngNg z@#U-O_4xN$s_9?(`{>{>7~-6FgWpBpqXb`Ydc3OFL#&I}Irse9F_8R@4zSS*Y*o*B zXL?6*Aw!AfkNCgcr#*yj&p3ZDe2y>v$>FUdKIy_2N~}6AbHc7gA3`6$g@1o|dE>vz z4pl(j9;kyMsjaw}lO?(?Xg%4k!5%^t#@5n=WVc&JRa+XT$~#@rldvN3S1rEpU$;XgxVny7mki3 z-Hh|jUCHrUXuLr!)`w>wgO0N%KTB-1di>cj(x3Bav`7v z3G7EIbU$z>`Nad7Rk_&OT-W{;qg)-GXV-aJT#(ozdmnA~Rq3GQ_3mby(>q6Ocb-RgTUhTN)))x>m&eD;$J5Bg zo&DhY36Yg=J=$Z>t}RJ>o|@hAcwWzN#r(WJ52^g$lh^!63@hh+dR$&_dEGu&^CR*< z!oFqSqO@>xZ*nC2oiOd0eS*F^IL~W-rsrO`J`ej{=ou_q^_(<$&-3f^J z&L^MSYWIe{&pYq&9eGaArA~*kA studio.requestScreenshot(), this.Wait, config); + } +} + +@customElement("app-root") +export class AppElement extends LitElement { + @state() loading = true; + @state() imageCaptureUrl?: string; + @state() realtimeCapture = true; + + params = new StudioURLParams(); + viewer = createRef(); + + protected override createRenderRoot = () => this; + + override disconnectedCallback(): void { + if (this.imageCaptureUrl != null) + URL.revokeObjectURL(this.imageCaptureUrl); + + super.disconnectedCallback(); + } + + @on("scene-state") + onSceneStateChange({ detail: state }: SceneStateEvent): void { + console.log("scene state change:", SceneState[state]); + + this.loading = match (state, { + [SceneState.Active]: () => false, + _: () => true, + }); + } + + @on("entity-changes") + onStudioChanges(): void { + this.requestScreenshot(); + } + + requestScreenshot = Debounce.func(Debounce.Realtime); + + @on("screenshot-ready") + onScreenshotReady({ detail: screenshot }: ScreenshotReadyEvent) { + const prevUrl = this.imageCaptureUrl; + + const blob = new Blob([screenshot.data.buffer], { type: "image/png" }); + this.imageCaptureUrl = URL.createObjectURL(blob); + console.log(`New blob URL: ${this.imageCaptureUrl}`); + + if (prevUrl != null) + URL.revokeObjectURL(prevUrl); + } + + toggleRealtimeCapture(event: InputEvent): void { + const { checked } = event.target as HTMLInputElement; + this.realtimeCapture = checked; + + const config = checked ? Debounce.Realtime : Debounce.Delayed; + this.requestScreenshot = Debounce.func(config); + } + + protected override render = () => html` + + + + ${this.imageCaptureUrl != null ? html` + Image capture + ` : nothing} + + + +
+ +
+ + ${this.loading ? html` + +
+

Loading

+
+ ` : nothing} +
+ ` +} diff --git a/image-generator-demo/src/main.ts b/image-generator-demo/src/main.ts new file mode 100644 index 0000000..cde5d45 --- /dev/null +++ b/image-generator-demo/src/main.ts @@ -0,0 +1 @@ +import "./app/app.element"; diff --git a/image-generator-demo/src/styles.scss b/image-generator-demo/src/styles.scss new file mode 100644 index 0000000..3782467 --- /dev/null +++ b/image-generator-demo/src/styles.scss @@ -0,0 +1,10 @@ +*, *::before, *::after { + box-sizing: border-box; +} + +html, body { + width: 100%; + height: 100%; + margin: 0; + overflow: hidden; +} diff --git a/image-generator-demo/tsconfig.app.json b/image-generator-demo/tsconfig.app.json new file mode 100644 index 0000000..433a657 --- /dev/null +++ b/image-generator-demo/tsconfig.app.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "types": ["node"] + }, + "exclude": [ + "src/**/*.spec.ts", + "src/**/*.test.ts" + ], + "include": [ + "src/**/*.ts", + "typings/*.d.ts" + ] +} diff --git a/image-generator-demo/tsconfig.json b/image-generator-demo/tsconfig.json new file mode 100644 index 0000000..724ccfc --- /dev/null +++ b/image-generator-demo/tsconfig.json @@ -0,0 +1,34 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "compilerOptions": { + "target": "ES2020", + "experimentalDecorators": true, + "useDefineForClassFields": false, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "esModuleInterop": true, + + "strict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitAny": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + + "types": ["vite/client"] + }, + "include": ["src"], + "references": [ + { + "path": "./tsconfig.app.json" + } + ] +} diff --git a/image-generator-demo/typings/scss.d.ts b/image-generator-demo/typings/scss.d.ts new file mode 100644 index 0000000..c057e6a --- /dev/null +++ b/image-generator-demo/typings/scss.d.ts @@ -0,0 +1,4 @@ +declare module "*.scss?inline" { + const styles: import("lit").CSSResult; + export default styles; +} diff --git a/image-generator-demo/typings/svg.d.ts b/image-generator-demo/typings/svg.d.ts new file mode 100644 index 0000000..bc2f8ce --- /dev/null +++ b/image-generator-demo/typings/svg.d.ts @@ -0,0 +1,4 @@ +declare module "*.svg?raw" { + const svg: string; + export default svg; +} diff --git a/image-generator-demo/vite.config.ts b/image-generator-demo/vite.config.ts new file mode 100644 index 0000000..d9af530 --- /dev/null +++ b/image-generator-demo/vite.config.ts @@ -0,0 +1,29 @@ + +/// +import { defineConfig } from "vite"; + +import { nxViteTsPaths } from "@nx/vite/plugins/nx-tsconfig-paths.plugin"; +import wasm from "vite-plugin-wasm"; +import topLevelAwait from "vite-plugin-top-level-await"; +import mergeAssetsDirs from "../vite-multiple-assets"; + +export default defineConfig({ + cacheDir: "../node_modules/.vite/image-generator-demo", + server:{ + port: 4200, + host: "localhost", + }, + preview:{ + port: 4300, + host: "localhost", + }, + plugins: [ + nxViteTsPaths(), + wasm(), + topLevelAwait(), + mergeAssetsDirs([ + "image-generator-demo/public", + "dist/studio/public", + ]), + ], +}); diff --git a/react-frontend/vite-plugins/multiple-assets/build.ts b/react-frontend/vite-plugins/multiple-assets/build.ts deleted file mode 100644 index b478c9d..0000000 --- a/react-frontend/vite-plugins/multiple-assets/build.ts +++ /dev/null @@ -1,25 +0,0 @@ -import fs from "fs"; -import {NormalizedOutputOptions} from "rollup"; - -function copyRecursively(src: string, dst: string) { - if (fs.statSync(src).isDirectory()) { - // folder - if (!fs.existsSync(dst)) { - fs.mkdirSync(dst); - } - for (const file of fs.readdirSync(src)) { - copyRecursively(src + "/" + file, dst + "/" + file); - } - } else { - // file - fs.copyFileSync(src, dst); - } -} - -export function buildMiddleWare(options: NormalizedOutputOptions, assets: string[] = []) { - const dst = options.dir; - if (!dst) throw new Error("options.dir is undefined"); - for (const dir of assets) { - copyRecursively(dir, dst) - } -} diff --git a/react-frontend/vite-plugins/multiple-assets/index.ts b/react-frontend/vite-plugins/multiple-assets/index.ts deleted file mode 100644 index bef1d09..0000000 --- a/react-frontend/vite-plugins/multiple-assets/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -// FIXME: Oh my god, did Danny seriously just copy and paste this entire folder -// from `studio-frontend` instead of creating a separate project for it -// and importing it like a decent, law-abiding citizen? Wow, dude really -// needs to get his shit together. - -// NOTE: This is an inline fork of this npm package: -// https://github.com/nguyenbatranvan/vite-multiple-assets -// -// The published version at time of writing doesn't include mime types for many -// of the asset types Bevy needs to load. - -import {PluginOption, ViteDevServer} from "vite"; -import {ServerMiddleWare} from "./server"; -import {buildMiddleWare} from "./build"; - -export default function DynamicPublicDirectory(assets: string[]): PluginOption { - return { - configureServer(server: ViteDevServer) { - return ServerMiddleWare(server, assets) - }, - async writeBundle(options) { - buildMiddleWare(options, assets) - }, - name: "dynamic assets" - }; -} diff --git a/react-frontend/vite-plugins/multiple-assets/server.ts b/react-frontend/vite-plugins/multiple-assets/server.ts deleted file mode 100644 index 61455c4..0000000 --- a/react-frontend/vite-plugins/multiple-assets/server.ts +++ /dev/null @@ -1,91 +0,0 @@ -import fs from "fs"; -import path from "path"; -import { ViteDevServer } from "vite"; - -interface IPropsFile { - name: string; - files: string[]; -} - -function getFiles(dir, files_): string[] { - files_ = files_ || []; - const files = fs.readdirSync(dir); - for (const i in files) { - const name = dir + "/" + files[i]; - if (fs.statSync(name).isDirectory()) { - getFiles(name, files_); - } else { - files_.push(name); - } - } - return files_; -} - -const mimeTypes = { - ".7z": "application/x-7z-compressed", - ".bin": "application/octet-stream", - ".css": "text/css", - ".eot": "font/eot", - ".gif": "image/gif", - ".gltf": "model/gltf+json", - ".gz": "application/gzip", - ".hdr": "image/vnd.radiance", - ".html": "text/html", - ".ico": "image/x-icon", - ".jpg": "image/jpeg", - ".js": "text/javascript", - ".json": "application/json", - ".ktx": "image/ktx", - ".ktx2": "image/ktx", - ".meta": "text/plain", - ".mjs": "text/javascript", - ".mp3": "audio/mpeg", - ".mp4": "video/mp4", - ".otf": "font/otf", - ".png": "image/png", - ".rar": "application/x-rar-compressed", - ".svg": "image/svg+xml", - ".tiff": "image/tiff", - ".ttf": "font/ttf", - ".txt": "text/plain", - ".wasm": "application/wasm", - ".webm": "video/webm", - ".webp": "image/webp", - ".wgsl": "text/wgsl", - ".woff": "font/woff", - ".woff2": "font/woff2", - ".xml": "text/xml", - ".zip": "application/zip", -} - -export function ServerMiddleWare(server: ViteDevServer, assets: string[] = []) { - if (!assets || !assets.length) - return; - - const fileObject: IPropsFile[] = []; - for (let i = 0; i < assets.length; i++) { - const files = getFiles(path.join(process.cwd(), `/${assets[i]}`), []); - fileObject.push({ - name: assets[i], - files - }); - } - - return () => { - server.middlewares.use(async (req, res, next) => { - for (let i = 0; i < fileObject.length; i++) { - const file = path.join(process.cwd(), `${fileObject[i].name}/${req.originalUrl}`); - if (fileObject[i].files.some(f => path.relative(f, file) === "")) { - const extension = file.substring(file.lastIndexOf(".")); - res.setHeader("Cache-Control", "max-age=31536000, immutable"); - res.setHeader("Content-Type", mimeTypes[extension]); - res.writeHead(200); - res.write(fs.readFileSync(path.join(process.cwd(), "/" + fileObject[i].name + req.originalUrl))); - res.end(); - break; - } - } - next(); - }); - }; -} diff --git a/react-frontend/vite.config.ts b/react-frontend/vite.config.ts index 483252c..248a00b 100644 --- a/react-frontend/vite.config.ts +++ b/react-frontend/vite.config.ts @@ -3,8 +3,7 @@ import react from "@vitejs/plugin-react"; import { defineConfig } from "vite"; import topLevelAwait from "vite-plugin-top-level-await"; import wasm from "vite-plugin-wasm"; - -import mergeAssetsDirs from "./vite-plugins/multiple-assets"; +import mergeAssetsDirs from "../vite-multiple-assets"; export default defineConfig({ cacheDir: "../node_modules/.vite/react-frontend", diff --git a/studio-frontend/src/app/anim-editor.element.ts b/studio-frontend/src/app/anim-editor.element.ts index b108990..47500ed 100644 --- a/studio-frontend/src/app/anim-editor.element.ts +++ b/studio-frontend/src/app/anim-editor.element.ts @@ -5,10 +5,10 @@ import { LitElement, type PropertyValues, html, unsafeCSS } from "lit"; import { customElement, state } from "lit/decorators.js"; import { styleMap } from "lit/directives/style-map.js"; +import "@storyteller/studio-ui/button"; +import "@storyteller/studio-ui/toolbar"; +import "@storyteller/studio-ui/tree"; import "./anim-timeline.element"; -import "./button.element"; -import "./toolbar.element"; -import "./tree.element"; import styles from "./anim-editor.element.scss?inline"; diff --git a/studio-frontend/src/app/app.element.scss b/studio-frontend/src/app/app.element.scss index fc4a85b..f580b98 100644 --- a/studio-frontend/src/app/app.element.scss +++ b/studio-frontend/src/app/app.element.scss @@ -35,33 +35,9 @@ sts-button.active { // Hierarchy (TODO: Probably move this) .hierarchy { - overflow: auto; - - box-sizing: border-box; width: $hierarchy-width; max-height: calc(100vh - 32px); - padding: 10px 15px; - - background: #0006; - backdrop-filter: blur(16px); - border: 8px solid transparent; - border-radius: 0.5rem; - pointer-events: auto; - - &::-webkit-scrollbar { - width: 8px; - height: 8px; - - &-thumb { - border-radius: 2px; - background: #FFF2; - - &:hover { - background: #FFF3; - } - } - } } .loading { diff --git a/studio-frontend/src/app/app.element.ts b/studio-frontend/src/app/app.element.ts index f2ad003..a9c4685 100644 --- a/studio-frontend/src/app/app.element.ts +++ b/studio-frontend/src/app/app.element.ts @@ -1,17 +1,12 @@ import { on } from "@storyteller/framework"; import * as studio from "@storyteller/studio"; import { - type EntityDespawnEvent, - type EntityMultiSpawnEvent, - type EntitySelectEvent, - type EntitySpawnEvent, type SceneSavedEvent, type SceneStateEvent, - TransformSpace, - TransformType, SceneState, StudioMode, } from "@storyteller/studio"; +import { StudioURLParams } from "@storyteller/studio-web"; import { CanvasProvider } from "@storyteller/studio-web/canvas-provider"; import { match } from "@storyteller/utility"; import { LitElement, html, nothing } from "lit"; @@ -20,144 +15,35 @@ import { classMap } from "lit-html/directives/class-map.js"; import { Ref, createRef, ref } from "lit-html/directives/ref.js"; import { v4 as uuid } from "uuid"; +import "@storyteller/studio-ui/button"; +import "@storyteller/studio-ui/icon"; +import "@storyteller/studio-ui/toolbar"; +import "@storyteller/studio-ui/tree"; import "@storyteller/studio-web/canvas-provider"; import "@storyteller/studio-web/viewer"; import "@storyteller/studio-web/bvh-viewer"; import "@storyteller/studio-web/editor"; import "@storyteller/studio-web/mixamo-viewer"; +import "@storyteller/studio-web/scene-hierarchy"; +import "@storyteller/studio-web/transform-toolbar"; import "./anim-editor.element"; -import "./button.element"; import "./help.element"; -import "./icon.element"; -import "./toolbar.element"; -import "./transform-toolbar.element"; -import "./tree.element"; import "./app.element.scss"; -interface SceneObject extends Omit { - children: SceneObject[]; -} - @customElement("app-root") export class AppElement extends LitElement { @state() showHelp = false; @state() loading = true; - @state() transformSpace = TransformSpace.Local; - @state() transformType = TransformType.Translate; - - @state() sceneObjects: SceneObject[] = []; - @state() selection?: string | null; - - @state() bvhPath?: string; - @state() mixamoPath?: string; - @state() scenePath?: string; - @state() mode?: StudioMode; - - #sceneObjects: studio.SceneObject[] = []; - #entityMap = new Map(); + #params = new StudioURLParams(); #canvasProvider: Ref = createRef(); - get #studioCanvas(): HTMLCanvasElement | null { - const provider = this.#canvasProvider.value; - if (!provider) return null; - - return document.getElementById(provider.canvasId) as HTMLCanvasElement | null; - } - - override connectedCallback(): void { - super.connectedCallback(); - - const params = new URLSearchParams(document.location.search); - - if (params.has("bvh")) - this.bvhPath = params.get("bvh")!; - - if (params.has("mixamo")) - this.mixamoPath = params.get("mixamo")!; - - if (params.has("scene")) - this.scenePath = params.get("scene")!; - - this.mode = match (params.get("mode"), { - "studio": () => StudioMode.Editor, - "viewer": () => StudioMode.Viewer, - _: () => StudioMode.Viewer, - }); - - this.#redirectBodyFocus(); - } - protected override createRenderRoot(): Element | ShadowRoot { return this; } - @on("keydown") - @on("keyup") - pipeKeyboardEvents(event: KeyboardEvent): void { - // When the user interacts with one of the web UI elements, the Bevy - // canvas will lose focus, preventing it from receiving keyboard events. - // As a workaround, we can listen for any events that have bubbled up to - // the app root and repeat them for the canvas. - // - // This does unfortunately burden the web front-end with some additional - // responsibility: when we handle a keyboard event and _don't_ want the - // Bevy app to receive it, we'll need to call `event.stopPropagation()` in - // the handler to prevent it from reaching this listener. - const { - type, - code, charCode, key, keyCode, location, repeat, - altKey, ctrlKey, metaKey, shiftKey, - } = event; - - this.#studioCanvas?.dispatchEvent(new KeyboardEvent(type, { - code, charCode, key, keyCode, location, repeat, - altKey, ctrlKey, metaKey, shiftKey, - bubbles: true, - cancelable: true, - composed: true, - })); - } - - onSceneStateChange({ detail: state }: SceneStateEvent): void { - console.log("scene state change:", SceneState[state]); - - this.loading = match (state, { - [SceneState.Active]: () => false, - _: () => true, - }); - } - - @on("window:entity-select") - onEntitySelectionChange({ detail: entity }: EntitySelectEvent): void { - const sceneObject = this.#entityMap.get(entity!); - console.log("Entity selection changed:", sceneObject); - this.selection = entity; - } - - @on("window:entity-spawn") - onEntitySpawned({ detail: value }: EntitySpawnEvent): void { - console.log("Entity spawned:", value); - this.#sceneObjects = this.#sceneObjects.concat(value).sort(sortByName); - this.#updateHierarchy(); - } - - @on("window:entity-multi-spawn") - onEntitiesSpawned({ detail: values }: EntityMultiSpawnEvent): void { - console.log("Entities spawned:", values); - this.#sceneObjects = this.#sceneObjects.concat(values).sort(sortByName); - this.#updateHierarchy(); - } - - @on("window:entity-despawn") - onEntityDespawned({ detail: entity }: EntityDespawnEvent): void { - console.log("Entity despawned:", entity); - this.#sceneObjects = this.#sceneObjects.filter(({ id }) => id !== entity); - this.#updateHierarchy(); - } - - @on("window:scene-saved") + @on("scene-saved") async onSceneSaved({ detail: scene }: SceneSavedEvent): Promise { const file = new File([scene], "scene.scn.ron", { type: "text/ron" }); const formData = new FormData(); @@ -179,98 +65,52 @@ export class AppElement extends LitElement { } } + @on("scene-state") + onSceneStateChange({ detail: state }: SceneStateEvent): void { + console.log("scene state change:", SceneState[state]); + + this.loading = match (state, { + [SceneState.Active]: () => false, + _: () => true, + }); + } + toggleHelp(): void { this.showHelp = !this.showHelp; } - onTransformSpaceChange({ detail: space }: CustomEvent): void { - this.transformSpace = space; - studio.setTransformSpace(space); - } - - onTransformTypeChange({ detail: type }: CustomEvent): void { - this.transformType = type; - studio.setTransformType(type); - } - - // TODO: Get some help from someone who knows what an algorithm is - #updateHierarchy(): void { - this.#entityMap.clear(); - - for (let obj of this.#sceneObjects) - this.#entityMap.set(obj.id, { ...obj, children: [] }); - - for (let obj of this.#entityMap.values()) { - if (obj.parent != null) { - const parent = this.#entityMap.get(obj.parent); - if (!parent) - throw new Error(`Missing parent: ${obj.parent}`); - - parent.children.push(obj); - } - } - - for (let obj of this.#entityMap.values()) - obj.children.sort(sortByName); - - this.sceneObjects = Array - .from(this.#entityMap.values()) - .filter(obj => obj.parent == null) - .sort(sortByName); - - console.log("Hierarchy:", this.sceneObjects); - } - - #redirectBodyFocus(): void { - // If user focus lands on the `document.body`, neither the frontend app - // nor the Bevy app will properly handle keyboard events. Thie function - // runs every tick to ensure that user focus never becomes "stranded" in - // this way. - if (document.activeElement === document.body) { - const canvasId = this.#canvasProvider.value?.canvasId; - if (canvasId) - document.getElementById(canvasId)?.focus(); - } - - requestAnimationFrame(() => this.#redirectBodyFocus()); - } - protected override render = () => html` - ${this.bvhPath ? html` + ${this.#params.bvh ? html` - ` : this.mixamoPath ? html` + ` : this.#params.mixamo ? html` - ` : this.scenePath ? html` + ` : this.#params.scene ? html` ` : html` `} - ${this.mode === StudioMode.Editor ? html` + ${this.#params.mode === StudioMode.Editor ? html` studio.saveScene()} @@ -288,30 +128,10 @@ export class AppElement extends LitElement { - ${this.mode === StudioMode.Editor ? html` - - - - -
- ${this.sceneObjects.map(obj => html` - - `)} -
- ` : nothing} - - - ${this.mode === StudioMode.Editor ? html` + + ${this.#params.mode === StudioMode.Editor ? html` + + ` : nothing} @@ -329,7 +149,3 @@ export class AppElement extends LitElement {
`; } - -function sortByName(a: { name: string }, b: { name: string }): number { - return a.name.localeCompare(b.name); -} diff --git a/studio-frontend/vite-plugins/multiple-assets/build.ts b/studio-frontend/vite-plugins/multiple-assets/build.ts deleted file mode 100644 index b478c9d..0000000 --- a/studio-frontend/vite-plugins/multiple-assets/build.ts +++ /dev/null @@ -1,25 +0,0 @@ -import fs from "fs"; -import {NormalizedOutputOptions} from "rollup"; - -function copyRecursively(src: string, dst: string) { - if (fs.statSync(src).isDirectory()) { - // folder - if (!fs.existsSync(dst)) { - fs.mkdirSync(dst); - } - for (const file of fs.readdirSync(src)) { - copyRecursively(src + "/" + file, dst + "/" + file); - } - } else { - // file - fs.copyFileSync(src, dst); - } -} - -export function buildMiddleWare(options: NormalizedOutputOptions, assets: string[] = []) { - const dst = options.dir; - if (!dst) throw new Error("options.dir is undefined"); - for (const dir of assets) { - copyRecursively(dir, dst) - } -} diff --git a/studio-frontend/vite-plugins/multiple-assets/index.ts b/studio-frontend/vite-plugins/multiple-assets/index.ts deleted file mode 100644 index 066c88a..0000000 --- a/studio-frontend/vite-plugins/multiple-assets/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -// NOTE: This is an inline fork of this npm package: -// https://github.com/nguyenbatranvan/vite-multiple-assets -// -// The published version at time of writing doesn't include a mime type for -// WGSL, which is fixed in this copy. This module can be removed and replaced -// with the npm dependency if/when this PR is accepted: -// https://github.com/nguyenbatranvan/vite-multiple-assets/pull/5 - -import {PluginOption, ViteDevServer} from "vite"; -import {ServerMiddleWare} from "./server"; -import {buildMiddleWare} from "./build"; - -export default function DynamicPublicDirectory(assets: string[]): PluginOption { - return { - configureServer(server: ViteDevServer) { - return ServerMiddleWare(server, assets) - }, - async writeBundle(options) { - buildMiddleWare(options, assets) - }, - name: "dynamic assets" - }; -} diff --git a/studio-frontend/vite-plugins/multiple-assets/server.ts b/studio-frontend/vite-plugins/multiple-assets/server.ts deleted file mode 100644 index de26582..0000000 --- a/studio-frontend/vite-plugins/multiple-assets/server.ts +++ /dev/null @@ -1,93 +0,0 @@ -import fs from "fs"; -import path from "path"; -import { ViteDevServer } from "vite"; - -interface IPropsFile { - name: string; - files: string[]; -} - -function getFiles(dir, files_): string[] { - files_ = files_ || []; - const files = fs.readdirSync(dir); - for (const i in files) { - const name = dir + "/" + files[i]; - if (fs.statSync(name).isDirectory()) { - getFiles(name, files_); - } else { - files_.push(name); - } - } - return files_; -} - -const mimeTypes = { - ".7z": "application/x-7z-compressed", - ".bin": "application/octet-stream", - ".bvh": "text/bvh", - ".css": "text/css", - ".eot": "font/eot", - ".gif": "image/gif", - ".glb": "model/gltf-binary", - ".gltf": "model/gltf+json", - ".gz": "application/gzip", - ".hdr": "image/vnd.radiance", - ".html": "text/html", - ".ico": "image/x-icon", - ".jpg": "image/jpeg", - ".js": "text/javascript", - ".json": "application/json", - ".ktx": "image/ktx", - ".ktx2": "image/ktx", - ".meta": "text/plain", - ".mjs": "text/javascript", - ".mp3": "audio/mpeg", - ".mp4": "video/mp4", - ".otf": "font/otf", - ".png": "image/png", - ".rar": "application/x-rar-compressed", - ".svg": "image/svg+xml", - ".tiff": "image/tiff", - ".ttf": "font/ttf", - ".txt": "text/plain", - ".wasm": "application/wasm", - ".webm": "video/webm", - ".webp": "image/webp", - ".wgsl": "text/wgsl", - ".woff": "font/woff", - ".woff2": "font/woff2", - ".xml": "text/xml", - ".zip": "application/zip", -} - -export function ServerMiddleWare(server: ViteDevServer, assets: string[] = []) { - if (!assets || !assets.length) - return; - - const fileObject: IPropsFile[] = []; - for (let i = 0; i < assets.length; i++) { - const files = getFiles(path.join(process.cwd(), `/${assets[i]}`), []); - fileObject.push({ - name: assets[i], - files - }); - } - - return () => { - server.middlewares.use(async (req, res, next) => { - for (let i = 0; i < fileObject.length; i++) { - const file = path.join(process.cwd(), `${fileObject[i].name}/${req.originalUrl}`); - if (fileObject[i].files.some(f => path.relative(f, file) === "")) { - const extension = file.substring(file.lastIndexOf(".")); - res.setHeader("Cache-Control", "max-age=31536000, immutable"); - res.setHeader("Content-Type", mimeTypes[extension]); - res.writeHead(200); - res.write(fs.readFileSync(path.join(process.cwd(), "/" + fileObject[i].name + req.originalUrl))); - res.end(); - break; - } - } - next(); - }); - }; -} diff --git a/studio-frontend/vite.config.ts b/studio-frontend/vite.config.ts index 4ade41c..2d5913f 100644 --- a/studio-frontend/vite.config.ts +++ b/studio-frontend/vite.config.ts @@ -5,8 +5,7 @@ import { defineConfig } from "vite"; import { nxViteTsPaths } from "@nx/vite/plugins/nx-tsconfig-paths.plugin"; import wasm from "vite-plugin-wasm"; import topLevelAwait from "vite-plugin-top-level-await"; - -import mergeAssetsDirs from "./vite-plugins/multiple-assets"; +import mergeAssetsDirs from "../vite-multiple-assets"; export default defineConfig({ cacheDir: "../node_modules/.vite/studio-frontend", diff --git a/studio-ui/README.md b/studio-ui/README.md new file mode 100644 index 0000000..e3c328d --- /dev/null +++ b/studio-ui/README.md @@ -0,0 +1,12 @@ +# studio-ui + +This is a UI/component library that can be easily shared between multiple +Storyteller Studio frontend applications. + +## Building + +Run `nx build studio-ui` to build the library. + +## Running unit tests + +Run `nx test studio-ui` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/studio-ui/package.json b/studio-ui/package.json new file mode 100644 index 0000000..5812501 --- /dev/null +++ b/studio-ui/package.json @@ -0,0 +1,12 @@ +{ + "name": "@storyteller/studio-ui", + "version": "0.0.1", + "dependencies": { + "@storyteller/framework": "0.0.1", + "@storyteller/studio": "0.0.1", + "lit": "^2.8.0" + }, + "main": "./index.js", + "module": "./index.mjs", + "typings": "./index.d.ts" + } diff --git a/studio-ui/project.json b/studio-ui/project.json new file mode 100644 index 0000000..623beb6 --- /dev/null +++ b/studio-ui/project.json @@ -0,0 +1,30 @@ +{ + "name": "studio-ui", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "studio-ui/src", + "projectType": "library", + "targets": { + "build": { + "executor": "@nx/vite:build", + "outputs": ["{options.outputPath}"], + "dependsOn": [ + { + "projects": ["studio"], + "target": "build:web" + } + ], + "options": { + "outputPath": "dist/studio-ui" + } + }, + "test": { + "executor": "@nx/vite:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "passWithNoTests": true, + "reportsDirectory": "../coverage/studio-ui" + } + } + }, + "tags": [] +} diff --git a/studio-ui/src/index.ts b/studio-ui/src/index.ts new file mode 100644 index 0000000..6cbf9ae --- /dev/null +++ b/studio-ui/src/index.ts @@ -0,0 +1,4 @@ +export * from "./lib/button.element"; +export * from "./lib/icon.element"; +export * from "./lib/toolbar.element"; +export * from "./lib/tree.element"; diff --git a/studio-frontend/src/app/button.element.scss b/studio-ui/src/lib/button.element.scss similarity index 100% rename from studio-frontend/src/app/button.element.scss rename to studio-ui/src/lib/button.element.scss diff --git a/studio-frontend/src/app/button.element.ts b/studio-ui/src/lib/button.element.ts similarity index 100% rename from studio-frontend/src/app/button.element.ts rename to studio-ui/src/lib/button.element.ts diff --git a/studio-frontend/src/app/icon.element.scss b/studio-ui/src/lib/icon.element.scss similarity index 100% rename from studio-frontend/src/app/icon.element.scss rename to studio-ui/src/lib/icon.element.scss diff --git a/studio-frontend/src/app/icon.element.ts b/studio-ui/src/lib/icon.element.ts similarity index 100% rename from studio-frontend/src/app/icon.element.ts rename to studio-ui/src/lib/icon.element.ts diff --git a/studio-frontend/src/app/toolbar-group.element.scss b/studio-ui/src/lib/toolbar-group.element.scss similarity index 100% rename from studio-frontend/src/app/toolbar-group.element.scss rename to studio-ui/src/lib/toolbar-group.element.scss diff --git a/studio-frontend/src/app/toolbar.element.scss b/studio-ui/src/lib/toolbar.element.scss similarity index 100% rename from studio-frontend/src/app/toolbar.element.scss rename to studio-ui/src/lib/toolbar.element.scss diff --git a/studio-frontend/src/app/toolbar.element.ts b/studio-ui/src/lib/toolbar.element.ts similarity index 100% rename from studio-frontend/src/app/toolbar.element.ts rename to studio-ui/src/lib/toolbar.element.ts diff --git a/studio-frontend/src/app/tree.element.scss b/studio-ui/src/lib/tree.element.scss similarity index 100% rename from studio-frontend/src/app/tree.element.scss rename to studio-ui/src/lib/tree.element.scss diff --git a/studio-frontend/src/app/tree.element.ts b/studio-ui/src/lib/tree.element.ts similarity index 97% rename from studio-frontend/src/app/tree.element.ts rename to studio-ui/src/lib/tree.element.ts index 3911fcc..96ce8a0 100644 --- a/studio-frontend/src/app/tree.element.ts +++ b/studio-ui/src/lib/tree.element.ts @@ -23,7 +23,7 @@ export class TreeElement extends LitElement { @property() name = ""; @property() icon?: string; @property({ attribute: false }) treeChildren?: Tree[]; - @property({ type: Boolean }) expanded = false; + @property({ type: Boolean }) expanded = true; @state() selected = false; diff --git a/studio-ui/tsconfig.json b/studio-ui/tsconfig.json new file mode 100644 index 0000000..451a604 --- /dev/null +++ b/studio-ui/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/studio-ui/tsconfig.lib.json b/studio-ui/tsconfig.lib.json new file mode 100644 index 0000000..4d90bb1 --- /dev/null +++ b/studio-ui/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node", "vite/client"] + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/studio-ui/tsconfig.spec.json b/studio-ui/tsconfig.spec.json new file mode 100644 index 0000000..d231383 --- /dev/null +++ b/studio-ui/tsconfig.spec.json @@ -0,0 +1,25 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/studio-ui/vite.config.ts b/studio-ui/vite.config.ts new file mode 100644 index 0000000..8ac8b66 --- /dev/null +++ b/studio-ui/vite.config.ts @@ -0,0 +1,58 @@ +/// +import { nxViteTsPaths } from "@nx/vite/plugins/nx-tsconfig-paths.plugin"; +import { defineConfig } from "vite"; +import dts from "vite-plugin-dts"; +import wasm from "vite-plugin-wasm"; +import topLevelAwait from "vite-plugin-top-level-await"; +import * as path from "path"; + +export default defineConfig({ + cacheDir: "../node_modules/.vite/studio-web", + + plugins: [ + nxViteTsPaths(), + wasm(), + topLevelAwait(), + dts({ + entryRoot: "src", + tsConfigFilePath: path.join(__dirname, "tsconfig.lib.json"), + skipDiagnostics: true, + }), + ], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + // Configuration for building your library. + // See: https://vitejs.dev/guide/build.html#library-mode + build: { + lib: { + // Could also be a dictionary or array of multiple entry points. + entry: "src/index.ts", + name: "studio-ui", + fileName: "index", + // Change this to the formats you want to support. + // Don't forget to update your package.json as well. + formats: ["es", "cjs"], + }, + rollupOptions: { + // External packages that should not be bundled into your library. + external: [ + "lit", + "@storyteller/framework", + "@storyteller/studio", + ], + }, + }, + + test: { + globals: true, + cache: { + dir: "../node_modules/.vitest", + }, + environment: "jsdom", + include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], + }, +}); diff --git a/studio-web/src/index.ts b/studio-web/src/index.ts index 82671ea..fc74141 100644 --- a/studio-web/src/index.ts +++ b/studio-web/src/index.ts @@ -2,4 +2,7 @@ export * from "./lib/bvh-viewer.element"; export * from "./lib/canvas-provider.element"; export * from "./lib/editor.element"; export * from "./lib/mixamo-viewer.element"; +export * from "./lib/scene-hierarchy.element"; +export * from "./lib/transform-toolbar.element"; +export * from "./lib/url-params"; export * from "./lib/viewer.element"; diff --git a/studio-web/src/lib/canvas-provider.element.ts b/studio-web/src/lib/canvas-provider.element.ts index a8a18c9..31f1889 100644 --- a/studio-web/src/lib/canvas-provider.element.ts +++ b/studio-web/src/lib/canvas-provider.element.ts @@ -1,4 +1,4 @@ -import { Token, UniqueToken, provide } from "@storyteller/framework"; +import { Token, UniqueToken, on, provide } from "@storyteller/framework"; import { LitElement, html, unsafeCSS } from "lit"; import { customElement } from "lit/decorators.js"; @@ -71,6 +71,35 @@ export class CanvasProviderElement super.connectedCallback(); } + @on("keydown") + @on("keyup") + _pipeKeyboardEvents(event: KeyboardEvent): void { + // When the user interacts with one of the web UI elements, the Bevy + // canvas will lose focus, preventing it from receiving keyboard events. + // As a workaround, we can listen for any events that have bubbled up to + // the app root and repeat them for the canvas. + // + // This does unfortunately burden the web front-end with some additional + // responsibility: when we handle a keyboard event and _don't_ want the + // Bevy app to receive it, we'll need to call `event.stopPropagation()` in + // the handler to prevent it from reaching this listener. + const { + type, + code, charCode, key, keyCode, location, repeat, + altKey, ctrlKey, metaKey, shiftKey, + } = event; + + document + .getElementById(this.#canvasId) + ?.dispatchEvent(new KeyboardEvent(type, { + code, charCode, key, keyCode, location, repeat, + altKey, ctrlKey, metaKey, shiftKey, + bubbles: true, + cancelable: true, + composed: true, + })); + } + protected override render = () => html` diff --git a/studio-web/src/lib/scene-hierarchy.element.scss b/studio-web/src/lib/scene-hierarchy.element.scss new file mode 100644 index 0000000..7cc3c00 --- /dev/null +++ b/studio-web/src/lib/scene-hierarchy.element.scss @@ -0,0 +1,24 @@ +:host { + box-sizing: border-box; + padding: 0.5rem 1rem; + overflow: auto; + + background: #0006; + backdrop-filter: blur(16px); + border: 8px solid transparent; + border-radius: 0.5rem; + + &::-webkit-scrollbar { + width: 8px; + height: 8px; + + &-thumb { + border-radius: 2px; + background: #FFF2; + + &:hover { + background: #FFF3; + } + } + } +} diff --git a/studio-web/src/lib/scene-hierarchy.element.ts b/studio-web/src/lib/scene-hierarchy.element.ts new file mode 100644 index 0000000..2769db2 --- /dev/null +++ b/studio-web/src/lib/scene-hierarchy.element.ts @@ -0,0 +1,77 @@ +import * as studio from "@storyteller/studio"; +import { + type EntityDespawnEvent, + type EntityMultiSpawnEvent, + type EntitySpawnEvent, +} from "@storyteller/studio"; +import { on } from "@storyteller/framework"; +import { LitElement, html, unsafeCSS } from "lit"; +import { customElement, state } from "lit/decorators.js"; + +import styles from "./scene-hierarchy.element.scss?inline"; + +import "@storyteller/studio-ui/tree"; + +interface SceneObject extends Omit { + children: SceneObject[]; +} + +@customElement("sts-scene-hierarchy") +export class SceneHierarchyElement extends LitElement { + static override styles = unsafeCSS(styles); + + get tree() { return this._tree as readonly SceneObject[]; } + get entityMap() { return this.#entityMap as ReadonlyMap; } + + @state() private _tree: SceneObject[] = []; + #sceneObjectsFlat: studio.SceneObject[] = []; + #entityMap = new Map(); + + @on("window:entity-spawn") + @on("window:entity-multi-spawn") + _onEntitiesSpawned({ detail: entities }: EntitySpawnEvent | EntityMultiSpawnEvent): void { + this.#sceneObjectsFlat = this.#sceneObjectsFlat.concat(entities); + this.#rebuildTree(); + } + + @on("window:entity-despawn") + _onEntityDespawn({ detail: entity }: EntityDespawnEvent): void { + this.#sceneObjectsFlat = this.#sceneObjectsFlat.filter(({ id }) => id !== entity); + this.#rebuildTree(); + } + + #rebuildTree(): void { + this.#entityMap.clear(); + + for (let obj of this.#sceneObjectsFlat) + this.#entityMap.set(obj.id, { ...obj, children: [] }); + + for (let obj of this.#entityMap.values()) { + if (obj.parent != null) { + const parent = this.#entityMap.get(obj.parent); + if (!parent) + throw new Error(`Missing parent: ${obj.parent}`); + + parent.children.push(obj); + } + } + + for (let obj of this.#entityMap.values()) + obj.children.sort((a, b) => a.name.localeCompare(b.name)); + + this._tree = Array + .from(this.#entityMap.values()) + .filter(obj => obj.parent == null) + .sort((a, b) => a.name.localeCompare(b.name)) + } + + protected override render = () => html` + ${this.tree.map(obj => html` + + `)} + ` +} diff --git a/studio-web/src/lib/studio-base.element.scss b/studio-web/src/lib/studio-base.element.scss index e9de20f..87e527a 100644 --- a/studio-web/src/lib/studio-base.element.scss +++ b/studio-web/src/lib/studio-base.element.scss @@ -10,4 +10,5 @@ inset: 0; width: 100%; height: 100%; + outline: none !important; } diff --git a/studio-web/src/lib/studio-base.element.ts b/studio-web/src/lib/studio-base.element.ts index 65db8cd..6d49d96 100644 --- a/studio-web/src/lib/studio-base.element.ts +++ b/studio-web/src/lib/studio-base.element.ts @@ -10,11 +10,14 @@ import styles from "./studio-base.element.scss?inline"; export abstract class StudioBaseElement extends LitElement { static override styles = unsafeCSS(styles); + get canvas() { return this.#canvas; } + @inject(CANVAS_PROVIDER) _canvasProvider?: CanvasProvider; #canvas?: HTMLCanvasElement; #resizeObserver?: ResizeObserver; + #frameRequest?: number; abstract onStart(viewportSize: ViewportSize): void; abstract onChanges?(changes: PropertyValues): void; @@ -30,9 +33,14 @@ export abstract class StudioBaseElement extends LitElement { if ((this.#canvas = this._canvasProvider.takeCanvas())) this.appendChild(this.#canvas); + + this.#tick(); } override disconnectedCallback(): void { + if (this.#frameRequest != null) + cancelAnimationFrame(this.#frameRequest); + if (this.#canvas) this._canvasProvider?.returnCanvas(this.removeChild(this.#canvas)); @@ -54,6 +62,17 @@ export abstract class StudioBaseElement extends LitElement { studio.resize(new ViewportSize(width, height)); } + #tick(): void { + // If user focus lands on the `document.body`, neither the frontend app + // nor the Bevy app will properly handle keyboard events. Thie function + // runs every tick to ensure that user focus never becomes "stranded" in + // this way. + if (document.activeElement === document.body) + this.#canvas?.focus(); + + this.#frameRequest = requestAnimationFrame(() => this.#tick()); + } + #start(): void { if (!this.#canvas) return; diff --git a/studio-frontend/src/app/transform-toolbar.element.scss b/studio-web/src/lib/transform-toolbar.element.scss similarity index 100% rename from studio-frontend/src/app/transform-toolbar.element.scss rename to studio-web/src/lib/transform-toolbar.element.scss diff --git a/studio-frontend/src/app/transform-toolbar.element.ts b/studio-web/src/lib/transform-toolbar.element.ts similarity index 72% rename from studio-frontend/src/app/transform-toolbar.element.ts rename to studio-web/src/lib/transform-toolbar.element.ts index e6ca3fe..8a8f4e1 100644 --- a/studio-frontend/src/app/transform-toolbar.element.ts +++ b/studio-web/src/lib/transform-toolbar.element.ts @@ -1,7 +1,11 @@ +import * as studio from "@storyteller/studio"; import { TransformSpace, TransformType } from "@storyteller/studio"; import { match } from "@storyteller/utility"; import { LitElement, html, unsafeCSS } from "lit"; -import { customElement, property } from "lit/decorators.js"; +import { customElement, state } from "lit/decorators.js"; + +import "@storyteller/studio-ui/icon"; +import "@storyteller/studio-ui/toolbar"; import styles from "./transform-toolbar.element.scss?inline"; @@ -9,12 +13,15 @@ import styles from "./transform-toolbar.element.scss?inline"; export class TransformToolbarElement extends LitElement { static override styles = unsafeCSS(styles); - @property({ type: Number }) space = TransformSpace.Local; - @property({ type: Number }) type = TransformType.Translate; + get space() { return this._space; } + @state() private _space = TransformSpace.Local; + + get type() { return this._type; } + @state() private _type = TransformType.Translate; #onSpaceChange(event: InputEvent): void { const { value } = event.target as HTMLInputElement; - const space = match (value, { + this._space = match (value, { "local": () => TransformSpace.Local, "world": () => TransformSpace.World, _: () => { @@ -22,11 +29,7 @@ export class TransformToolbarElement extends LitElement { } }); - this.dispatchEvent(new CustomEvent("space-change", { - detail: space, - bubbles: true, - composed: true, - })); + studio.setTransformSpace(this._space); } #onTypeChange(event: InputEvent): void { @@ -40,15 +43,10 @@ export class TransformToolbarElement extends LitElement { } }); - const type = checked - ? this.type | flag - : this.type & ~flag; + if (checked) this._type |= flag; + else this._type &= ~flag; - this.dispatchEvent(new CustomEvent("type-change", { - detail: type, - bubbles: true, - composed: true, - })); + studio.setTransformType(this._type); } protected override render = () => html` @@ -59,7 +57,7 @@ export class TransformToolbarElement extends LitElement { @@ -68,7 +66,7 @@ export class TransformToolbarElement extends LitElement { @@ -78,7 +76,7 @@ export class TransformToolbarElement extends LitElement { Translate @@ -86,7 +84,7 @@ export class TransformToolbarElement extends LitElement { Rotate @@ -95,7 +93,7 @@ export class TransformToolbarElement extends LitElement { diff --git a/studio-web/src/lib/url-params.ts b/studio-web/src/lib/url-params.ts new file mode 100644 index 0000000..a8e449a --- /dev/null +++ b/studio-web/src/lib/url-params.ts @@ -0,0 +1,20 @@ +import { StudioMode } from "@storyteller/studio"; +import { match } from "@storyteller/utility"; + +export class StudioURLParams { + #_nativeParams?: URLSearchParams; + get #nativeParams() { + return this.#_nativeParams ??= new URLSearchParams(document.location.search); + } + + get bvh() { return this.#nativeParams.get("bvh"); } + get mixamo() { return this.#nativeParams.get("mixamo"); } + get scene() { return this.#nativeParams.get("scene"); } + get mode(): StudioMode { + return match(this.#nativeParams.get("mode"), { + "studio": () => StudioMode.Editor, + "viewer": () => StudioMode.Viewer, + _: () => StudioMode.Viewer, + }); + } +} diff --git a/studio/Cargo.toml b/studio/Cargo.toml index 3daa843..3892c64 100644 --- a/studio/Cargo.toml +++ b/studio/Cargo.toml @@ -66,6 +66,7 @@ wasm = [ "bevy_rapier3d/wasm-bindgen", ] desktop = [] +wasm_screenshot = [] [dependencies.bevy] workspace = true diff --git a/studio/project.json b/studio/project.json index bffad5a..eac8000 100644 --- a/studio/project.json +++ b/studio/project.json @@ -27,7 +27,15 @@ "executor": "nx:run-commands", "inputs": ["assets"], "options": { - "command": "node scripts/build-web.mjs", + "command": "node scripts/build-web.mjs --features=wasm", + "cwd": "studio" + } + }, + "build:image-generator": { + "executor": "nx:run-commands", + "inputs": ["assets"], + "options": { + "command": "node scripts/build-web.mjs --features=wasm,wasm_screenshot", "cwd": "studio" } }, @@ -41,8 +49,8 @@ "headless": { "executor": "nx:run-commands", "options": { - "command": "cargo run -p studio --bin studio-headless -- {args}", - } + "command": "cargo run -p studio --bin studio-headless -- {args}" + } }, "test": { "executor": "@nxrs/cargo:test", diff --git a/studio/scripts/build-web.mjs b/studio/scripts/build-web.mjs index bb65eea..10b0c47 100644 --- a/studio/scripts/build-web.mjs +++ b/studio/scripts/build-web.mjs @@ -13,6 +13,12 @@ async function main() { const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); const workspaceRoot = path.resolve(__dirname, "../.."); + const extraCargoArgs = process.argv.slice(2); + console.log(`Extra cargo args:`); + for (let arg of extraCargoArgs) { + console.log(` ${arg}`); + } + /** @type import("node:child_process").StdioOptions */ const stdio = ["ignore", "inherit", "inherit"]; @@ -26,9 +32,8 @@ async function main() { "-p", "studio", "--lib", "--release", - "--features", "wasm", "--target", "wasm32-unknown-unknown", - ], { + ].concat(extraCargoArgs), { shell: true, cwd: workspaceRoot, stdio, diff --git a/studio/src/camera_controller.rs b/studio/src/camera_controller.rs index 186f69d..66d4ae4 100644 --- a/studio/src/camera_controller.rs +++ b/studio/src/camera_controller.rs @@ -10,7 +10,7 @@ use crate::{ interaction::Selected, math::{ Easing, InterpPosition, InterpVelocity, Interpolation, InterpolationSystem, NearlyEq, - Velocity, + NearlyZero, Velocity, }, }; @@ -78,9 +78,6 @@ fn camera_control_kinematic( return; } - let (mut controller, mut xform, proj) = q_camera.single_mut(); - let mut window = q_window.single_mut(); - let mut any_ongoing = false; let mut any_started = false; let mut any_stopped = false; @@ -92,7 +89,8 @@ fn camera_control_kinematic( ) }) { if let InputAction(lifecycle, Action::Camera(motion)) = action { - use CameraMotion::*; + let (mut controller, mut xform, proj) = q_camera.single_mut(); + let window = q_window.single(); match lifecycle { Lifecycle::Start => any_started = true, @@ -100,20 +98,21 @@ fn camera_control_kinematic( Lifecycle::Stop => any_stopped = true, } + use CameraMotion::*; match motion { - Pan(delta) => do_pan(proj, &window, *delta, &mut xform, &mut controller), - Zoom(delta) => do_zoom(&window, *delta, &mut xform, &mut controller), - Orbit(delta) => do_orbit(&window, *delta, *lifecycle, &mut xform, &mut controller), - Rotate(delta) => do_rotate(&window, *delta, &mut xform, &mut controller), + Pan(delta) => do_pan(proj, window, *delta, &mut xform, &mut controller), + Zoom(delta) => do_zoom(window, *delta, &mut xform, &mut controller), + Orbit(delta) => do_orbit(window, *delta, *lifecycle, &mut xform, &mut controller), + Rotate(delta) => do_rotate(window, *delta, &mut xform, &mut controller), _ => {} } } } if any_started { - capture_pointer(&mut window); + capture_pointer(&mut q_window.single_mut()); } else if any_stopped && !any_ongoing { - release_pointer(&mut window); + release_pointer(&mut q_window.single_mut()); } } @@ -215,12 +214,16 @@ fn process_focus_inputs( } fn camera_control_physical( - mut q_camera: Query<(&mut CameraController, &mut Transform, &Velocity)>, + mut q_camera: Query<(Entity, &mut CameraController, &Velocity)>, + mut q_xforms: Query<&mut Transform>, ) { - for (mut controller, mut xform, velocity) in q_camera.iter_mut() { - let delta_pos = xform.rotation * (**velocity); - xform.translation += delta_pos; - controller.focus += delta_pos; + for (ent, mut controller, velocity) in q_camera.iter_mut() { + if !velocity.nearly_zero() { + let mut xform = q_xforms.get_mut(ent).unwrap(); + let delta_pos = xform.rotation * (**velocity); + xform.translation += delta_pos; + controller.focus += delta_pos; + } } } diff --git a/studio/src/change_tracking.rs b/studio/src/change_tracking.rs new file mode 100644 index 0000000..a3f4e32 --- /dev/null +++ b/studio/src/change_tracking.rs @@ -0,0 +1,77 @@ +use bevy::prelude::*; + +pub struct ChangeTrackingPlugin; + +impl Plugin for ChangeTrackingPlugin { + fn build(&self, app: &mut App) { + app.add_event::(); + + // Add more of these systems for each component that we want to track + app.add_systems(Update, send_change_events::); + + #[cfg(feature = "wasm")] + app.add_systems( + Update, + wasm::send_change_events::.map(bevy::utils::error), + ); + } +} + +#[derive(Component, Debug)] +pub struct ChangeTracker; + +fn send_change_events( + query: Query, With)>, + mut entity_change_writer: EventWriter, +) { + for entity in query.iter() { + entity_change_writer.send(EntityChangedEvent(entity)); + } +} + +#[derive(Event, Deref)] +pub struct EntityChangedEvent(pub Entity); + +#[cfg(feature = "wasm")] +mod wasm { + use bevy::{prelude::*, window::PrimaryWindow}; + use wasm_bindgen::prelude::wasm_bindgen; + + use crate::wasm; + + use super::ChangeTracker; + + #[wasm_bindgen(typescript_custom_section)] + const ENTITY_CHANGES_EVENT: &str = r#" +export interface EntityChangesEvent extends CustomEvent { + type: "entity-changes"; + detail: string[]; +} + +declare global { + export interface GlobalEventHandlersEventMap { + "entity-changes": EntityChangesEvent; + } +} + "#; + + pub(super) fn send_change_events( + q_changed_ents: Query, With)>, + q_window: Query<&Window, With>, + ) -> Result<(), String> { + if q_changed_ents.is_empty() { + return Ok(()); + } + + let Ok(window) = q_window.get_single() else { + return Ok(()); + }; + + let entities = q_changed_ents + .iter() + .map(|ent| format!("{ent:?}")) + .collect::>(); + + wasm::dispatch_to_js(window, "entity-changes", &entities) + } +} diff --git a/studio/src/lib.rs b/studio/src/lib.rs index da30fb8..48939dd 100644 --- a/studio/src/lib.rs +++ b/studio/src/lib.rs @@ -19,6 +19,7 @@ use wgpu::Extent3d; mod anim; mod bvh; mod camera_controller; +mod change_tracking; mod debug; mod design_system; mod hierarchy; @@ -279,6 +280,8 @@ pub fn start_internal( ..default() }), CommonPlugins, + #[cfg(all(feature = "wasm", feature = "wasm_screenshot"))] + wasm::ScreenshotPlugin, )); if matches!(studio_mode, StudioMode::Editor) { diff --git a/studio/src/scene.rs b/studio/src/scene.rs index 1faaa8c..97575a5 100644 --- a/studio/src/scene.rs +++ b/studio/src/scene.rs @@ -22,7 +22,9 @@ use wasm_bindgen::prelude::wasm_bindgen; use wgpu::{TextureDescriptor, TextureUsages}; use crate::{ + anim::SkeletalJoint, camera_controller::{CameraController, CameraControllerBundle}, + change_tracking::{ChangeTracker, ChangeTrackingPlugin}, debug::DebugPoint, is_headless, is_not_headless, math::{Combinable, Extrema}, @@ -37,6 +39,8 @@ pub struct SceneSpawnerSystem; impl Plugin for ScenePlugin { fn build(&self, app: &mut App) { + app.add_plugins(ChangeTrackingPlugin); + app.insert_resource(ClearColor(Color::hsl(0.0, 0.0, 0.25))) .insert_resource(Msaa::Off) .add_state::() @@ -56,10 +60,15 @@ impl Plugin for ScenePlugin { .add_systems( OnEnter(SceneState::Active), ( - tag_scene_elements, - frame_scene_in_view, - start_capture.run_if(is_headless), + ( + tag_scene_elements, + frame_scene_in_view, + start_capture.run_if(is_headless), + ), + apply_deferred, + track_scene_elements, ) + .chain() .in_set(SceneSpawnerSystem), ); @@ -234,6 +243,7 @@ fn initialize(mut cmd: Commands) { cmd.spawn(( Name::new("Main Camera"), MainCamera, + ChangeTracker, Camera3dBundle { transform: camera_xform, tonemapping: Tonemapping::BlenderFilmic, @@ -483,6 +493,15 @@ fn start_capture(mut captures: Query<&mut ScreenCapture>) { } } +fn track_scene_elements( + mut commands: Commands, + scene_elements: Query, With)>, +) { + for element in scene_elements.iter() { + commands.entity(element).insert(ChangeTracker); + } +} + #[cfg(feature = "wasm")] mod wasm { use bevy::{prelude::*, window::PrimaryWindow}; diff --git a/studio/src/wasm/mod.rs b/studio/src/wasm/mod.rs index 751854a..6ec32e2 100644 --- a/studio/src/wasm/mod.rs +++ b/studio/src/wasm/mod.rs @@ -4,9 +4,13 @@ use parking_lot::ReentrantMutex; use wasm_bindgen::prelude::wasm_bindgen; mod conv; +#[cfg(feature = "wasm_screenshot")] +mod screenshot; mod util; pub use conv::*; +#[cfg(feature = "wasm_screenshot")] +pub use screenshot::ScreenshotPlugin; pub(crate) use util::*; static INITIALIZED: OnceLock>> = OnceLock::new(); diff --git a/studio/src/wasm/screenshot.rs b/studio/src/wasm/screenshot.rs new file mode 100644 index 0000000..b4141c4 --- /dev/null +++ b/studio/src/wasm/screenshot.rs @@ -0,0 +1,161 @@ +//! Outline of the flow of events here: +//! +//! 1. [`crate::change_tracking`] system sends events to frontend to notify of +//! tracked changes +//! 2. Frontend calls [`request_screenshot`] on a debounce, writing an empty +//! message to [`SCREENSHOT_REQUEST`] +//! 3. [`take_screenshots`] watches the [`SCREENSHOT_REQUEST`] buffer and +//! populates the [`SCREENSHOT`] buffer with a PNG-encoded `Vec` +//! 4. [`send_screenshots`] watches the [`SCREENSHOT`] buffer and sends an event +//! to the frontend by converting the `Vec` to a [`js_sys::Uint8Array`] + +use bevy::{prelude::*, render::view::screenshot::ScreenshotManager, window::PrimaryWindow}; +use image::{codecs::png::PngEncoder, ColorType, ImageEncoder}; +use wasm_bindgen::prelude::{wasm_bindgen, JsValue}; + +use super::{AsJsValue, StaticBuffer, WasmMessageBuffer}; + +static SCREENSHOT_REQUEST: WasmMessageBuffer<()> = WasmMessageBuffer::new(); +static SCREENSHOT: WasmMessageBuffer = WasmMessageBuffer::new(); + +pub struct ScreenshotPlugin; + +impl Plugin for ScreenshotPlugin { + fn build(&self, app: &mut App) { + app.add_systems( + Update, + ( + take_screenshots.map(bevy::utils::error), + send_screenshots.map(bevy::utils::error), + ), + ); + } +} + +#[wasm_bindgen] +#[derive(Clone)] +pub struct Screenshot { + data_pvt: js_sys::Uint8Array, + pub width: usize, + pub height: usize, +} + +// This intermediate type is necessary because the `Screenshot` struct +// cannot be safely stored in a `WasmMessageBuffer` +struct ScreenshotNative { + data: Vec, + width: usize, + height: usize, +} + +impl From for Screenshot { + fn from(value: ScreenshotNative) -> Self { + Self { + data_pvt: js_sys::Uint8Array::from(&value.data[..]), + width: value.width, + height: value.height, + } + } +} + +#[wasm_bindgen] +impl Screenshot { + #[wasm_bindgen(getter)] + pub fn data(&self) -> js_sys::Uint8Array { + self.data_pvt.clone() + } +} + +impl AsJsValue for Screenshot { + fn as_js(&self) -> Result { + Ok(JsValue::from(self.clone())) + } +} + +#[wasm_bindgen(js_name = requestScreenshot)] +pub fn request_screenshot() { + SCREENSHOT_REQUEST.write_message(()); +} + +fn take_screenshots( + mut r_screenshot_mgr: ResMut, + q_window: Query>, +) -> Result<(), String> { + if SCREENSHOT_REQUEST.take_message().is_none() { + return Ok(()); + } + + let Ok(window_ent) = q_window.get_single() else { + return Ok(()); + }; + + r_screenshot_mgr + .take_screenshot(window_ent, |img| { + let img = match img.try_into_dynamic().map(|img| img.to_rgb8()) { + Ok(img) => img, + Err(err) => { + error!("{err}"); + return; + } + }; + + let channel_count = as image::Pixel>::CHANNEL_COUNT as usize; + let buffer_len = match Some(channel_count) + .and_then(|size| size.checked_mul(img.width() as usize)) + .and_then(|size| size.checked_mul(img.height() as usize)) + { + Some(size) => size, + None => { + error!("Failed to compute buffer length for image!"); + return; + } + }; + let src_buffer = &img.as_raw()[..buffer_len]; + + let mut png_bytes = vec![]; + if let Err(err) = PngEncoder::new(&mut png_bytes).write_image( + src_buffer, + img.width(), + img.height(), + ColorType::Rgb8, + ) { + error!("{err}"); + return; + } + + SCREENSHOT.write_message(ScreenshotNative { + data: png_bytes, + width: img.width() as usize, + height: img.height() as usize, + }); + }) + .map_err(|err| format!("{err}")) +} + +#[wasm_bindgen(typescript_custom_section)] +const SCREENSHOT_READY_EVENT: &str = r#" +export interface ScreenshotReadyEvent extends CustomEvent { + type: "screenshot-ready"; + detail: Screenshot; +} + +declare global { + export interface GlobalEventHandlersEventMap { + "screenshot-ready": ScreenshotReadyEvent; + } +} + "#; + +fn send_screenshots(q_window: Query<&Window, With>) -> Result<(), String> { + let Some(screenshot) = SCREENSHOT.take_message() else { + return Ok(()); + }; + + let Ok(window) = q_window.get_single() else { + return Ok(()); + }; + + let screenshot = Screenshot::from(screenshot); + + super::dispatch_to_js(window, "screenshot-ready", &screenshot) +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 2d911b3..7cab5a6 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -17,12 +17,19 @@ "paths": { "@storyteller/framework": ["framework/src/index.ts"], "@storyteller/studio": ["dist/studio"], + "@storyteller/studio-ui": ["studio-ui/src/index.ts"], + "@storyteller/studio-ui/button": ["studio-ui/src/lib/button.element.ts"], + "@storyteller/studio-ui/icon": ["studio-ui/src/lib/icon.element.ts"], + "@storyteller/studio-ui/toolbar": ["studio-ui/src/lib/toolbar.element.ts"], + "@storyteller/studio-ui/tree": ["studio-ui/src/lib/tree.element.ts"], "@storyteller/studio-web": ["studio-web/src/index.ts"], "@storyteller/studio-web/canvas-provider": ["studio-web/src/lib/canvas-provider.element.ts"], "@storyteller/studio-web/viewer": ["studio-web/src/lib/viewer.element.ts"], "@storyteller/studio-web/bvh-viewer": ["studio-web/src/lib/bvh-viewer.element.ts"], "@storyteller/studio-web/editor": ["studio-web/src/lib/editor.element.ts"], "@storyteller/studio-web/mixamo-viewer": ["studio-web/src/lib/mixamo-viewer.element.ts"], + "@storyteller/studio-web/scene-hierarchy": ["studio-web/src/lib/scene-hierarchy.element.ts"], + "@storyteller/studio-web/transform-toolbar": ["studio-web/src/lib/transform-toolbar.element.ts"], "@storyteller/utility": ["utility/src/index.ts"] } }, diff --git a/vite-multiple-assets/README.md b/vite-multiple-assets/README.md new file mode 100644 index 0000000..d5b41a7 --- /dev/null +++ b/vite-multiple-assets/README.md @@ -0,0 +1,5 @@ +# vite-multiple-assets + +This is a simple Vite plugin forked from [`vite-multiple-assets`](https://github.com/nguyenbatranvan/vite-multiple-assets) +and extended to provide MIME types for additional filetypes not commonly used on +the web, but needed for a Bevy 3D application. diff --git a/vite-multiple-assets/package.json b/vite-multiple-assets/package.json new file mode 100644 index 0000000..96542b9 --- /dev/null +++ b/vite-multiple-assets/package.json @@ -0,0 +1,6 @@ +{ + "name": "@storyteller/vite-multiple-assets", + "version": "0.0.1", + "dependencies": {}, + "main": "./src/index.js" +} diff --git a/vite-multiple-assets/project.json b/vite-multiple-assets/project.json new file mode 100644 index 0000000..6a6bcf7 --- /dev/null +++ b/vite-multiple-assets/project.json @@ -0,0 +1,8 @@ +{ + "name": "vite-multiple-assets", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "projectType": "library", + "sourceRoot": "vite-multiple-assets/src", + "targets": {}, + "tags": [] +} diff --git a/vite-multiple-assets/src/index.ts b/vite-multiple-assets/src/index.ts new file mode 100644 index 0000000..2e13364 --- /dev/null +++ b/vite-multiple-assets/src/index.ts @@ -0,0 +1,16 @@ +import { PluginOption, ViteDevServer } from "vite"; + +import { ServerMiddleWare } from "./lib/server"; +import { buildMiddleWare } from "./lib/build"; + +export default function DynamicPublicDirectory(assets: string[]): PluginOption { + return { + configureServer(server: ViteDevServer) { + return ServerMiddleWare(server, assets) + }, + async writeBundle(options) { + buildMiddleWare(options, assets) + }, + name: "dynamic assets" + }; +} diff --git a/vite-multiple-assets/src/lib/build.ts b/vite-multiple-assets/src/lib/build.ts new file mode 100644 index 0000000..31d30a4 --- /dev/null +++ b/vite-multiple-assets/src/lib/build.ts @@ -0,0 +1,25 @@ +import fs from "fs"; +import { NormalizedOutputOptions } from "rollup"; + +function copyRecursively(src: string, dst: string) { + if (fs.statSync(src).isDirectory()) { + // folder + if (!fs.existsSync(dst)) { + fs.mkdirSync(dst); + } + for (const file of fs.readdirSync(src)) { + copyRecursively(src + "/" + file, dst + "/" + file); + } + } else { + // file + fs.copyFileSync(src, dst); + } +} + +export function buildMiddleWare(options: NormalizedOutputOptions, assets: string[] = []) { + const dst = options.dir; + if (!dst) throw new Error("options.dir is undefined"); + for (const dir of assets) { + copyRecursively(dir, dst) + } +} diff --git a/vite-multiple-assets/src/lib/server.ts b/vite-multiple-assets/src/lib/server.ts new file mode 100644 index 0000000..996bd5e --- /dev/null +++ b/vite-multiple-assets/src/lib/server.ts @@ -0,0 +1,93 @@ +import fs from "fs"; +import path from "path"; +import { ViteDevServer } from "vite"; + +interface IPropsFile { + name: string; + files: string[]; +} + +function getFiles(dir, files_): string[] { + files_ = files_ || []; + const files = fs.readdirSync(dir); + for (const i in files) { + const name = dir + "/" + files[i]; + if (fs.statSync(name).isDirectory()) { + getFiles(name, files_); + } else { + files_.push(name); + } + } + return files_; +} + +const mimeTypes = { + ".7z": "application/x-7z-compressed", + ".bin": "application/octet-stream", + ".bvh": "text/bvh", + ".css": "text/css", + ".eot": "font/eot", + ".gif": "image/gif", + ".glb": "model/gltf-binary", + ".gltf": "model/gltf+json", + ".gz": "application/gzip", + ".hdr": "image/vnd.radiance", + ".html": "text/html", + ".ico": "image/x-icon", + ".jpg": "image/jpeg", + ".js": "text/javascript", + ".json": "application/json", + ".ktx": "image/ktx", + ".ktx2": "image/ktx", + ".meta": "text/plain", + ".mjs": "text/javascript", + ".mp3": "audio/mpeg", + ".mp4": "video/mp4", + ".otf": "font/otf", + ".png": "image/png", + ".rar": "application/x-rar-compressed", + ".svg": "image/svg+xml", + ".tiff": "image/tiff", + ".ttf": "font/ttf", + ".txt": "text/plain", + ".wasm": "application/wasm", + ".webm": "video/webm", + ".webp": "image/webp", + ".wgsl": "text/wgsl", + ".woff": "font/woff", + ".woff2": "font/woff2", + ".xml": "text/xml", + ".zip": "application/zip", +} + +export function ServerMiddleWare(server: ViteDevServer, assets: string[] = []) { + if (!assets || !assets.length) + return; + + const fileObject: IPropsFile[] = []; + for (let i = 0; i < assets.length; i++) { + const files = getFiles(path.join(process.cwd(), `/${assets[i]}`), []); + fileObject.push({ + name: assets[i], + files + }); + } + + return () => { + server.middlewares.use(async (req, res, next) => { + for (let i = 0; i < fileObject.length; i++) { + const file = path.join(process.cwd(), `${fileObject[i].name}/${req.originalUrl}`); + if (fileObject[i].files.some(f => path.relative(f, file) === "")) { + const extension = file.substring(file.lastIndexOf(".")); + res.setHeader("Cache-Control", "max-age=31536000, immutable"); + res.setHeader("Content-Type", mimeTypes[extension]); + res.writeHead(200); + res.write(fs.readFileSync(path.join(process.cwd(), "/" + fileObject[i].name + req.originalUrl))); + res.end(); + break; + } + } + next(); + }); + }; +} diff --git a/vite-multiple-assets/tsconfig.json b/vite-multiple-assets/tsconfig.json new file mode 100644 index 0000000..a99bedc --- /dev/null +++ b/vite-multiple-assets/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "strict": true, + "noImplicitAny": false, + "skipLibCheck": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/vite-multiple-assets/tsconfig.lib.json b/vite-multiple-assets/tsconfig.lib.json new file mode 100644 index 0000000..4d90bb1 --- /dev/null +++ b/vite-multiple-assets/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node", "vite/client"] + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/vite-multiple-assets/tsconfig.spec.json b/vite-multiple-assets/tsconfig.spec.json new file mode 100644 index 0000000..d231383 --- /dev/null +++ b/vite-multiple-assets/tsconfig.spec.json @@ -0,0 +1,25 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ] + }, + "include": [ + "vite.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} From c788bcf6b7642775332939669e94b7ca3e922171 Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Tue, 27 Feb 2024 12:22:00 -0500 Subject: [PATCH 07/13] Refactor Studio entry-points (#54) This PR heavily refactors the entry-point functions in `studio/src/lib.rs` to simplify and consolidate. Additionally, the frontend application should now be configurable as expected with any valid combination of the following URL parameters: * `objectId` : A pre-bundled library object to load (e.g., "couch.gltf") * `bvh` : Any resolvable path to a BVH animation with a MocapNET skeleton (e.g., "mocap/shuffle.bvh") * `mixamo` : Any resolvable path to a glTF animation with the Mixamo skeleton (e.g., "mocap/hip-hop-dancing.gltf") * `sceneImport` : Any resolvable path to an arbitrary glTF scene (untested, but should theoretically work) * `scene` : Any resolvable path to a previously saved Storyteller Studio scene in `*.scn.ron` format * `skybox` : The ID of a pre-bundled skybox asset. Valid options are: - "gum_trees_4k" - "kloofenfal_28d_misty_4k" - "meadow_4k" - "promenade_de_vidy_4k" - "scythian_tombs_4k" - "test_scene" (this is the default if not specified) * `mode` : One of "studio" or "viewer" (the default if not specified) "Validity" rules are as follows: * `objectId`, `bvh`, `mixamo`, `sceneImport` and `scene` are mutually exclusive * `skybox` is not supported for `scene` (the skybox should be saved and loaded as part of the scene description, though this is not currently working) * Both `mode` options are valid for all other parameters --- Cargo.lock | 78 ++-- image-generator-demo/src/app/app.element.ts | 12 +- studio-frontend/src/app/app.element.ts | 35 +- studio-web/src/index.ts | 5 +- studio-web/src/lib/bvh-viewer.element.ts | 34 -- studio-web/src/lib/editor.element.ts | 28 -- studio-web/src/lib/mixamo-viewer.element.ts | 34 -- ...-base.element.scss => studio.element.scss} | 0 ...udio-base.element.ts => studio.element.ts} | 57 ++- studio-web/src/lib/url-params.ts | 13 +- studio-web/src/lib/viewer.element.ts | 42 -- studio/Cargo.toml | 1 + studio/src/headless.rs | 165 ++++++++ studio/src/lib.rs | 388 ++++-------------- studio/src/main-headless.rs | 2 +- studio/src/main.rs | 20 +- studio/src/scene.rs | 31 +- studio/src/viewport.rs | 3 +- studio/src/wasm/init.rs | 164 ++++++++ studio/src/wasm/mod.rs | 1 + tsconfig.base.json | 5 +- 21 files changed, 564 insertions(+), 554 deletions(-) delete mode 100644 studio-web/src/lib/bvh-viewer.element.ts delete mode 100644 studio-web/src/lib/editor.element.ts delete mode 100644 studio-web/src/lib/mixamo-viewer.element.ts rename studio-web/src/lib/{studio-base.element.scss => studio.element.scss} (100%) rename studio-web/src/lib/{studio-base.element.ts => studio.element.ts} (58%) delete mode 100644 studio-web/src/lib/viewer.element.ts create mode 100644 studio/src/headless.rs create mode 100644 studio/src/wasm/init.rs diff --git a/Cargo.lock b/Cargo.lock index c46c87c..a514c1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -431,7 +431,7 @@ checksum = "5ec77479f56958ed1b2802c3129ebc704d12245627b2d4dae61f11e6ed5c21b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -531,7 +531,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -606,7 +606,7 @@ checksum = "f484318350462c58ba3942a45a656c1fd6b6e484a6b6b7abc3a787ad1a51e500" dependencies = [ "bevy_macro_utils", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -664,7 +664,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -720,7 +720,7 @@ checksum = "c6a13f388de6f4e809c15130c3251f60921ab4d0db37cc9ccce36f2296eeb73d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -882,7 +882,7 @@ dependencies = [ "proc-macro2", "quote", "rustc-hash", - "syn 2.0.37", + "syn 2.0.51", "toml_edit 0.20.7", ] @@ -1184,7 +1184,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", "uuid", ] @@ -1243,7 +1243,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -1413,7 +1413,7 @@ checksum = "7aafecc952b6b8eb1a93c12590bd867d25df2f4ae1033a01dfdfc3c35ebccfff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -1495,7 +1495,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e1ef1d5e328abe1b76df974245f78e17fd17867583883d5e77444c6a8223a64" dependencies = [ "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -1515,7 +1515,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -1660,7 +1660,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -1760,7 +1760,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -2235,7 +2235,7 @@ checksum = "3fe2568f851fd6144a45fa91cfed8fe5ca8fc0b56ba6797bfc1ed2771b90e37c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -2410,7 +2410,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -2535,7 +2535,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -2699,7 +2699,7 @@ dependencies = [ "inflections", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -2936,7 +2936,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.5.4", "tokio", "tower-service", "tracing", @@ -3735,7 +3735,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -3873,7 +3873,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -4013,7 +4013,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -4125,9 +4125,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -4149,9 +4149,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -4521,7 +4521,7 @@ checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -4535,6 +4535,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.51", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -4820,6 +4831,7 @@ dependencies = [ "serde", "serde-wasm-bindgen", "serde_json", + "serde_repr", "space_editor", "studio-bvh", "wasm-bindgen", @@ -4856,9 +4868,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" dependencies = [ "proc-macro2", "quote", @@ -4983,7 +4995,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -5116,7 +5128,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] @@ -5349,7 +5361,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", "wasm-bindgen-shared", ] @@ -5383,7 +5395,7 @@ checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5991,7 +6003,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.51", ] [[package]] diff --git a/image-generator-demo/src/app/app.element.ts b/image-generator-demo/src/app/app.element.ts index 7f0b042..e8f2dc6 100644 --- a/image-generator-demo/src/app/app.element.ts +++ b/image-generator-demo/src/app/app.element.ts @@ -6,17 +6,15 @@ import { type ScreenshotReadyEvent, StudioMode, } from "@storyteller/studio"; -import { StudioURLParams, ViewerElement } from "@storyteller/studio-web"; import { match } from "@storyteller/utility"; import { LitElement, html, nothing } from "lit"; import { customElement, state } from "lit/decorators.js"; -import { createRef, ref } from "lit/directives/ref.js"; import { DebounceSettings, debounce } from "lodash"; import "@storyteller/studio-web/canvas-provider"; import "@storyteller/studio-web/scene-hierarchy"; +import "@storyteller/studio-web/studio"; import "@storyteller/studio-web/transform-toolbar"; -import "@storyteller/studio-web/viewer"; import "./app.element.scss" @@ -44,9 +42,6 @@ export class AppElement extends LitElement { @state() imageCaptureUrl?: string; @state() realtimeCapture = true; - params = new StudioURLParams(); - viewer = createRef(); - protected override createRenderRoot = () => this; override disconnectedCallback(): void { @@ -95,13 +90,12 @@ export class AppElement extends LitElement { protected override render = () => html` - + > ${this.imageCaptureUrl != null ? html` - ${this.#params.bvh ? html` - - ` : this.#params.mixamo ? html` - - ` : this.#params.scene ? html` - - ` : html` - - `} + diff --git a/studio-web/src/index.ts b/studio-web/src/index.ts index fc74141..e97dae9 100644 --- a/studio-web/src/index.ts +++ b/studio-web/src/index.ts @@ -1,8 +1,5 @@ -export * from "./lib/bvh-viewer.element"; export * from "./lib/canvas-provider.element"; -export * from "./lib/editor.element"; -export * from "./lib/mixamo-viewer.element"; export * from "./lib/scene-hierarchy.element"; +export * from "./lib/studio.element"; export * from "./lib/transform-toolbar.element"; export * from "./lib/url-params"; -export * from "./lib/viewer.element"; diff --git a/studio-web/src/lib/bvh-viewer.element.ts b/studio-web/src/lib/bvh-viewer.element.ts deleted file mode 100644 index d81f0d3..0000000 --- a/studio-web/src/lib/bvh-viewer.element.ts +++ /dev/null @@ -1,34 +0,0 @@ -import * as studio from "@storyteller/studio"; -import { ViewportSize } from "@storyteller/studio"; -import { customElement, property } from "lit/decorators.js"; - -import { StudioBaseElement } from "./studio-base.element"; -import { PropertyValues } from "lit"; - -@customElement("sts-bvh-viewer") -export class BvhViewerElement extends StudioBaseElement { - @property() bvhPath?: string; - @property() skyboxId?: string; - - onStart(viewportSize: ViewportSize): void { - if (!this.bvhPath) return; - if (!this.skyboxId) return; - - studio.startBvhViewer( - this.bvhPath, - this.skyboxId, - `#${this._canvasProvider!.canvasId}`, - "Storyteller Studio", - viewportSize, - ); - } - - onChanges(changes: PropertyValues): void { - if (changes.has("bvhPath") && !!this.bvhPath) { - // TODO - } - - if (changes.has("skyboxId") && !!this.skyboxId) - studio.setSkybox(this.skyboxId); - } -} diff --git a/studio-web/src/lib/editor.element.ts b/studio-web/src/lib/editor.element.ts deleted file mode 100644 index 19a22a1..0000000 --- a/studio-web/src/lib/editor.element.ts +++ /dev/null @@ -1,28 +0,0 @@ -import * as studio from "@storyteller/studio"; -import { ViewportSize } from "@storyteller/studio"; -import { PropertyValues } from "lit"; -import { customElement, property } from "lit/decorators.js"; - -import { StudioBaseElement } from "./studio-base.element"; - -@customElement("sts-editor") -export class EditorElement extends StudioBaseElement { - @property() scenePath?: string; - - onStart(viewportSize: ViewportSize): void { - if (!this.scenePath) return; - - studio.startEditor( - this.scenePath, - `#${this._canvasProvider!.canvasId}`, - "Storyteller Studio", - viewportSize, - ); - } - - onChanges(changes: PropertyValues): void { - if (changes.has("scenePath") && !!this.scenePath) { - // TODO - } - } -} diff --git a/studio-web/src/lib/mixamo-viewer.element.ts b/studio-web/src/lib/mixamo-viewer.element.ts deleted file mode 100644 index d3c96f8..0000000 --- a/studio-web/src/lib/mixamo-viewer.element.ts +++ /dev/null @@ -1,34 +0,0 @@ -import * as studio from "@storyteller/studio"; -import { ViewportSize } from "@storyteller/studio"; -import { PropertyValues } from "lit"; -import { customElement, property } from "lit/decorators.js"; - -import { StudioBaseElement } from "./studio-base.element"; - -@customElement("sts-mixamo-viewer") -export class MixamoViewerElement extends StudioBaseElement { - @property() mixamoPath?: string; - @property() skyboxId?: string; - - onStart(viewportSize: ViewportSize): void { - if (!this.mixamoPath) return; - if (!this.skyboxId) return; - - studio.startMixamoViewer( - this.mixamoPath, - this.skyboxId, - `#${this._canvasProvider!.canvasId}`, - "Storyteller Studio", - viewportSize, - ); - } - - onChanges(changes: PropertyValues): void { - if (changes.has("mixamoPath") && !!this.mixamoPath) { - // TODO - } - - if (changes.has("skyboxId") && !!this.skyboxId) - studio.setSkybox(this.skyboxId); - } -} diff --git a/studio-web/src/lib/studio-base.element.scss b/studio-web/src/lib/studio.element.scss similarity index 100% rename from studio-web/src/lib/studio-base.element.scss rename to studio-web/src/lib/studio.element.scss diff --git a/studio-web/src/lib/studio-base.element.ts b/studio-web/src/lib/studio.element.ts similarity index 58% rename from studio-web/src/lib/studio-base.element.ts rename to studio-web/src/lib/studio.element.ts index 6d49d96..63881b5 100644 --- a/studio-web/src/lib/studio-base.element.ts +++ b/studio-web/src/lib/studio.element.ts @@ -1,16 +1,28 @@ import { inject } from "@storyteller/framework"; import * as studio from "@storyteller/studio"; -import { ViewportSize } from "@storyteller/studio"; -import { LitElement, PropertyValues, html, unsafeCSS } from "lit"; - +import { + type InitOptions, + type SkyboxId, + StudioMode, + ViewportSize, +} from "@storyteller/studio"; +import { LitElement, type PropertyValues, html, unsafeCSS } from "lit"; +import { customElement, property } from "lit/decorators.js"; import { CANVAS_PROVIDER, type CanvasProvider } from "./canvas-provider.element"; -import styles from "./studio-base.element.scss?inline"; +import styles from "./studio.element.scss?inline"; -export abstract class StudioBaseElement extends LitElement { +@customElement("sts-studio") +export class StudioElement extends LitElement { static override styles = unsafeCSS(styles); - get canvas() { return this.#canvas; } + @property() objectId?: string; + @property() bvhPath?: string; + @property() mixamoPath?: string; + @property() sceneImport?: string; + @property() storytellerScene?: string; + @property() skyboxId?: SkyboxId; + @property({ type: Number }) mode?: StudioMode; @inject(CANVAS_PROVIDER) _canvasProvider?: CanvasProvider; @@ -19,9 +31,6 @@ export abstract class StudioBaseElement extends LitElement { #resizeObserver?: ResizeObserver; #frameRequest?: number; - abstract onStart(viewportSize: ViewportSize): void; - abstract onChanges?(changes: PropertyValues): void; - override connectedCallback(): void { super.connectedCallback(); @@ -53,7 +62,7 @@ export abstract class StudioBaseElement extends LitElement { if (!studio.isInitialized()) { this.#start(); } else { - this.onChanges?.(changes); + // TODO } } @@ -75,10 +84,36 @@ export abstract class StudioBaseElement extends LitElement { #start(): void { if (!this.#canvas) return; + if (this.mode == null) return; const { width, height } = this.getBoundingClientRect(); + const options: InitOptions = { + mode: this.mode, + canvasSelector: `#${this._canvasProvider?.canvasId}`, + canvasAlt: "Storyteller Studio", + viewportSize: new ViewportSize(width, height), + }; + try { - this.onStart(new ViewportSize(width, height)); + if ( + this.skyboxId + && (this.objectId || this.bvhPath || this.mixamoPath || this.sceneImport) + ) { + options.skyboxId = this.skyboxId; + + if (this.objectId) { + studio.initFromLibrary(this.objectId, options); + } else if (this.bvhPath) { + studio.initFromBvh(this.bvhPath, options); + } else if (this.mixamoPath) { + studio.initFromMixamo(this.mixamoPath, options); + } else if (this.sceneImport) { + studio.initFromSceneImport(this.sceneImport, options); + } + } + else if (this.storytellerScene) { + studio.initFromStorytellerScene(this.storytellerScene, options); + } } catch (err) { if (!(err as Error).message?.startsWith("Using exceptions for control flow")) throw err; diff --git a/studio-web/src/lib/url-params.ts b/studio-web/src/lib/url-params.ts index a8e449a..8135957 100644 --- a/studio-web/src/lib/url-params.ts +++ b/studio-web/src/lib/url-params.ts @@ -1,4 +1,4 @@ -import { StudioMode } from "@storyteller/studio"; +import { type SkyboxId, StudioMode } from "@storyteller/studio"; import { match } from "@storyteller/utility"; export class StudioURLParams { @@ -7,9 +7,14 @@ export class StudioURLParams { return this.#_nativeParams ??= new URLSearchParams(document.location.search); } - get bvh() { return this.#nativeParams.get("bvh"); } - get mixamo() { return this.#nativeParams.get("mixamo"); } - get scene() { return this.#nativeParams.get("scene"); } + get objectId() { return this.#nativeParams.get("objectId") ?? undefined; } + get bvh() { return this.#nativeParams.get("bvh") ?? undefined; } + get mixamo() { return this.#nativeParams.get("mixamo") ?? undefined; } + get sceneImport() { return this.#nativeParams.get("sceneImport") ?? undefined; } + get scene() { return this.#nativeParams.get("scene") ?? undefined; } + get skybox() { + return this.#nativeParams.get("skybox") as SkyboxId ?? undefined; + } get mode(): StudioMode { return match(this.#nativeParams.get("mode"), { "studio": () => StudioMode.Editor, diff --git a/studio-web/src/lib/viewer.element.ts b/studio-web/src/lib/viewer.element.ts deleted file mode 100644 index ec72727..0000000 --- a/studio-web/src/lib/viewer.element.ts +++ /dev/null @@ -1,42 +0,0 @@ -import * as studio from "@storyteller/studio"; -import { StudioMode, ViewportSize } from "@storyteller/studio"; -import { PropertyValues } from "lit"; -import { customElement, property } from "lit/decorators.js"; - -import { StudioBaseElement } from "./studio-base.element"; - -@customElement("sts-viewer") -export class ViewerElement extends StudioBaseElement { - @property() objectId?: string; - @property() skyboxId?: string; - @property({ type: Number }) mode?: StudioMode; - - onStart(viewportSize: ViewportSize): void { - if (!this.objectId) return; - if (!this.skyboxId) return; - if (this.mode == null) return; - - studio.start( - this.objectId, - this.skyboxId, - `#${this._canvasProvider!.canvasId}`, - "Storyteller Studio", - viewportSize, - this.mode, - ); - } - - onChanges(changes: PropertyValues): void { - if (changes.has("objectId") && !!this.objectId) - studio.loadObject(this.objectId); - - if (changes.has("skyboxId") && !!this.skyboxId) - studio.setSkybox(this.skyboxId); - } -} - -declare global { - export interface HTMLElementTagNameMap { - "sts-viewer": ViewerElement; - } -} diff --git a/studio/Cargo.toml b/studio/Cargo.toml index 3892c64..8303db2 100644 --- a/studio/Cargo.toml +++ b/studio/Cargo.toml @@ -48,6 +48,7 @@ image = "0.24.8" bytemuck = "1.14.1" space_editor = {git = "https://github.com/rewin123/space_editor", rev = "ce83f86dc902787ab16213f3209276a784654df6"} anyhow.workspace = true +serde_repr = "0.1.18" [dependencies.reqwest] version = "0.11.24" diff --git a/studio/src/headless.rs b/studio/src/headless.rs new file mode 100644 index 0000000..3b4d1de --- /dev/null +++ b/studio/src/headless.rs @@ -0,0 +1,165 @@ +use std::time::Duration; + +use bevy::{ + app::{AppExit, ScheduleRunnerPlugin}, + prelude::*, +}; +use space_editor::prelude::{EditorEvent, EditorPrefabPath}; +use wgpu::Extent3d; + +use crate::{ + bvh::{BvhAnimCompleteEvent, TestBvh}, + screenshot::{ScreenCapture, ScreenShotPlugin}, + BvhPlugin, CommonPlugins, LoadLibraryObjectEvent, LoadSceneEvent, MainCamera, + MixamoImportEvent, MixamoPlugin, SkyboxId, StudioMode, WorldGridPlugin, +}; + +#[derive(Debug, Resource, Clone)] +pub enum HeadlessMode { + Bvh(String, String), + Scene(String, String), + Mixamo(String, String), + None, +} + +pub fn start_headless( + mode: HeadlessMode, + fps: u32, + outout_dir: &str, + frames_to_capture: u32, + image_res: Extent3d, +) -> App { + let mut app = App::new(); + + app.insert_resource(mode.clone()); + app.insert_resource(StudioMode::Headless); + app.insert_resource(HeadlessSettings { + max_frames: frames_to_capture, + output_dims: image_res, + output_dir: outout_dir.to_string(), + }); + + app.add_plugins(( + ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1.0 / fps as f64)), + DefaultPlugins.set(WindowPlugin { + primary_window: None, + exit_condition: bevy::window::ExitCondition::DontExit, + close_when_requested: true, + }), + ScreenShotPlugin, + CommonPlugins.build().disable::(), + )); + + match mode { + HeadlessMode::Bvh(bvh_dir, skybox) => { + app.add_plugins(BvhPlugin); + app.add_systems( + Startup, + move |mut cmd: Commands, + asset_server: Res, + mut ew: EventWriter| { + cmd.insert_resource(SkyboxId(skybox.clone())); + cmd.insert_resource(TestBvh(asset_server.load(bvh_dir.clone()))); + ew.send(LoadLibraryObjectEvent("Mannequin.gltf".to_string())); + }, + ); + + app.add_systems(PostUpdate, check_for_bvh_capture_complete); + } + HeadlessMode::Scene(scene, skybox) => { + app.add_systems( + Startup, + move |mut cmd: Commands, mut ew: EventWriter| { + cmd.insert_resource(SkyboxId(skybox.clone())); + ew.send(EditorEvent::Load(EditorPrefabPath::File(scene.clone()))) + }, + ); + } + HeadlessMode::Mixamo(mixamo_path, skybox) => { + app.add_plugins(MixamoPlugin); + app.add_systems( + Startup, + move |mut commands: Commands, + mut ew: EventWriter, + mut load_scene_event: EventWriter| { + ew.send(MixamoImportEvent(mixamo_path.clone())); + load_scene_event.send(LoadSceneEvent("Mannequin.gltf".to_string())); + commands.insert_resource(SkyboxId(skybox.clone())); + }, + ); + app.add_systems(PostUpdate, check_for_mixamo_capture_complete); + + app.run(); + } + HeadlessMode::None => {} + } + + app +} + +pub fn is_headless(studio_state: Res) -> bool { + *studio_state == StudioMode::Headless +} + +pub fn is_not_headless(studio_state: Res) -> bool { + *studio_state != StudioMode::Headless +} + +#[derive(Resource)] +pub struct HeadlessSettings { + pub output_dims: Extent3d, + pub output_dir: String, + pub max_frames: u32, +} + +impl Default for HeadlessSettings { + fn default() -> Self { + HeadlessSettings { + output_dims: Extent3d { + width: 1280, + height: 720, + depth_or_array_layers: 1, + }, + output_dir: "./screen_shots/".to_string(), + max_frames: u32::MAX, + } + } +} + +fn check_for_bvh_capture_complete( + mut close_app: EventWriter, + mut main_camera: Query<&mut ScreenCapture, With>, + bvh_event_reader: EventReader, +) { + let Ok(mut screen_capture) = main_camera.get_single_mut() else { + return; + }; + + println!("Frames captured {}", screen_capture.frames_captured()); + if !screen_capture.should_capture() || !bvh_event_reader.is_empty() { + screen_capture.stop_capturing(); + close_app.send(AppExit); + } +} + +fn check_for_mixamo_capture_complete( + mut close_app: EventWriter, + mut main_camera: Query<&mut ScreenCapture, With>, + mixamo_anims: Query<&AnimationPlayer>, +) { + let Ok(mut capture) = main_camera.get_single_mut() else { + return; + }; + + for anim in mixamo_anims.iter() { + println!( + "Time elapsed {} | Frames Captured : {}", + anim.elapsed(), + capture.frames_captured() + ); + if anim.completions() != 0 { + capture.stop_capturing(); + close_app.send(AppExit); + } + } +} diff --git a/studio/src/lib.rs b/studio/src/lib.rs index 48939dd..560a707 100644 --- a/studio/src/lib.rs +++ b/studio/src/lib.rs @@ -1,20 +1,14 @@ #![allow(clippy::type_complexity, clippy::too_many_arguments)] -use std::time::Duration; - -use bevy::{ - app::{AppExit, PluginGroupBuilder, ScheduleRunnerPlugin}, - prelude::*, -}; +use bevy::{app::PluginGroupBuilder, prelude::*}; use bevy_mod_picking::DefaultPickingPlugins; use bevy_web_asset::WebAssetPlugin; -use bvh::{BvhAnimCompleteEvent, TestBvh}; -use screenshot::{ScreenCapture, ScreenShotPlugin}; -use space_editor::prelude::{EditorEvent, EditorPrefabPath}; +use scene::ImportSceneEvent; +#[cfg(feature = "wasm")] +use serde_repr::{Deserialize_repr, Serialize_repr}; #[cfg(feature = "wasm")] use wasm_bindgen::prelude::*; -use wgpu::Extent3d; mod anim; mod bvh; @@ -22,6 +16,7 @@ mod camera_controller; mod change_tracking; mod debug; mod design_system; +pub mod headless; mod hierarchy; mod input; mod inspector; @@ -63,7 +58,12 @@ mod wasm; #[derive(Component)] pub(crate) struct MainCamera; -#[cfg_attr(feature = "wasm", wasm_bindgen)] +#[cfg_attr( + feature = "wasm", + wasm_bindgen, + repr(u8), + derive(Deserialize_repr, Serialize_repr) +)] #[derive(Resource, Clone, Copy, PartialEq, Eq, Debug)] pub enum StudioMode { Editor, @@ -104,166 +104,47 @@ impl PluginGroup for EditorPlugins { } } -#[cfg_attr(feature = "wasm", wasm_bindgen(js_name = startViewer))] -/// Start the application as a read-only viewer for a single library object. -/// -/// @param object_id ID of the library object to load. -/// @param skybox_id ID of the Skybox to use -/// @param canvas_selector A CSS selector for the canvas that will host the Bevy -/// application. This should be unique (i.e. `querySelectorAll` should not -/// return more than one element), so using an ID selector is a good idea. -/// @param canvas_alt `alt` text for the HTML canvas element. -/// @param viewport_size The size of the canvas in CSS `px` units. -pub fn start_viewer( - object_id: &str, - skybox_id: &str, - canvas_selector: &str, - canvas_alt: &str, - viewport_size: ViewportSize, -) { - start_internal( - InitSeed::FromLibrary { - object_id: object_id.into(), - skybox_id: skybox_id.into(), - }, - canvas_selector, - canvas_alt, - viewport_size, - StudioMode::Viewer, - ) - .run(); -} - -#[cfg_attr(feature = "wasm", wasm_bindgen(js_name = startEditor))] -pub fn start_editor( - scene_id: &str, - canvas_selector: &str, - canvas_alt: &str, - viewport_size: ViewportSize, -) { - start_internal( - InitSeed::FromScene(scene_id.into()), - canvas_selector, - canvas_alt, - viewport_size, - StudioMode::Editor, - ) - .run(); -} - -#[cfg_attr(feature = "wasm", wasm_bindgen(js_name = startBvhViewer))] -pub fn start_bvh_viewer( - bvh_path: &str, - skybox_id: &str, - canvas_selector: &str, - canvas_alt: &str, - viewport_size: ViewportSize, -) { - let mut app = start_internal( - InitSeed::FromLibrary { - object_id: "Mannequin.gltf".into(), - skybox_id: skybox_id.into(), - }, - canvas_selector, - canvas_alt, - viewport_size, - StudioMode::Viewer, - ); - - let bvh_path = bvh_path.to_string(); - - app.add_plugins(BvhPlugin); - app.add_systems( - Startup, - move |mut cmd: Commands, r_assets: Res| { - cmd.insert_resource(bvh::TestBvh(r_assets.load(bvh_path.clone()))); - }, - ); - - app.run(); -} - -#[cfg_attr(feature = "wasm", wasm_bindgen(js_name = startMixamoViewer))] -pub fn start_mixamo_viewer( - mixamo_path: &str, - skybox_id: &str, - canvas_selector: &str, - canvas_alt: &str, - viewport_size: ViewportSize, -) { - let mut app = start_internal( - InitSeed::FromLibrary { - object_id: "Mannequin.gltf".into(), - skybox_id: skybox_id.into(), - }, - canvas_selector, - canvas_alt, - viewport_size, - StudioMode::Viewer, - ); - - let mixamo_path = mixamo_path.to_string(); - - app.add_plugins(MixamoPlugin); - app.add_systems(Startup, move |mut ew: EventWriter| { - ew.send(MixamoImportEvent(mixamo_path.clone())); - }); - - app.run(); -} - -#[cfg_attr(feature = "wasm", wasm_bindgen)] -pub fn start( - object_id: &str, - skybox_id: &str, - canvas_selector: &str, - canvas_alt: &str, - viewport_size: ViewportSize, - studio_mode: StudioMode, -) { - start_internal( - InitSeed::FromLibrary { - object_id: object_id.into(), - skybox_id: skybox_id.into(), - }, - canvas_selector, - canvas_alt, - viewport_size, - studio_mode, - ) - .run(); -} - -pub enum InitSeed { - /// Initialize the application from assets in the "bundled" asset library. - FromLibrary { - /// A filename, including the extension, that can be found under - /// `studio/assets/gltf` (e.g., "Mannequin.gltf") - object_id: String, +#[derive(Debug)] +pub enum InitParams { + /// Initialize the application by importing an asset and processing it to + /// work with Storyteller Studio's feature-set. + FromAsset { + asset: InitAsset, /// A skybox name that corresponds to a matching set of assets under /// `studio/assets/skyboxes`, _not_ including file extensions or /// "diffuse"/"specular" qualifiers (e.g., "gum_trees_4k") skybox_id: String, }, - /// Initialize the application by loading a previously saved `*.scn.ron` - /// scene file. + /// Initialize the application by loading a previously saved Storyteller + /// Studio scene. FromScene(String), } -pub fn start_internal( - seed: InitSeed, - canvas_selector: &str, - canvas_alt: &str, - viewport_size: ViewportSize, - studio_mode: StudioMode, -) -> App { +#[derive(Debug)] +pub enum InitAsset { + /// Initialize the application from an asset in the "bundled" asset library. + /// Takes a filename, including the extension, that can be found under + /// `studio/assets/gltf` (e.g., "base-human-female.gltf"). + LibraryObject(String), + /// Initialize the application by loading an arbitrary glTF scene from any + /// source (e.g., the Storyteller.ai backend) + ImportedScene(String), + /// Initialize the application by retargeting a BVH animation (currently + /// only supports the MocapNET skeleton) onto the bundled `Mannequin.gltf` + /// model. + BvhAnim(String), + /// Initialize the application by retargeting a Mixamo animation onto the + /// bundled `Mannequin.gltf` model. + MixamoAnim(String), +} + +pub fn start(init: InitParams, mode: StudioMode, window_config: Option) -> App { #[cfg(feature = "wasm")] console_error_panic_hook::set_once(); let mut app = App::new(); - app.insert_resource(HeadlessMode::None); - app.insert_resource(studio_mode); + app.insert_resource(mode); app.add_plugins(( #[cfg(feature = "wasm")] @@ -271,12 +152,7 @@ pub fn start_internal( WebAssetPlugin, RemoteAssetPlugin, DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - resolution: viewport_size.into(), - title: canvas_alt.into(), - canvas: Some(canvas_selector.into()), - ..default() - }), + primary_window: Some(window_config.unwrap_or_default()), ..default() }), CommonPlugins, @@ -284,7 +160,7 @@ pub fn start_internal( wasm::ScreenshotPlugin, )); - if matches!(studio_mode, StudioMode::Editor) { + if matches!(mode, StudioMode::Editor) { app.add_plugins((DefaultPickingPlugins, EditorPlugins)); // Only for registering components for undo @@ -292,20 +168,11 @@ pub fn start_internal( app.auto_reflected_undo::(); } - match seed { - InitSeed::FromLibrary { - object_id, - skybox_id, - } => { - app.add_systems( - Startup, - move |mut cmd: Commands, mut ew: EventWriter| { - cmd.insert_resource(SkyboxId(skybox_id.clone())); - ew.send(LoadLibraryObjectEvent(object_id.clone())); - }, - ); + match init { + InitParams::FromAsset { asset, skybox_id } => { + init_from_asset(&mut app, asset, skybox_id); } - InitSeed::FromScene(scene) => { + InitParams::FromScene(scene) => { app.add_systems(Startup, move |mut ew: EventWriter| { ew.send(LoadSceneEvent(scene.clone())); }); @@ -318,152 +185,51 @@ pub fn start_internal( app } -#[derive(Debug, Resource, Clone)] -pub enum HeadlessMode { - Bvh(String, String), - Scene(String, String), - Mixamo(String, String), - None, -} - -pub fn start_headless( - mode: HeadlessMode, - fps: u32, - outout_dir: &str, - frames_to_capture: u32, - image_res: Extent3d, -) -> App { - let mut app = App::new(); - - app.insert_resource(mode.clone()); - app.insert_resource(StudioMode::Headless); - app.insert_resource(HeadlessSettings { - max_frames: frames_to_capture, - output_dims: image_res, - output_dir: outout_dir.to_string(), +fn init_from_asset(app: &mut App, asset: InitAsset, skybox_id: String) { + app.add_systems(Startup, move |mut cmd: Commands| { + cmd.insert_resource(SkyboxId(skybox_id.clone())); }); - app.add_plugins(( - ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1.0 / fps as f64)), - DefaultPlugins.set(WindowPlugin { - primary_window: None, - exit_condition: bevy::window::ExitCondition::DontExit, - close_when_requested: true, - }), - ScreenShotPlugin, - CommonPlugins.build().disable::(), - )); - - match mode { - HeadlessMode::Bvh(bvh_dir, skybox) => { - app.add_plugins(BvhPlugin); + match asset { + InitAsset::LibraryObject(id) => { app.add_systems( Startup, - move |mut cmd: Commands, - asset_server: Res, - mut ew: EventWriter| { - cmd.insert_resource(SkyboxId(skybox.clone())); - cmd.insert_resource(TestBvh(asset_server.load(bvh_dir.clone()))); - ew.send(LoadLibraryObjectEvent("Mannequin.gltf".to_string())); - }, - ); - - app.add_systems(PostUpdate, check_for_bvh_capture_complete); - } - HeadlessMode::Scene(scene, skybox) => { - app.add_systems( - Startup, - move |mut cmd: Commands, mut ew: EventWriter| { - cmd.insert_resource(SkyboxId(skybox.clone())); - ew.send(EditorEvent::Load(EditorPrefabPath::File(scene.clone()))) + move |mut ew: EventWriter| { + ew.send(LoadLibraryObjectEvent(id.clone())); }, ); } - HeadlessMode::Mixamo(mixamo_path, skybox) => { - app.add_plugins(MixamoPlugin); + anim @ (InitAsset::BvhAnim(_) | InitAsset::MixamoAnim(_)) => { app.add_systems( Startup, - move |mut commands: Commands, - mut ew: EventWriter, - mut load_scene_event: EventWriter| { - ew.send(MixamoImportEvent(mixamo_path.clone())); - load_scene_event.send(LoadSceneEvent("Mannequin.gltf".to_string())); - commands.insert_resource(SkyboxId(skybox.clone())); + move |mut ew: EventWriter| { + ew.send(LoadLibraryObjectEvent("Mannequin.gltf".into())); }, ); - app.add_systems(PostUpdate, check_for_mixamo_capture_complete); - app.run(); + match anim { + InitAsset::BvhAnim(anim) => { + app.add_plugins(BvhPlugin); + app.add_systems( + Startup, + move |mut cmd: Commands, r_assets: Res| { + cmd.insert_resource(bvh::TestBvh(r_assets.load(anim.clone()))); + }, + ); + } + InitAsset::MixamoAnim(anim) => { + app.add_plugins(MixamoPlugin); + app.add_systems(Startup, move |mut ew: EventWriter| { + ew.send(MixamoImportEvent(anim.clone())); + }); + } + _ => unreachable!(), + } } - HeadlessMode::None => {} - } - - app -} - -pub fn is_headless(studio_state: Res) -> bool { - *studio_state == StudioMode::Headless -} - -pub fn is_not_headless(studio_state: Res) -> bool { - *studio_state != StudioMode::Headless -} - -#[derive(Resource)] -pub struct HeadlessSettings { - pub output_dims: Extent3d, - pub output_dir: String, - pub max_frames: u32, -} - -impl Default for HeadlessSettings { - fn default() -> Self { - HeadlessSettings { - output_dims: Extent3d { - width: 1280, - height: 720, - depth_or_array_layers: 1, - }, - output_dir: "./screen_shots/".to_string(), - max_frames: u32::MAX, - } - } -} - -fn check_for_bvh_capture_complete( - mut close_app: EventWriter, - mut main_camera: Query<&mut ScreenCapture, With>, - bvh_event_reader: EventReader, -) { - let Ok(mut screen_capture) = main_camera.get_single_mut() else { - return; - }; - - println!("Frames captured {}", screen_capture.frames_captured()); - if !screen_capture.should_capture() || !bvh_event_reader.is_empty() { - screen_capture.stop_capturing(); - close_app.send(AppExit); - } -} - -fn check_for_mixamo_capture_complete( - mut close_app: EventWriter, - mut main_camera: Query<&mut ScreenCapture, With>, - mixamo_anims: Query<&AnimationPlayer>, -) { - let Ok(mut capture) = main_camera.get_single_mut() else { - return; - }; - - for anim in mixamo_anims.iter() { - println!( - "Time elapsed {} | Frames Captured : {}", - anim.elapsed(), - capture.frames_captured() - ); - if anim.completions() != 0 { - capture.stop_capturing(); - close_app.send(AppExit); + InitAsset::ImportedScene(scene) => { + app.add_systems(Startup, move |mut ew: EventWriter| { + ew.send(ImportSceneEvent(scene.clone())); + }); } } } diff --git a/studio/src/main-headless.rs b/studio/src/main-headless.rs index da01023..f21a302 100644 --- a/studio/src/main-headless.rs +++ b/studio/src/main-headless.rs @@ -1,6 +1,6 @@ use bevy::render::render_resource::Extent3d; use clap::{Args, Parser, Subcommand}; -use studio::{start_headless, HeadlessMode}; +use studio::headless::{start_headless, HeadlessMode}; #[derive(Parser)] #[command(name = "StorytellerStudioHeadless")] diff --git a/studio/src/main.rs b/studio/src/main.rs index 8ef44f3..f15a89d 100644 --- a/studio/src/main.rs +++ b/studio/src/main.rs @@ -1,6 +1,9 @@ -use bevy::{app::Update, window::close_on_esc}; +use bevy::{ + app::Update, + window::{close_on_esc, Window}, +}; use clap::Parser; -use studio::{screenshot::ScreenShotPlugin, InitSeed, StudioMode, ViewportSize}; +use studio::{screenshot::ScreenShotPlugin, InitAsset, InitParams, StudioMode}; #[derive(Parser)] #[command(name = "StorytellerStudio")] @@ -20,15 +23,16 @@ fn main() { let skybox_id = args.skybox.unwrap_or("gum_trees_4k".to_string()); // Edit the arguments here to change the default startup scene or skybox - let mut app = studio::start_internal( - InitSeed::FromLibrary { - object_id, + let mut app = studio::start( + InitParams::FromAsset { + asset: InitAsset::LibraryObject(object_id), skybox_id, }, - "", // ignored for non-WASM - "Storyteller Studio", - ViewportSize::default(), StudioMode::Editor, + Some(Window { + title: "Storyteller Studio".into(), + ..Default::default() + }), ); // Add any additional systems, resources, etc. for local debugging diff --git a/studio/src/scene.rs b/studio/src/scene.rs index 97575a5..875373a 100644 --- a/studio/src/scene.rs +++ b/studio/src/scene.rs @@ -26,10 +26,10 @@ use crate::{ camera_controller::{CameraController, CameraControllerBundle}, change_tracking::{ChangeTracker, ChangeTrackingPlugin}, debug::DebugPoint, - is_headless, is_not_headless, + headless::{is_headless, is_not_headless, HeadlessSettings}, math::{Combinable, Extrema}, screenshot::ScreenCapture, - HeadlessSettings, MainCamera, + MainCamera, }; pub struct ScenePlugin; @@ -46,6 +46,7 @@ impl Plugin for ScenePlugin { .add_state::() .add_event::() .add_event::() + .add_event::() .add_systems( Startup, ( @@ -55,7 +56,8 @@ impl Plugin for ScenePlugin { ) .add_systems( Update, - (init_object_loading, init_scene_loading).in_set(SceneSpawnerSystem), + (init_object_loading, init_scene_import, init_scene_loading) + .in_set(SceneSpawnerSystem), ) .add_systems( OnEnter(SceneState::Active), @@ -208,8 +210,7 @@ fn auto_add_handle( #[derive(Event, Deref)] pub struct LoadLibraryObjectEvent(pub String); -/// Request the application to load a previously saved `*.scn.ron` dynamic scene -/// file. +/// Request the application to load a previously saved Storyteller Studio scene. /// /// Expects a full, resolvable path to the file (e.g. `scenes/my-scene.scn.ron` /// for a local file saved under `studio/assets/scenes`, or @@ -218,6 +219,11 @@ pub struct LoadLibraryObjectEvent(pub String); #[derive(Event, Deref)] pub struct LoadSceneEvent(pub String); +/// Request the application to import and process a glTF scene from an arbitrary +/// asset source (e.g., an http path or a Storyteller.ai media token). +#[derive(Event, Deref)] +pub struct ImportSceneEvent(pub String); + // TODOL This could be converted into an enum that indicates what "kind" of // element this is (e.g. StaticMesh, SkinnedMesh, Bone, Light, Camera). // We don't have an immediate need for that just yet, but likely will @@ -329,6 +335,21 @@ fn init_object_loading(mut cmd: Commands, mut er: EventReader) { + if let Some(path) = er.read().last() { + info!("Importing asset: {}", path.0); + cmd.spawn(( + SpatialBundle::default(), + space_editor::prelude::GltfPrefab { + path: path.0.clone(), + scene: "Scene0".to_string(), + }, + PrefabMarker, + SceneRoot, + )); + } +} + fn init_scene_loading( mut er_load_scene: EventReader, mut ew_editor: EventWriter, diff --git a/studio/src/viewport.rs b/studio/src/viewport.rs index 1c79bd0..edda86c 100644 --- a/studio/src/viewport.rs +++ b/studio/src/viewport.rs @@ -1,10 +1,11 @@ use core::fmt; use bevy::window::WindowResolution; +use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; #[wasm_bindgen] -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Serialize, Deserialize)] pub struct ViewportSize { pub width: f32, pub height: f32, diff --git a/studio/src/wasm/init.rs b/studio/src/wasm/init.rs new file mode 100644 index 0000000..0fb6a21 --- /dev/null +++ b/studio/src/wasm/init.rs @@ -0,0 +1,164 @@ +use bevy::prelude::*; +use serde::{Deserialize, Serialize}; +use wasm_bindgen::prelude::*; + +use crate::{InitAsset, InitParams, StudioMode, ViewportSize}; + +#[wasm_bindgen(typescript_custom_section)] +const WASM_ENTRY_POINTS: &str = r#" +export type SkyboxId + = "gum_trees_4k" + | "kloofenfal_28d_misty_4k" + | "meadow_4k" + | "promenade_de_vidy_4k" + | "scythian_tombs_4k" + | "test_scene" + ; + +export interface InitOptions { + mode: StudioMode; + /** Required for all entry-points except `initFromStorytellerScene()` */ + skyboxId?: SkyboxId; + canvasSelector: string; + canvasAlt: string; + viewportSize: ViewportSize; +} + +export function initFromLibrary(objectId: string, options: InitOptions): void; +export function initFromBvh(animPath: string, options: InitOptions): void; +export function initFromMixamo(animPath: string, options: InitOptions): void; +export function initFromSceneImport(scenePath: string, options: InitOptions): void; +export function initFromStorytellerScene(scenePath: string, options: InitOptions): void; +"#; + +#[derive(Serialize, Deserialize)] +struct WasmInitOptions { + #[serde(rename = "skyboxId")] + skybox_id: Option, + mode: StudioMode, + #[serde(rename = "canvasSelector")] + canvas_selector: String, + #[serde(rename = "canvasAlt")] + canvas_alt: String, + #[serde(rename = "viewportSize")] + viewport_size: ViewportSize, +} + +#[wasm_bindgen(skip_typescript, js_name = initFromLibrary)] +pub fn init_from_library(object_id: String, options: JsValue) -> Result<(), JsValue> { + let options = serde_wasm_bindgen::from_value::(options)?; + let skybox_id = options + .skybox_id + .expect("`skyboxId` is required for `initFromLibrary`"); + + crate::start( + InitParams::FromAsset { + asset: InitAsset::LibraryObject(object_id), + skybox_id, + }, + options.mode, + Some(Window { + resolution: options.viewport_size.into(), + title: options.canvas_alt, + canvas: Some(options.canvas_selector), + ..default() + }), + ) + .run(); + + Ok(()) +} + +#[wasm_bindgen(skip_typescript, js_name = initFromBvh)] +pub fn init_from_bvh(anim_path: String, options: JsValue) -> Result<(), JsValue> { + let options = serde_wasm_bindgen::from_value::(options)?; + let skybox_id = options + .skybox_id + .expect("`skyboxId` is required for `initFromBvh`"); + + crate::start( + InitParams::FromAsset { + asset: InitAsset::BvhAnim(anim_path), + skybox_id, + }, + options.mode, + Some(Window { + resolution: options.viewport_size.into(), + title: options.canvas_alt, + canvas: Some(options.canvas_selector), + ..default() + }), + ) + .run(); + + Ok(()) +} + +#[wasm_bindgen(skip_typescript, js_name = initFromMixamo)] +pub fn init_from_mixamo(anim_path: String, options: JsValue) -> Result<(), JsValue> { + let options = serde_wasm_bindgen::from_value::(options)?; + let skybox_id = options + .skybox_id + .expect("`skyboxId` is required for `initFromMixamo`"); + + crate::start( + InitParams::FromAsset { + asset: InitAsset::MixamoAnim(anim_path), + skybox_id, + }, + options.mode, + Some(Window { + resolution: options.viewport_size.into(), + title: options.canvas_alt, + canvas: Some(options.canvas_selector), + ..default() + }), + ) + .run(); + + Ok(()) +} + +#[wasm_bindgen(skip_typescript, js_name = initFromSceneImport)] +pub fn init_from_scene_import(scene_path: String, options: JsValue) -> Result<(), JsValue> { + let options = serde_wasm_bindgen::from_value::(options)?; + let skybox_id = options + .skybox_id + .expect("`skyboxId` is required for `initFromSceneImport`"); + + crate::start( + InitParams::FromAsset { + asset: InitAsset::ImportedScene(scene_path), + skybox_id, + }, + options.mode, + Some(Window { + resolution: options.viewport_size.into(), + title: options.canvas_alt, + canvas: Some(options.canvas_selector), + ..default() + }), + ) + .run(); + + Ok(()) +} + +#[wasm_bindgen(skip_typescript, js_name = initFromStorytellerScene)] +pub fn init_from_storyteller_scene(scene_path: String, options: JsValue) -> Result<(), JsValue> { + let options = serde_wasm_bindgen::from_value::(options)?; + + crate::start( + InitParams::FromScene(scene_path), + options.mode, + Some(Window { + resolution: options.viewport_size.into(), + title: options.canvas_alt, + canvas: Some(options.canvas_selector), + ..default() + }), + ) + .run(); + + Ok(()) +} diff --git a/studio/src/wasm/mod.rs b/studio/src/wasm/mod.rs index 6ec32e2..c109cad 100644 --- a/studio/src/wasm/mod.rs +++ b/studio/src/wasm/mod.rs @@ -4,6 +4,7 @@ use parking_lot::ReentrantMutex; use wasm_bindgen::prelude::wasm_bindgen; mod conv; +mod init; #[cfg(feature = "wasm_screenshot")] mod screenshot; mod util; diff --git a/tsconfig.base.json b/tsconfig.base.json index 7cab5a6..1157706 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -24,11 +24,8 @@ "@storyteller/studio-ui/tree": ["studio-ui/src/lib/tree.element.ts"], "@storyteller/studio-web": ["studio-web/src/index.ts"], "@storyteller/studio-web/canvas-provider": ["studio-web/src/lib/canvas-provider.element.ts"], - "@storyteller/studio-web/viewer": ["studio-web/src/lib/viewer.element.ts"], - "@storyteller/studio-web/bvh-viewer": ["studio-web/src/lib/bvh-viewer.element.ts"], - "@storyteller/studio-web/editor": ["studio-web/src/lib/editor.element.ts"], - "@storyteller/studio-web/mixamo-viewer": ["studio-web/src/lib/mixamo-viewer.element.ts"], "@storyteller/studio-web/scene-hierarchy": ["studio-web/src/lib/scene-hierarchy.element.ts"], + "@storyteller/studio-web/studio": ["studio-web/src/lib/studio.element.ts"], "@storyteller/studio-web/transform-toolbar": ["studio-web/src/lib/transform-toolbar.element.ts"], "@storyteller/utility": ["utility/src/index.ts"] } From 343919a9f52af95d620ff68b08ddf459f248a580 Mon Sep 17 00:00:00 2001 From: Brooks Palin Date: Tue, 27 Feb 2024 22:11:37 -0700 Subject: [PATCH 08/13] Allow Skybox to take a Color (#57) This PR Adds the ability to set the color of the skybox using the URL parameters. - Now you can pass a color's hexadecimal number (without the #) in the skybox parameter, and that will set the skybox to that color. --- studio-web/src/lib/studio.element.ts | 3 +- studio-web/src/lib/url-params.ts | 6 +-- studio/assets/scenes/test.ron | 69 ++++++++++++++++++++++++++++ studio/src/lib.rs | 3 ++ studio/src/skybox.rs | 21 ++++++--- studio/src/wasm/init.rs | 11 +---- 6 files changed, 91 insertions(+), 22 deletions(-) create mode 100644 studio/assets/scenes/test.ron diff --git a/studio-web/src/lib/studio.element.ts b/studio-web/src/lib/studio.element.ts index 63881b5..c8db6d3 100644 --- a/studio-web/src/lib/studio.element.ts +++ b/studio-web/src/lib/studio.element.ts @@ -2,7 +2,6 @@ import { inject } from "@storyteller/framework"; import * as studio from "@storyteller/studio"; import { type InitOptions, - type SkyboxId, StudioMode, ViewportSize, } from "@storyteller/studio"; @@ -21,7 +20,7 @@ export class StudioElement extends LitElement { @property() mixamoPath?: string; @property() sceneImport?: string; @property() storytellerScene?: string; - @property() skyboxId?: SkyboxId; + @property() skyboxId?: string; @property({ type: Number }) mode?: StudioMode; @inject(CANVAS_PROVIDER) diff --git a/studio-web/src/lib/url-params.ts b/studio-web/src/lib/url-params.ts index 8135957..cadf983 100644 --- a/studio-web/src/lib/url-params.ts +++ b/studio-web/src/lib/url-params.ts @@ -1,4 +1,4 @@ -import { type SkyboxId, StudioMode } from "@storyteller/studio"; +import { StudioMode } from "@storyteller/studio"; import { match } from "@storyteller/utility"; export class StudioURLParams { @@ -12,9 +12,7 @@ export class StudioURLParams { get mixamo() { return this.#nativeParams.get("mixamo") ?? undefined; } get sceneImport() { return this.#nativeParams.get("sceneImport") ?? undefined; } get scene() { return this.#nativeParams.get("scene") ?? undefined; } - get skybox() { - return this.#nativeParams.get("skybox") as SkyboxId ?? undefined; - } + get skybox() { return this.#nativeParams.get("skybox") ?? undefined; } get mode(): StudioMode { return match(this.#nativeParams.get("mode"), { "studio": () => StudioMode.Editor, diff --git a/studio/assets/scenes/test.ron b/studio/assets/scenes/test.ron new file mode 100644 index 0000000..095a3b3 --- /dev/null +++ b/studio/assets/scenes/test.ron @@ -0,0 +1,69 @@ +( + resources: {}, + entities: { + 2: ( + components: { + "bevy_transform::components::transform::Transform": ( + translation: ( + x: 0.0, + y: 0.0, + z: 0.0, + ), + rotation: ( + x: -0.27984813, + y: 0.36470518, + z: 0.11591689, + w: 0.88047624, + ), + scale: ( + x: 1.0, + y: 1.0, + z: 1.0, + ), + ), + "bevy_render::view::visibility::Visibility": Inherited, + "bevy_pbr::light::DirectionalLight": ( + color: Rgba( + red: 1.0, + green: 1.0, + blue: 1.0, + alpha: 1.0, + ), + illuminance: 20000.0, + shadows_enabled: false, + shadow_depth_bias: 0.02, + shadow_normal_bias: 1.8, + ), + }, + ), + 9: ( + components: { + "space_prefab::sub_scene::CollapsedSubScene": ("(\n resources: {},\n entities: {\n 9: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::component::GltfPrefab\": (\n path: \"gltf/sample-room.gltf\",\n scene: \"Scene0\",\n ),\n },\n ),\n 10: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 93,\n 94,\n 95,\n 96,\n 342,\n 98,\n 99,\n 100,\n 101,\n 343,\n 103,\n 104,\n 105,\n 344,\n 345,\n 108,\n 346,\n 347,\n 111,\n 348,\n 113,\n 349,\n 115,\n 116,\n 117,\n 118,\n 119,\n 120,\n 121,\n 122,\n 123,\n 124,\n 125,\n 126,\n 127,\n 128,\n 129,\n 130,\n 131,\n 350,\n ]),\n },\n ),\n 11: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 6,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0000000203421,\n y: 0.044360533,\n z: -0.0000000016096777,\n ),\n rotation: (\n x: -0.014980346,\n y: -0.0000001823493,\n z: 0.0000008322585,\n w: 0.9998878,\n ),\n scale: (\n x: 0.9999974,\n y: 1.0000049,\n z: 0.999997,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17821275905860473352,\n name: \"DEF-spine.006\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0000000203421,\n y: 0.044360533,\n z: -0.0000000016096777,\n ),\n rotation: (\n x: -0.014980346,\n y: -0.0000001823493,\n z: 0.0000008322585,\n w: 0.9998878,\n ),\n scale: (\n x: 0.9999974,\n y: 1.0000049,\n z: 0.999997,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041383,\n y: -0.0000000009400143,\n z: 0.0000000009215703,\n ),\n y_axis: (\n x: 0.00000000088706786,\n y: 0.8040894,\n z: -0.008830743,\n ),\n z_axis: (\n x: -0.000000000914611,\n y: 0.00883094,\n z: 0.8040894,\n ),\n ),\n translation: (\n x: 0.3501124,\n y: 1.0830238,\n z: -1.0933075,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435672,\n y: 0.0000000014692579,\n z: -0.0000000014091218,\n ),\n y_axis: (\n x: -0.0000000013561997,\n y: 1.2434928,\n z: 0.013656397,\n ),\n z_axis: (\n x: 0.0000000014293892,\n y: -0.013656703,\n z: 1.2434928,\n ),\n ),\n translation: (\n x: -0.43538833,\n y: -1.3616633,\n z: 1.3447299,\n ),\n )),\n },\n ),\n 12: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 7,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000023841858,\n y: 0.5970744,\n z: -0.0808239,\n ),\n rotation: (\n x: 0.15047461,\n y: 0.7774583,\n z: 0.33841825,\n w: -0.50832,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5338185809916520741,\n name: \"DEF-pelvis.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000023841858,\n y: 0.5970744,\n z: -0.0808239,\n ),\n rotation: (\n x: 0.15047461,\n y: 0.7774583,\n z: 0.33841825,\n w: -0.50832,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 0.99999994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.35216174,\n y: -0.088514775,\n z: 0.717486,\n ),\n y_axis: (\n x: 0.46481213,\n y: 0.5835319,\n z: 0.30013156,\n ),\n z_axis: (\n x: -0.5536883,\n y: 0.54616326,\n z: -0.20438628,\n ),\n ),\n translation: (\n x: 0.3501125,\n y: 0.4801305,\n z: -1.060749,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.5446033,\n y: 0.71881247,\n z: -0.8562558,\n ),\n y_axis: (\n x: -0.13688435,\n y: 0.902408,\n z: 0.844619,\n ),\n z_axis: (\n x: 1.109562,\n y: 0.464141,\n z: -0.31607482,\n ),\n ),\n translation: (\n x: 1.4333616,\n y: -0.19260171,\n z: -0.44101754,\n ),\n )),\n },\n ),\n 13: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 8,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000023841858,\n y: 0.5970744,\n z: -0.0808239,\n ),\n rotation: (\n x: -0.15047462,\n y: 0.7774582,\n z: 0.33841825,\n w: 0.50832,\n ),\n scale: (\n x: 1.0000002,\n y: 0.99999994,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14454054902076798865,\n name: \"DEF-pelvis.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000023841858,\n y: 0.5970744,\n z: -0.0808239,\n ),\n rotation: (\n x: -0.15047462,\n y: 0.7774582,\n z: 0.33841825,\n w: 0.50832,\n ),\n scale: (\n x: 1.0000002,\n y: 0.99999994,\n z: 0.99999994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.35216153,\n y: 0.08851481,\n z: -0.71748614,\n ),\n y_axis: (\n x: -0.46481207,\n y: 0.58353186,\n z: 0.30013147,\n ),\n z_axis: (\n x: 0.5536882,\n y: 0.54616326,\n z: -0.20438598,\n ),\n ),\n translation: (\n x: 0.3501125,\n y: 0.4801305,\n z: -1.060749,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.54460293,\n y: -0.7188128,\n z: 0.856256,\n ),\n y_axis: (\n x: 0.13688451,\n y: 0.90240794,\n z: 0.844619,\n ),\n z_axis: (\n x: -1.109562,\n y: 0.46414092,\n z: -0.31607458,\n ),\n ),\n translation: (\n x: -1.0520171,\n y: 0.31072882,\n z: -1.0405891,\n ),\n )),\n },\n ),\n 14: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 9,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000014901161,\n y: 0.20526445,\n z: 0.0,\n ),\n rotation: (\n x: -0.000097672106,\n y: 0.97285354,\n z: -0.2314216,\n w: -0.00040191185,\n ),\n scale: (\n x: 0.9999547,\n y: 1.0000634,\n z: 0.9999826,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12641277161544865435,\n name: \"DEF-toe.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000014901161,\n y: 0.20526445,\n z: 0.0,\n ),\n rotation: (\n x: -0.000097672106,\n y: 0.97285354,\n z: -0.2314216,\n w: -0.00040191185,\n ),\n scale: (\n x: 0.9999547,\n y: 1.0000634,\n z: 0.9999826,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.67654365,\n y: 0.40687674,\n z: -0.15272073,\n ),\n y_axis: (\n x: -0.06632598,\n y: 0.18710205,\n z: 0.7930914,\n ),\n z_axis: (\n x: 0.41841292,\n y: 0.665858,\n z: -0.09064055,\n ),\n ),\n translation: (\n x: 0.08941162,\n y: 0.21149693,\n z: -0.46448725,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.048125,\n y: -0.124631494,\n z: 0.67548424,\n ),\n y_axis: (\n x: 0.62656885,\n y: 0.24080381,\n z: 1.0512885,\n ),\n z_axis: (\n x: -0.23547126,\n y: 1.1936566,\n z: -0.19152406,\n ),\n ),\n translation: (\n x: -0.14817625,\n y: 0.5146525,\n z: -0.37170094,\n ),\n )),\n },\n ),\n 15: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 10,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0000000643704,\n y: 0.2052647,\n z: -0.000000007188646,\n ),\n rotation: (\n x: -0.000091319474,\n y: 0.97285044,\n z: -0.23143427,\n w: -0.0004041775,\n ),\n scale: (\n x: 0.9999719,\n y: 1.0000393,\n z: 0.999989,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14118345266549736952,\n name: \"DEF-toe.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0000000643704,\n y: 0.2052647,\n z: -0.000000007188646,\n ),\n rotation: (\n x: -0.000091319474,\n y: 0.97285044,\n z: -0.23143427,\n w: -0.0004041775,\n ),\n scale: (\n x: 0.9999719,\n y: 1.0000393,\n z: 0.999989,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.8038364,\n y: -0.0023199506,\n z: 0.0034964955,\n ),\n y_axis: (\n x: -0.0005125017,\n y: 0.18738024,\n z: 0.7911549,\n ),\n z_axis: (\n x: 0.0056871683,\n y: 0.7845266,\n z: -0.1434557,\n ),\n ),\n translation: (\n x: 0.3689385,\n y: 0.0797288,\n z: -0.36637783,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.244071,\n y: 0.0046305372,\n z: -0.0047848662,\n ),\n y_axis: (\n x: 0.008502875,\n y: 0.22150005,\n z: 1.221775,\n ),\n z_axis: (\n x: -0.0028197502,\n y: 1.2115171,\n z: -0.2893731,\n ),\n ),\n translation: (\n x: 0.45727468,\n y: 0.4245047,\n z: -0.20166522,\n ),\n )),\n },\n ),\n 16: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 11,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.08711493,\n y: 1.3709469,\n z: -0.120574474,\n ),\n rotation: (\n x: -0.105440766,\n y: -0.096332185,\n z: -0.020338729,\n w: 0.9895397,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999994,\n z: 0.99999976,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4475437106531023163,\n name: \"DEF-ear.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.08711493,\n y: 1.3709469,\n z: -0.120574474,\n ),\n rotation: (\n x: -0.105440766,\n y: -0.096332185,\n z: -0.020338729,\n w: 0.9895397,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999994,\n z: 0.99999976,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.78854847,\n y: -0.016032333,\n z: 0.1567572,\n ),\n y_axis: (\n x: 0.04870396,\n y: 0.78559273,\n z: -0.16465305,\n ),\n z_axis: (\n x: -0.14985919,\n y: 0.17095512,\n z: 0.7713332,\n ),\n ),\n translation: (\n x: 0.42016515,\n y: 1.1024312,\n z: -1.0927141,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.219458,\n y: 0.07531868,\n z: -0.23175117,\n ),\n y_axis: (\n x: -0.02479334,\n y: 1.2148869,\n z: 0.26437518,\n ),\n z_axis: (\n x: 0.24241862,\n y: -0.25462916,\n z: 1.1928356,\n ),\n ),\n translation: (\n x: -0.22014654,\n y: -1.6492124,\n z: 1.1093465,\n ),\n )),\n },\n ),\n 17: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 12,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.08992565,\n y: 1.4162838,\n z: -0.13007653,\n ),\n rotation: (\n x: -0.5146281,\n y: -0.10243849,\n z: -0.3528473,\n w: 0.77470195,\n ),\n scale: (\n x: 1.0000008,\n y: 0.999998,\n z: 1.0000007,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13245080596571993233,\n name: \"DEF-ear.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.08992565,\n y: 1.4162838,\n z: -0.13007653,\n ),\n rotation: (\n x: -0.5146281,\n y: -0.10243849,\n z: -0.3528473,\n w: 0.77470195,\n ),\n scale: (\n x: 1.0000008,\n y: 0.999998,\n z: 1.0000007,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.5870298,\n y: -0.3548405,\n z: 0.41967124,\n ),\n y_axis: (\n x: 0.5244085,\n y: 0.17796622,\n z: -0.58306074,\n ),\n z_axis: (\n x: 0.16440761,\n y: 0.6993252,\n z: 0.36132264,\n ),\n ),\n translation: (\n x: 0.42242536,\n y: 1.1388884,\n z: -1.100355,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.90781593,\n y: 0.81097937,\n z: 0.25424927,\n ),\n y_axis: (\n x: -0.5487453,\n y: 0.27521858,\n z: 1.0814759,\n ),\n z_axis: (\n x: 0.6490032,\n y: -0.901683,\n z: 0.5587697,\n ),\n ),\n translation: (\n x: 0.955609,\n y: -1.6481929,\n z: -0.7242366,\n ),\n )),\n },\n ),\n 18: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 13,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000008940697,\n y: 0.041360185,\n z: -0.000000007450581,\n ),\n rotation: (\n x: -0.36466363,\n y: 0.017230907,\n z: -0.21004441,\n w: 0.9069757,\n ),\n scale: (\n x: 0.99999714,\n y: 1.000002,\n z: 1.0000011,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7830967844259008606,\n name: \"DEF-ear.L.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000008940697,\n y: 0.041360185,\n z: -0.000000007450581,\n ),\n rotation: (\n x: -0.36466363,\n y: 0.017230907,\n z: -0.21004441,\n w: 0.9069757,\n ),\n scale: (\n x: 0.99999714,\n y: 1.000002,\n z: 1.0000011,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.5840152,\n y: 0.12935303,\n z: 0.53743106,\n ),\n y_axis: (\n x: -0.3306733,\n y: -0.544744,\n z: 0.49045777,\n ),\n z_axis: (\n x: 0.44297206,\n y: -0.5771923,\n z: -0.34243676,\n ),\n ),\n translation: (\n x: 0.4339797,\n y: 1.1126906,\n z: -1.1251793,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9031549,\n y: -0.5113702,\n z: 0.6850259,\n ),\n y_axis: (\n x: 0.20005192,\n y: -0.84243494,\n z: -0.8926164,\n ),\n z_axis: (\n x: 0.83111405,\n y: 0.7584591,\n z: -0.52956164,\n ),\n ),\n translation: (\n x: 0.32060552,\n y: 2.012696,\n z: 0.10006678,\n ),\n )),\n },\n ),\n 19: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 14,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.08255935,\n y: 1.3478996,\n z: -0.12871015,\n ),\n rotation: (\n x: 0.17441106,\n y: 0.0883209,\n z: -0.07795724,\n w: 0.9776006,\n ),\n scale: (\n x: 0.99999917,\n y: 1.0000012,\n z: 0.99999917,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10734110240432112616,\n name: \"DEF-ear.L.004\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.08255935,\n y: 1.3478996,\n z: -0.12871015,\n ),\n rotation: (\n x: 0.17441106,\n y: 0.0883209,\n z: -0.07795724,\n w: 0.9776006,\n ),\n scale: (\n x: 0.99999917,\n y: 1.0000012,\n z: 0.99999917,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7818183,\n y: -0.09779425,\n z: -0.16072974,\n ),\n y_axis: (\n x: 0.14734277,\n y: 0.7454428,\n z: 0.26314512,\n ),\n z_axis: (\n x: 0.116995566,\n y: -0.28529137,\n z: 0.7426698,\n ),\n ),\n translation: (\n x: 0.41650182,\n y: 1.083898,\n z: -1.0992563,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2090517,\n y: 0.22785895,\n z: 0.18092911,\n ),\n y_axis: (\n x: -0.15123503,\n y: 1.1527936,\n z: -0.44119203,\n ),\n z_axis: (\n x: -0.24856232,\n y: 0.40694207,\n z: 1.1485101,\n ),\n ),\n translation: (\n x: -0.6128826,\n y: -0.8970807,\n z: 1.6653569,\n ),\n )),\n },\n ),\n 20: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 15,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.087115705,\n y: 1.370947,\n z: -0.120574474,\n ),\n rotation: (\n x: -0.10544076,\n y: 0.096332155,\n z: 0.02033873,\n w: 0.9895396,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999994,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3123306842418822660,\n name: \"DEF-ear.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.087115705,\n y: 1.370947,\n z: -0.120574474,\n ),\n rotation: (\n x: -0.10544076,\n y: 0.096332155,\n z: 0.02033873,\n w: 0.9895396,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999994,\n z: 0.99999994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.78854847,\n y: 0.016032338,\n z: -0.15675715,\n ),\n y_axis: (\n x: -0.048703954,\n y: 0.78559273,\n z: -0.16465303,\n ),\n z_axis: (\n x: 0.14985916,\n y: 0.17095514,\n z: 0.7713334,\n ),\n ),\n translation: (\n x: 0.28005958,\n y: 1.1024313,\n z: -1.0927141,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.219458,\n y: -0.07531866,\n z: 0.23175102,\n ),\n y_axis: (\n x: 0.024793355,\n y: 1.2148868,\n z: 0.26437512,\n ),\n z_axis: (\n x: -0.24241853,\n y: -0.25462914,\n z: 1.1928353,\n ),\n ),\n translation: (\n x: -0.63374794,\n y: -1.5964724,\n z: 0.94706845,\n ),\n )),\n },\n ),\n 21: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 16,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.08992651,\n y: 1.416284,\n z: -0.13007653,\n ),\n rotation: (\n x: -0.51462805,\n y: 0.102438465,\n z: 0.35284728,\n w: 0.7747021,\n ),\n scale: (\n x: 1.0000008,\n y: 0.99999833,\n z: 1.0000007,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7805192637420836136,\n name: \"DEF-ear.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.08992651,\n y: 1.416284,\n z: -0.13007653,\n ),\n rotation: (\n x: -0.51462805,\n y: 0.102438465,\n z: 0.35284728,\n w: 0.7747021,\n ),\n scale: (\n x: 1.0000008,\n y: 0.99999833,\n z: 1.0000007,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.5870299,\n y: 0.35484055,\n z: -0.4196712,\n ),\n y_axis: (\n x: -0.52440876,\n y: 0.17796643,\n z: -0.58306104,\n ),\n z_axis: (\n x: -0.16440754,\n y: 0.6993252,\n z: 0.36132273,\n ),\n ),\n translation: (\n x: 0.2777993,\n y: 1.1388885,\n z: -1.100355,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9078159,\n y: -0.810979,\n z: -0.25424922,\n ),\n y_axis: (\n x: 0.54874516,\n y: 0.2752186,\n z: 1.0814759,\n ),\n z_axis: (\n x: -0.6490031,\n y: -0.90168244,\n z: 0.55876976,\n ),\n ),\n translation: (\n x: -1.591284,\n y: -1.0803246,\n z: -0.546205,\n ),\n )),\n },\n ),\n 22: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 17,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000010430813,\n y: 0.041359827,\n z: -0.00000011175871,\n ),\n rotation: (\n x: -0.36466548,\n y: -0.017232342,\n z: 0.21004212,\n w: 0.90697545,\n ),\n scale: (\n x: 0.9999975,\n y: 1.000003,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1855354839461481842,\n name: \"DEF-ear.R.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000010430813,\n y: 0.041359827,\n z: -0.00000011175871,\n ),\n rotation: (\n x: -0.36466548,\n y: -0.017232342,\n z: 0.21004212,\n w: 0.90697545,\n ),\n scale: (\n x: 0.9999975,\n y: 1.000003,\n z: 1.0,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.5840129,\n y: -0.12935421,\n z: -0.53743327,\n ),\n y_axis: (\n x: 0.3306764,\n y: -0.5447454,\n z: 0.49045652,\n ),\n z_axis: (\n x: -0.44297206,\n y: -0.5771938,\n z: -0.34243426,\n ),\n ),\n translation: (\n x: 0.26624477,\n y: 1.112691,\n z: -1.1251792,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9031516,\n y: 0.511373,\n z: -0.68502915,\n ),\n y_axis: (\n x: -0.20005003,\n y: -0.84243095,\n z: -0.89261574,\n ),\n z_axis: (\n x: -0.8311179,\n y: 0.7584578,\n z: -0.52955836,\n ),\n ),\n translation: (\n x: -0.9530221,\n y: 1.6546159,\n z: 0.57974297,\n ),\n )),\n },\n ),\n 23: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 18,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0825603,\n y: 1.3478996,\n z: -0.12871015,\n ),\n rotation: (\n x: 0.17441009,\n y: -0.08832091,\n z: 0.0779568,\n w: 0.9776008,\n ),\n scale: (\n x: 0.99999666,\n y: 1.0000068,\n z: 0.9999965,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17302349132630004254,\n name: \"DEF-ear.R.004\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0825603,\n y: 1.3478996,\n z: -0.12871015,\n ),\n rotation: (\n x: 0.17441009,\n y: -0.08832091,\n z: 0.0779568,\n w: 0.9776008,\n ),\n scale: (\n x: 0.99999666,\n y: 1.0000068,\n z: 0.9999965,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7818165,\n y: 0.09779349,\n z: 0.16072913,\n ),\n y_axis: (\n x: -0.1473428,\n y: 0.7454477,\n z: 0.26314524,\n ),\n z_axis: (\n x: -0.116995536,\n y: -0.2852891,\n z: 0.74266845,\n ),\n ),\n translation: (\n x: 0.28372276,\n y: 1.083898,\n z: -1.0992563,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2090547,\n y: -0.22785641,\n z: -0.18092999,\n ),\n y_axis: (\n x: 0.15123457,\n y: 1.1527882,\n z: -0.44119084,\n ),\n z_axis: (\n x: 0.24856257,\n y: 0.4069376,\n z: 1.1485139,\n ),\n ),\n translation: (\n x: -0.23372516,\n y: -0.73752797,\n z: 1.792051,\n ),\n )),\n },\n ),\n 24: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 19,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000003874302,\n y: 1.3464934,\n z: -0.0061694384,\n ),\n rotation: (\n x: 0.710716,\n y: 0.000000000000099766956,\n z: 0.00000000000011412578,\n w: -0.7034791,\n ),\n scale: (\n x: 1.0,\n y: 0.9999999,\n z: 0.9999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11231444943004178836,\n name: \"DEF-teeth.T\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000003874302,\n y: 1.3464934,\n z: -0.0061694384,\n ),\n rotation: (\n x: 0.710716,\n y: 0.000000000000099766956,\n z: 0.00000000000011412578,\n w: -0.7034791,\n ),\n scale: (\n x: 1.0,\n y: 0.9999999,\n z: 0.9999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041385,\n y: -0.000000000000015084235,\n z: 0.00000000000024332424,\n ),\n y_axis: (\n x: 0.00000000000024315708,\n y: -0.008229935,\n z: -0.80409634,\n ),\n z_axis: (\n x: 0.00000000000001757371,\n y: 0.80409634,\n z: -0.008229935,\n ),\n ),\n translation: (\n x: 0.35011238,\n y: 1.0827671,\n z: -1.0007166,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435668,\n y: 0.0000000000003760324,\n z: 0.000000000000027177064,\n ),\n y_axis: (\n x: -0.000000000000023327098,\n y: -0.012727253,\n z: 1.2435018,\n ),\n z_axis: (\n x: 0.00000000000037629082,\n y: -1.2435018,\n z: -0.012727253,\n ),\n ),\n translation: (\n x: -0.43538812,\n y: -1.2306123,\n z: -1.3591592,\n ),\n )),\n },\n ),\n 25: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 20,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0000000055879354,\n y: 0.0096595865,\n z: -0.000000068335794,\n ),\n rotation: (\n x: 0.110856906,\n y: 0.0043972307,\n z: 0.016644903,\n w: 0.9936872,\n ),\n scale: (\n x: 0.99996513,\n y: 1.0000671,\n z: 0.99996746,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12536130446972954018,\n name: \"DEF-nose.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0000000055879354,\n y: 0.0096595865,\n z: -0.000000068335794,\n ),\n rotation: (\n x: 0.110856906,\n y: 0.0043972307,\n z: 0.016644903,\n w: 0.9936872,\n ),\n scale: (\n x: 0.99996513,\n y: 1.0000671,\n z: 0.99996746,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.803913,\n y: -0.01200916,\n z: -0.013821544,\n ),\n y_axis: (\n x: -0.017310381,\n y: -0.30027622,\n z: -0.74580604,\n ),\n z_axis: (\n x: 0.0059768115,\n y: 0.74585813,\n z: -0.30045128,\n ),\n ),\n translation: (\n x: 0.35020107,\n y: 1.0891192,\n z: -0.9915994,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2432705,\n y: -0.026764309,\n z: 0.009242977,\n ),\n y_axis: (\n x: -0.018574463,\n y: -0.4643469,\n z: 1.1534963,\n ),\n z_axis: (\n x: -0.02137824,\n y: -1.1532546,\n z: -0.46463487,\n ),\n ),\n translation: (\n x: -0.43636352,\n y: -0.62846464,\n z: -1.7202635,\n ),\n )),\n },\n ),\n 26: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 21,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.014026254,\n y: 1.3605889,\n z: -0.0019644499,\n ),\n rotation: (\n x: -0.23619555,\n y: 0.6360578,\n z: 0.67916095,\n w: 0.27996898,\n ),\n scale: (\n x: 0.99999136,\n y: 1.000017,\n z: 0.9999914,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 955012332037807640,\n name: \"DEF-nose.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.014026254,\n y: 1.3605889,\n z: -0.0019644499,\n ),\n rotation: (\n x: -0.23619555,\n y: 0.6360578,\n z: 0.67916095,\n w: 0.27996898,\n ),\n scale: (\n x: 0.99999136,\n y: 1.000017,\n z: 0.9999914,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.58834946,\n y: 0.06418576,\n z: -0.544383,\n ),\n y_axis: (\n x: -0.54743147,\n y: -0.02741828,\n z: 0.58841133,\n ),\n z_axis: (\n x: 0.028404575,\n y: 0.80109686,\n z: 0.06375502,\n ),\n ),\n translation: (\n x: 0.36139172,\n y: 1.0941019,\n z: -0.99733514,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.9098735,\n y: -0.846551,\n z: 0.043927208,\n ),\n y_axis: (\n x: 0.099262215,\n y: -0.04239963,\n z: 1.2388842,\n ),\n z_axis: (\n x: -0.8418801,\n y: 0.9099226,\n z: 0.09859636,\n ),\n ),\n translation: (\n x: -0.6194188,\n y: 1.2598238,\n z: -1.2730069,\n ),\n )),\n },\n ),\n 27: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 22,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.014027327,\n y: 1.3605889,\n z: -0.0019644499,\n ),\n rotation: (\n x: 0.23619764,\n y: 0.63605684,\n z: 0.6791602,\n w: -0.2799712,\n ),\n scale: (\n x: 0.9999883,\n y: 1.0000231,\n z: 0.99998826,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15567506659244206260,\n name: \"DEF-nose.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.014027327,\n y: 1.3605889,\n z: -0.0019644499,\n ),\n rotation: (\n x: 0.23619764,\n y: 0.63605684,\n z: 0.6791602,\n w: -0.2799712,\n ),\n scale: (\n x: 0.9999883,\n y: 1.0000231,\n z: 0.99998826,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.58834404,\n y: -0.06418588,\n z: 0.54438514,\n ),\n y_axis: (\n x: 0.5474387,\n y: -0.02741835,\n z: 0.5884113,\n ),\n z_axis: (\n x: -0.02840439,\n y: 0.80109435,\n z: 0.063755155,\n ),\n ),\n translation: (\n x: 0.33883277,\n y: 1.0941019,\n z: -0.99733514,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.9098707,\n y: 0.8465519,\n z: -0.04392716,\n ),\n y_axis: (\n x: -0.09926304,\n y: -0.04239921,\n z: 1.238888,\n ),\n z_axis: (\n x: 0.8418887,\n y: 0.9099116,\n z: 0.09859718,\n ),\n ),\n translation: (\n x: 1.2565432,\n y: 0.66703635,\n z: -1.2422513,\n ),\n )),\n },\n ),\n 28: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 23,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.03892362,\n y: 1.4065202,\n z: -0.052212834,\n ),\n rotation: (\n x: -0.50260365,\n y: 0.50324047,\n z: 0.49702534,\n w: -0.4970961,\n ),\n scale: (\n x: 1.0000001,\n y: 0.9999996,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12179034412417901657,\n name: \"DEF-eye_master.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.03892362,\n y: 1.4065202,\n z: -0.052212834,\n ),\n rotation: (\n x: -0.50260365,\n y: 0.50324047,\n z: 0.49702534,\n w: -0.4970961,\n ),\n scale: (\n x: 1.0000001,\n y: 0.9999996,\n z: 1.0,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.000458598,\n y: -0.80413836,\n z: 0.00056632154,\n ),\n y_axis: (\n x: -0.009426322,\n y: 0.00057156966,\n z: 0.8040828,\n ),\n z_axis: (\n x: -0.80408317,\n y: 0.00045183976,\n z: -0.009426757,\n ),\n ),\n translation: (\n x: 0.38141266,\n y: 1.131037,\n z: -1.0377418,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.00070906495,\n y: -0.014577593,\n z: -1.243481,\n ),\n y_axis: (\n x: -1.243566,\n y: 0.0008840463,\n z: 0.0006988874,\n ),\n z_axis: (\n x: 0.00087565696,\n y: 1.2434814,\n z: -0.014577917,\n ),\n ),\n translation: (\n x: 1.4076984,\n y: 1.2949728,\n z: 0.45836082,\n ),\n )),\n },\n ),\n 29: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 24,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000074505806,\n y: 0.017641604,\n z: -0.000000029802322,\n ),\n rotation: (\n x: 0.20679732,\n y: 0.014154065,\n z: -0.15862872,\n w: 0.96533483,\n ),\n scale: (\n x: 1.002308,\n y: 0.9951915,\n z: 1.0025251,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9203777093992465967,\n name: \"DEF-lid.B.L.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000074505806,\n y: 0.017641604,\n z: -0.000000029802322,\n ),\n rotation: (\n x: 0.20679732,\n y: 0.014154065,\n z: -0.15862872,\n w: 0.96533483,\n ),\n scale: (\n x: 1.002308,\n y: 0.9951915,\n z: 1.0025251,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.24170643,\n y: 0.487456,\n z: 0.59545404,\n ),\n y_axis: (\n x: 0.4080344,\n y: 0.6041245,\n z: -0.32985225,\n ),\n z_axis: (\n x: -0.6498824,\n y: 0.20052677,\n z: -0.43201444,\n ),\n ),\n translation: (\n x: 0.39846012,\n y: 1.1232173,\n z: -1.0243715,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.37469104,\n y: 0.6345783,\n z: -1.0009581,\n ),\n y_axis: (\n x: 0.75120765,\n y: 0.94495803,\n z: 0.31390864,\n ),\n z_axis: (\n x: 0.91233605,\n y: -0.5159824,\n z: -0.6632832,\n ),\n ),\n translation: (\n x: 0.24010098,\n y: -1.842805,\n z: -0.63319415,\n ),\n )),\n },\n ),\n 30: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 25,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000022351742,\n y: 0.018302545,\n z: 0.000000024214387,\n ),\n rotation: (\n x: 0.31420818,\n y: 0.012877992,\n z: -0.24024364,\n w: 0.9183622,\n ),\n scale: (\n x: 0.98983335,\n y: 1.0212759,\n z: 0.9891742,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18266451632329864495,\n name: \"DEF-lid.T.L.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000022351742,\n y: 0.018302545,\n z: 0.000000024214387,\n ),\n rotation: (\n x: 0.31420818,\n y: 0.012877992,\n z: -0.24024364,\n w: 0.9183622,\n ),\n scale: (\n x: 0.98983335,\n y: 1.0212759,\n z: 0.9891742,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.52027315,\n y: -0.43138477,\n z: 0.41985765,\n ),\n y_axis: (\n x: -0.39561892,\n y: -0.6932867,\n z: -0.18984199,\n ),\n z_axis: (\n x: 0.4552847,\n y: -0.10730122,\n z: -0.6459401,\n ),\n ),\n translation: (\n x: 0.3722893,\n y: 1.1393753,\n z: -1.0185754,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.82160497,\n y: -0.62218416,\n z: 0.716899,\n ),\n y_axis: (\n x: -0.6573169,\n y: -1.0133704,\n z: -0.12942266,\n ),\n z_axis: (\n x: 0.6882915,\n y: -0.27020314,\n z: -1.0213324,\n ),\n ),\n translation: (\n x: 1.1441327,\n y: 1.1110194,\n z: -1.1597369,\n ),\n )),\n },\n ),\n 31: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 26,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000048763468,\n y: 0.026824642,\n z: 0.00000005203765,\n ),\n rotation: (\n x: -0.0000000002809806,\n y: 0.00032350796,\n z: -0.0000022223694,\n w: 1.0,\n ),\n scale: (\n x: 1.0000001,\n y: 1.0,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 708598158688698797,\n name: \"DEF-eye_iris.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000048763468,\n y: 0.026824642,\n z: 0.00000005203765,\n ),\n rotation: (\n x: -0.0000000002809806,\n y: 0.00032350796,\n z: -0.0000022223694,\n w: 1.0,\n ),\n scale: (\n x: 1.0000001,\n y: 1.0,\n z: 0.99999994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.00023539833,\n y: -0.8041383,\n z: 0.0005679604,\n ),\n y_axis: (\n x: -0.009427065,\n y: 0.00056526344,\n z: 0.80408263,\n ),\n z_axis: (\n x: -0.80408305,\n y: -0.00024198246,\n z: -0.009426868,\n ),\n ),\n translation: (\n x: 0.38115972,\n y: 1.1310523,\n z: -1.0161725,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.0003639424,\n y: -0.014578531,\n z: -1.2434816,\n ),\n y_axis: (\n x: -1.2435665,\n y: 0.00087399967,\n z: -0.00037430553,\n ),\n z_axis: (\n x: 0.0008784838,\n y: 1.2434818,\n z: -0.014578315,\n ),\n ),\n translation: (\n x: 1.4072926,\n y: 1.2681602,\n z: 0.4595744,\n ),\n )),\n },\n ),\n 32: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 27,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.038924277,\n y: 1.4065202,\n z: -0.052212834,\n ),\n rotation: (\n x: 0.50260365,\n y: 0.5032406,\n z: 0.49702534,\n w: 0.49709603,\n ),\n scale: (\n x: 1.0,\n y: 0.99999994,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12476158725425951894,\n name: \"DEF-eye_master.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.038924277,\n y: 1.4065202,\n z: -0.052212834,\n ),\n rotation: (\n x: 0.50260365,\n y: 0.5032406,\n z: 0.49702534,\n w: 0.49709603,\n ),\n scale: (\n x: 1.0,\n y: 0.99999994,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.00045878967,\n y: 0.8041383,\n z: -0.00056636945,\n ),\n y_axis: (\n x: 0.009426469,\n y: 0.00057156984,\n z: 0.8040831,\n ),\n z_axis: (\n x: 0.80408335,\n y: 0.00045198362,\n z: -0.0094269505,\n ),\n ),\n translation: (\n x: 0.31881216,\n y: 1.131037,\n z: -1.0377418,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.0007092875,\n y: 0.014577883,\n z: 1.2434808,\n ),\n y_axis: (\n x: 1.243566,\n y: 0.0008841237,\n z: 0.0006991826,\n ),\n z_axis: (\n x: -0.0008756543,\n y: 1.2434809,\n z: -0.014578136,\n ),\n ),\n translation: (\n x: -1.4072018,\n y: 1.2847645,\n z: -0.41235596,\n ),\n )),\n },\n ),\n 33: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 28,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000026077032,\n y: 0.017641544,\n z: -0.000000074505806,\n ),\n rotation: (\n x: 0.20679319,\n y: -0.014157609,\n z: 0.15864211,\n w: 0.9653335,\n ),\n scale: (\n x: 1.0023099,\n y: 0.9951877,\n z: 1.0025268,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9791648691772608385,\n name: \"DEF-lid.B.R.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000026077032,\n y: 0.017641544,\n z: -0.000000074505806,\n ),\n rotation: (\n x: 0.20679319,\n y: -0.014157609,\n z: 0.15864211,\n w: 0.9653335,\n ),\n scale: (\n x: 1.0023099,\n y: 0.9951877,\n z: 1.0025268,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.24171683,\n y: -0.48745546,\n z: -0.5954541,\n ),\n y_axis: (\n x: -0.40799013,\n y: 0.60413545,\n z: -0.32983136,\n ),\n z_axis: (\n x: 0.6499009,\n y: 0.20056425,\n z: -0.43200666,\n ),\n ),\n translation: (\n x: 0.30176455,\n y: 1.1232159,\n z: -1.0243714,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.37467527,\n y: -0.63461334,\n z: 1.0009506,\n ),\n y_axis: (\n x: -0.7511502,\n y: 0.9449842,\n z: 0.31386104,\n ),\n z_axis: (\n x: -0.9123834,\n y: -0.5159775,\n z: -0.6632583,\n ),\n ),\n translation: (\n x: 0.022148132,\n y: -1.39847,\n z: -1.334008,\n ),\n )),\n },\n ),\n 34: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 29,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000018626451,\n y: 0.018302552,\n z: -0.000000063329935,\n ),\n rotation: (\n x: 0.31422332,\n y: -0.012871618,\n z: 0.24023628,\n w: 0.918359,\n ),\n scale: (\n x: 0.9898307,\n y: 1.0212837,\n z: 0.98916906,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4085010346607589104,\n name: \"DEF-lid.T.R.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000018626451,\n y: 0.018302552,\n z: -0.000000063329935,\n ),\n rotation: (\n x: 0.31422332,\n y: -0.012871618,\n z: 0.24023628,\n w: 0.918359,\n ),\n scale: (\n x: 0.9898307,\n y: 1.0212837,\n z: 0.98916906,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.5202752,\n y: 0.43137816,\n z: -0.41985822,\n ),\n y_axis: (\n x: 0.39567393,\n y: -0.6932594,\n z: -0.1898348,\n ),\n z_axis: (\n x: -0.45528644,\n y: -0.107265726,\n z: -0.6459388,\n ),\n ),\n translation: (\n x: 0.3279355,\n y: 1.1393747,\n z: -1.0185755,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.8215858,\n y: 0.62214786,\n z: -0.7168711,\n ),\n y_axis: (\n x: 0.65738016,\n y: -1.013376,\n z: -0.12947425,\n ),\n z_axis: (\n x: -0.68825597,\n y: -0.27023453,\n z: -1.021351,\n ),\n ),\n translation: (\n x: -1.7194703,\n y: 0.67533636,\n z: -0.657716,\n ),\n )),\n },\n ),\n 35: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 30,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000019639265,\n y: 0.026824344,\n z: -0.000000031490345,\n ),\n rotation: (\n x: 0.00000000018415858,\n y: -0.00032350802,\n z: 0.000002222878,\n w: 1.0,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0,\n z: 0.9999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11773759275882309225,\n name: \"DEF-eye_iris.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000019639265,\n y: 0.026824344,\n z: -0.000000031490345,\n ),\n rotation: (\n x: 0.00000000018415858,\n y: -0.00032350802,\n z: 0.000002222878,\n w: 1.0,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0,\n z: 0.9999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.00023511099,\n y: 0.80413824,\n z: -0.00056810264,\n ),\n y_axis: (\n x: 0.009426063,\n y: 0.00056526286,\n z: 0.8040831,\n ),\n z_axis: (\n x: 0.8040833,\n y: -0.00024186276,\n z: -0.009426007,\n ),\n ),\n translation: (\n x: 0.31906494,\n y: 1.1310524,\n z: -1.0161728,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.0003637582,\n y: 0.014577188,\n z: 1.2434813,\n ),\n y_axis: (\n x: 1.2435665,\n y: 0.0008742248,\n z: -0.0003738626,\n ),\n z_axis: (\n x: -0.00087847986,\n y: 1.243481,\n z: -0.014576754,\n ),\n ),\n translation: (\n x: -1.4075476,\n y: 1.2579516,\n z: -0.41114092,\n ),\n )),\n },\n ),\n 36: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 31,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000003874302,\n y: 1.3371471,\n z: -0.008412242,\n ),\n rotation: (\n x: 0.70874864,\n y: 0.00000000000014485696,\n z: 0.00000000000012525548,\n w: -0.7054611,\n ),\n scale: (\n x: 1.0,\n y: 0.9999997,\n z: 0.99999964,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18012796943927027661,\n name: \"DEF-teeth.B\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000003874302,\n y: 1.3371471,\n z: -0.008412242,\n ),\n rotation: (\n x: 0.70874864,\n y: 0.00000000000014485696,\n z: 0.00000000000012525548,\n w: -0.7054611,\n ),\n scale: (\n x: 1.0,\n y: 0.9999997,\n z: 0.99999964,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041385,\n y: 0.000000000000023005286,\n z: 0.00000000000030712558,\n ),\n y_axis: (\n x: 0.0000000000003072291,\n y: -0.003738665,\n z: -0.80412954,\n ),\n z_axis: (\n x: -0.000000000000021577114,\n y: 0.8041295,\n z: -0.0037386646,\n ),\n ),\n translation: (\n x: 0.35011238,\n y: 1.0752515,\n z: -1.0025201,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.243567,\n y: 0.0000000000004751174,\n z: -0.00000000000003336814,\n ),\n y_axis: (\n x: 0.00000000000003557672,\n y: -0.005781694,\n z: 1.2435539,\n ),\n z_axis: (\n x: 0.000000000000474957,\n y: -1.2435539,\n z: -0.005781695,\n ),\n ),\n translation: (\n x: -0.4353882,\n y: -1.240471,\n z: -1.3429295,\n ),\n )),\n },\n ),\n 37: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 32,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000029801715,\n y: 0.019996595,\n z: -0.000000045576797,\n ),\n rotation: (\n x: -0.21408515,\n y: -0.00000021305972,\n z: -0.0000009721538,\n w: 0.97681504,\n ),\n scale: (\n x: 0.99999577,\n y: 1.0000072,\n z: 0.99999845,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6267547875699012781,\n name: \"DEF-tongue.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000029801715,\n y: 0.019996595,\n z: -0.000000045576797,\n ),\n rotation: (\n x: -0.21408515,\n y: -0.00000021305972,\n z: -0.0000009721538,\n w: 0.97681504,\n ),\n scale: (\n x: 0.99999577,\n y: 1.0000072,\n z: 0.99999845,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.80413663,\n y: 0.000000669726,\n z: 0.000001453711,\n ),\n y_axis: (\n x: 0.0000016006222,\n y: -0.3364748,\n z: -0.73036194,\n ),\n z_axis: (\n x: 0.000000000008930587,\n y: 0.73035973,\n z: -0.33646947,\n ),\n ),\n translation: (\n x: 0.3501123,\n y: 1.0739014,\n z: -1.0380951,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435697,\n y: 0.0000024752035,\n z: -0.000000000010057158,\n ),\n y_axis: (\n x: 0.0000010357061,\n y: -0.52033466,\n z: 1.1294714,\n ),\n z_axis: (\n x: 0.0000022481954,\n y: -1.129468,\n z: -0.52034295,\n ),\n ),\n translation: (\n x: -0.43538782,\n y: -0.6137079,\n z: -1.7531064,\n ),\n )),\n },\n ),\n 38: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 33,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000032782555,\n y: 1.351748,\n z: -0.121840954,\n ),\n rotation: (\n x: 0.8802697,\n y: 0.000000169685,\n z: 0.00000031480897,\n w: 0.4744738,\n ),\n scale: (\n x: 1.0,\n y: 0.9999998,\n z: 0.9999996,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11893174428051106710,\n name: \"DEF-jaw_master\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000032782555,\n y: 1.351748,\n z: -0.121840954,\n ),\n rotation: (\n x: 0.8802697,\n y: 0.000000169685,\n z: 0.00000031480897,\n w: 0.4744738,\n ),\n scale: (\n x: 1.0,\n y: 0.9999998,\n z: 0.9999996,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041385,\n y: 0.0000004804521,\n z: 0.00000031619646,\n ),\n y_axis: (\n x: -0.00000000000009141995,\n y: -0.44207463,\n z: 0.67172074,\n ),\n z_axis: (\n x: 0.0000005751645,\n y: -0.67172056,\n z: -0.44207454,\n ),\n ),\n translation: (\n x: 0.3501124,\n y: 1.0869926,\n z: -1.0937325,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.243567,\n y: -0.000000000000027329254,\n z: 0.00000088946865,\n ),\n y_axis: (\n x: 0.00000074299925,\n y: -0.68365014,\n z: -1.0387886,\n ),\n z_axis: (\n x: 0.00000048898477,\n y: 1.0387883,\n z: -0.6836503,\n ),\n ),\n translation: (\n x: -0.4353885,\n y: 1.8792791,\n z: 0.3814246,\n ),\n )),\n },\n ),\n 39: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 34,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000015043042,\n y: 0.014125079,\n z: 0.00000011821727,\n ),\n rotation: (\n x: -0.37329552,\n y: -0.0000013305475,\n z: -0.0000034846971,\n w: 0.92771256,\n ),\n scale: (\n x: 1.000004,\n y: 1.0,\n z: 0.99999547,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14592791315165727011,\n name: \"DEF-chin.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000015043042,\n y: 0.014125079,\n z: 0.00000011821727,\n ),\n rotation: (\n x: -0.37329552,\n y: -0.0000013305475,\n z: -0.0000034846971,\n w: 0.92771256,\n ),\n scale: (\n x: 1.000004,\n y: 1.0,\n z: 0.99999547,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041369,\n y: -0.0000026367118,\n z: 0.0000032269975,\n ),\n y_axis: (\n x: 0.0000011668103,\n y: 0.74027073,\n z: 0.31407347,\n ),\n z_axis: (\n x: -0.0000040005966,\n y: -0.31405857,\n z: 0.7402725,\n ),\n ),\n translation: (\n x: 0.35011223,\n y: 1.0444213,\n z: -1.0118126,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435694,\n y: 0.0000018046981,\n z: -0.000006186645,\n ),\n y_axis: (\n x: -0.0000040774867,\n y: 1.1447992,\n z: -0.485701,\n ),\n z_axis: (\n x: 0.000004990662,\n y: 0.48567796,\n z: 1.1447965,\n ),\n ),\n translation: (\n x: -0.43537953,\n y: -0.7042383,\n z: 1.6655982,\n ),\n )),\n },\n ),\n 40: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 35,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000004172325,\n y: 1.3075068,\n z: -0.08405161,\n ),\n rotation: (\n x: 0.7964777,\n y: 0.000001153314,\n z: 0.0000015191627,\n w: 0.60466796,\n ),\n scale: (\n x: 1.0,\n y: 0.9999997,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5795822014188452907,\n name: \"DEF-jaw\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000004172325,\n y: 1.3075068,\n z: -0.08405161,\n ),\n rotation: (\n x: 0.7964777,\n y: 0.000001153314,\n z: 0.0000015191627,\n w: 0.60466796,\n ),\n scale: (\n x: 1.0,\n y: 0.9999997,\n z: 1.0,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041385,\n y: 0.0000029546907,\n z: 0.00000082441426,\n ),\n y_axis: (\n x: -0.00000000000018283987,\n y: -0.2161149,\n z: 0.77455324,\n ),\n z_axis: (\n x: 0.000003067549,\n y: -0.7745535,\n z: -0.21611495,\n ),\n ),\n translation: (\n x: 0.35011235,\n y: 1.0514165,\n z: -1.0633446,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435669,\n y: -0.000000000000218634,\n z: 0.0000047438366,\n ),\n y_axis: (\n x: 0.0000045693064,\n y: -0.3342129,\n z: -1.1978147,\n ),\n z_axis: (\n x: 0.0000012749225,\n y: 1.1978151,\n z: -0.33421278,\n ),\n ),\n translation: (\n x: -0.43539158,\n y: 1.6250871,\n z: 0.9040171,\n ),\n )),\n },\n ),\n 41: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 36,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000059604645,\n y: 0.07027218,\n z: 0.00000017881393,\n ),\n rotation: (\n x: -0.5186842,\n y: 0.0016960792,\n z: 0.35712358,\n w: 0.7768054,\n ),\n scale: (\n x: 0.9797646,\n y: 1.0417325,\n z: 0.97976583,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13368040984610527760,\n name: \"DEF-chin.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000059604645,\n y: 0.07027218,\n z: 0.00000017881393,\n ),\n rotation: (\n x: -0.5186842,\n y: 0.0016960792,\n z: 0.35712358,\n w: 0.7768054,\n ),\n scale: (\n x: 0.9797646,\n y: 1.0417325,\n z: 0.97976583,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.3965739,\n y: -0.28073615,\n z: 0.620201,\n ),\n y_axis: (\n x: -0.21149161,\n y: 0.6790505,\n z: 0.44260502,\n ),\n z_axis: (\n x: -0.6510746,\n y: -0.36611637,\n z: 0.25058934,\n ),\n ),\n translation: (\n x: 0.37798616,\n y: 1.0444913,\n z: -1.0282217,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.63887686,\n y: -0.3013849,\n z: -1.048878,\n ),\n y_axis: (\n x: -0.45226377,\n y: 0.96766686,\n z: -0.58980864,\n ),\n z_axis: (\n x: 0.999146,\n y: 0.63073176,\n z: 0.40370297,\n ),\n ),\n translation: (\n x: 1.2582426,\n y: -0.24826825,\n z: 1.4276075,\n ),\n )),\n },\n ),\n 42: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 37,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000014901161,\n y: 0.07027282,\n z: -0.000000007450581,\n ),\n rotation: (\n x: -0.51868576,\n y: -0.0016948244,\n z: -0.35712287,\n w: 0.7768046,\n ),\n scale: (\n x: 0.97976565,\n y: 1.0417308,\n z: 0.97976524,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12523388222297113054,\n name: \"DEF-chin.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000014901161,\n y: 0.07027282,\n z: -0.000000007450581,\n ),\n rotation: (\n x: -0.51868576,\n y: -0.0016948244,\n z: -0.35712287,\n w: 0.7768046,\n ),\n scale: (\n x: 0.97976565,\n y: 1.0417308,\n z: 0.97976524,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.39657316,\n y: 0.28073886,\n z: -0.62020147,\n ),\n y_axis: (\n x: 0.21148783,\n y: 0.6790485,\n z: 0.44260532,\n ),\n z_axis: (\n x: 0.65107524,\n y: -0.36611483,\n z: 0.2505925,\n ),\n ),\n translation: (\n x: 0.32223874,\n y: 1.044491,\n z: -1.0282211,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.6388793,\n y: 0.30138054,\n z: 1.0488793,\n ),\n y_axis: (\n x: 0.4522655,\n y: 0.9676709,\n z: -0.5898043,\n ),\n z_axis: (\n x: -0.9991417,\n y: 0.63073415,\n z: 0.40370163,\n ),\n ),\n translation: (\n x: -1.7055976,\n y: -0.45930588,\n z: 0.6931503,\n ),\n )),\n },\n ),\n 43: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 38,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000017136335,\n y: 0.010280877,\n z: 0.000000037252903,\n ),\n rotation: (\n x: 0.008547257,\n y: -0.08109962,\n z: 0.15406595,\n w: 0.9846895,\n ),\n scale: (\n x: 1.0119565,\n y: 0.9768293,\n z: 1.011627,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18088193694388964900,\n name: \"DEF-lip.T.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000017136335,\n y: 0.010280877,\n z: 0.000000037252903,\n ),\n rotation: (\n x: 0.008547257,\n y: -0.08109962,\n z: 0.15406595,\n w: 0.9846895,\n ),\n scale: (\n x: 1.0119565,\n y: 0.9768293,\n z: 1.011627,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.42234865,\n y: 0.051508397,\n z: 0.69449764,\n ),\n y_axis: (\n x: 0.66939753,\n y: -0.030517021,\n z: -0.4067378,\n ),\n z_axis: (\n x: 0.0005504925,\n y: 0.81221706,\n z: -0.06048672,\n ),\n ),\n translation: (\n x: 0.3581177,\n y: 1.0800043,\n z: -0.9999241,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.63887125,\n y: 1.090792,\n z: 0.00046844836,\n ),\n y_axis: (\n x: 0.07743596,\n y: -0.049864247,\n z: 1.2244138,\n ),\n z_axis: (\n x: 1.0456264,\n y: -0.659651,\n z: -0.09109525,\n ),\n ),\n translation: (\n x: 0.73312473,\n y: -0.99637926,\n z: -1.4136282,\n ),\n )),\n },\n ),\n 44: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 39,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000007450581,\n y: 0.010280766,\n z: -0.00000008568168,\n ),\n rotation: (\n x: 0.00854344,\n y: 0.08109917,\n z: -0.154082,\n w: 0.98468715,\n ),\n scale: (\n x: 1.0119909,\n y: 0.97675544,\n z: 1.0116684,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9053504476489813688,\n name: \"DEF-lip.T.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000007450581,\n y: 0.010280766,\n z: -0.00000008568168,\n ),\n rotation: (\n x: 0.00854344,\n y: 0.08109917,\n z: -0.154082,\n w: 0.98468715,\n ),\n scale: (\n x: 1.0119909,\n y: 0.97675544,\n z: 1.0116684,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.42238474,\n y: -0.051506553,\n z: -0.6944915,\n ),\n y_axis: (\n x: -0.66937554,\n y: -0.030520855,\n z: -0.40672392,\n ),\n z_axis: (\n x: -0.00055057637,\n y: 0.8122306,\n z: -0.06048817,\n ),\n ),\n translation: (\n x: 0.3421065,\n y: 1.0800042,\n z: -0.999924,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.6388606,\n y: -1.0907999,\n z: -0.00047602435,\n ),\n y_axis: (\n x: -0.0774352,\n y: -0.049869716,\n z: 1.2243931,\n ),\n z_axis: (\n x: -1.0456091,\n y: -0.6597181,\n z: -0.0910959,\n ),\n ),\n translation: (\n x: -1.1804576,\n y: -0.23263872,\n z: -1.413276,\n ),\n )),\n },\n ),\n 45: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 40,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000011920929,\n y: 0.009838767,\n z: 0.00000020861626,\n ),\n rotation: (\n x: 0.16748782,\n y: 0.16030714,\n z: 0.20552082,\n w: 0.95079476,\n ),\n scale: (\n x: 0.9685754,\n y: 1.0656189,\n z: 0.9688693,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14506113311342826934,\n name: \"DEF-lip.B.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000011920929,\n y: 0.009838767,\n z: 0.00000020861626,\n ),\n rotation: (\n x: 0.16748782,\n y: 0.16030714,\n z: 0.20552082,\n w: 0.95079476,\n ),\n scale: (\n x: 0.9685754,\n y: 1.0656189,\n z: 0.9688693,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.4383838,\n y: -0.18740311,\n z: 0.6156001,\n ),\n y_axis: (\n x: 0.67173064,\n y: 0.3975971,\n z: -0.35543603,\n ),\n z_axis: (\n x: -0.20853323,\n y: 0.6635365,\n z: 0.34999448,\n ),\n ),\n translation: (\n x: 0.35795677,\n y: 1.0742003,\n z: -1.0005163,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.7211737,\n y: 0.9116813,\n z: -0.34260613,\n ),\n y_axis: (\n x: -0.3095876,\n y: 0.54194534,\n z: 1.0949004,\n ),\n z_axis: (\n x: 1.01662,\n y: -0.4842495,\n z: 0.5772915,\n ),\n ),\n translation: (\n x: 1.091555,\n y: -1.3929999,\n z: -0.4759146,\n ),\n )),\n },\n ),\n 46: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 41,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000007450581,\n y: 0.009838767,\n z: 0.00000009126961,\n ),\n rotation: (\n x: 0.16749525,\n y: -0.1603064,\n z: -0.20554315,\n w: 0.9507888,\n ),\n scale: (\n x: 0.9685991,\n y: 1.0655549,\n z: 0.9689037,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15969980415204072109,\n name: \"DEF-lip.B.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000007450581,\n y: 0.009838767,\n z: 0.00000009126961,\n ),\n rotation: (\n x: 0.16749525,\n y: -0.1603064,\n z: -0.20554315,\n w: 0.9507888,\n ),\n scale: (\n x: 0.9685991,\n y: 1.0655549,\n z: 0.9689037,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.4384268,\n y: 0.18738884,\n z: -0.6155871,\n ),\n y_axis: (\n x: -0.6717156,\n y: 0.39758095,\n z: -0.35542613,\n ),\n z_axis: (\n x: 0.20855874,\n y: 0.66353697,\n z: 0.35000148,\n ),\n ),\n translation: (\n x: 0.3422673,\n y: 1.0742002,\n z: -1.000516,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.72115636,\n y: -0.91165876,\n z: 0.34259057,\n ),\n y_axis: (\n x: 0.30957326,\n y: 0.5420055,\n z: 1.0948875,\n ),\n z_axis: (\n x: -1.0166152,\n y: -0.48430166,\n z: 0.57728726,\n ),\n ),\n translation: (\n x: -1.5965116,\n y: -0.7547429,\n z: -0.7158007,\n ),\n )),\n },\n ),\n 47: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 42,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000029802322,\n y: 0.025579154,\n z: 0.000000026077032,\n ),\n rotation: (\n x: -0.28118876,\n y: 0.027964624,\n z: 0.27679214,\n w: 0.9184403,\n ),\n scale: (\n x: 0.9804175,\n y: 1.040753,\n z: 0.9799392,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1562629352996756224,\n name: \"DEF-brow.B.L.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000029802322,\n y: 0.025579154,\n z: 0.000000026077032,\n ),\n rotation: (\n x: -0.28118876,\n y: 0.027964624,\n z: 0.27679214,\n w: 0.9184403,\n ),\n scale: (\n x: 0.9804175,\n y: 1.040753,\n z: 0.9799392,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.6141562,\n y: 0.29535502,\n z: -0.38484335,\n ),\n y_axis: (\n x: -0.3461963,\n y: -0.75294137,\n z: 0.036920514,\n ),\n z_axis: (\n x: -0.35126886,\n y: 0.22988893,\n z: 0.68589,\n ),\n ),\n translation: (\n x: 0.37002215,\n y: 1.1427816,\n z: -1.011845,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.0073348,\n y: -0.55853397,\n z: -0.5351364,\n ),\n y_axis: (\n x: 0.43078753,\n y: -1.0677925,\n z: 0.2991867,\n ),\n z_axis: (\n x: -0.6602788,\n y: 0.07184545,\n z: 1.0836191,\n ),\n ),\n translation: (\n x: -0.7876597,\n y: 1.4996201,\n z: 0.95256186,\n ),\n )),\n },\n ),\n 48: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 43,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000074505806,\n y: 0.018314548,\n z: 0.00000008940697,\n ),\n rotation: (\n x: -0.028115863,\n y: -0.28913903,\n z: 0.1816857,\n w: 0.9394671,\n ),\n scale: (\n x: 1.0002162,\n y: 0.99978733,\n z: 0.99999195,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16914163148261392083,\n name: \"DEF-nose.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000074505806,\n y: 0.018314548,\n z: 0.00000008940697,\n ),\n rotation: (\n x: -0.028115863,\n y: -0.28913903,\n z: 0.1816857,\n w: 0.9394671,\n ),\n scale: (\n x: 1.0002162,\n y: 0.99978733,\n z: 0.99999195,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.7904071,\n y: -0.13668805,\n z: -0.06299982,\n ),\n y_axis: (\n x: 0.098423325,\n y: -0.7205898,\n z: 0.3408616,\n ),\n z_axis: (\n x: -0.114564605,\n y: 0.3275793,\n z: 0.7259219,\n ),\n ),\n translation: (\n x: 0.35877326,\n y: 1.1133585,\n z: -1.0064356,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.2207098,\n y: 0.15113392,\n z: -0.17690642,\n ),\n y_axis: (\n x: -0.21250278,\n y: -1.1173227,\n z: 0.50620425,\n ),\n z_axis: (\n x: -0.09675782,\n y: 0.52805454,\n z: 1.1212099,\n ),\n ),\n translation: (\n x: 0.5771693,\n y: 1.7212107,\n z: 0.6283081,\n ),\n )),\n },\n ),\n 49: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 44,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000014901161,\n y: 0.025579423,\n z: 0.000000034458935,\n ),\n rotation: (\n x: -0.28118184,\n y: -0.027965365,\n z: -0.2767868,\n w: 0.918444,\n ),\n scale: (\n x: 0.98041296,\n y: 1.0407629,\n z: 0.9799347,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10464729830164471764,\n name: \"DEF-brow.B.R.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000014901161,\n y: 0.025579423,\n z: 0.000000034458935,\n ),\n rotation: (\n x: -0.28118184,\n y: -0.027965365,\n z: -0.2767868,\n w: 0.918444,\n ),\n scale: (\n x: 0.98041296,\n y: 1.0407629,\n z: 0.9799347,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.61414975,\n y: -0.2953635,\n z: 0.38484266,\n ),\n y_axis: (\n x: 0.34621817,\n y: -0.75293916,\n z: 0.036922194,\n ),\n z_axis: (\n x: 0.3512634,\n y: 0.22989027,\n z: 0.68588513,\n ),\n ),\n translation: (\n x: 0.33020246,\n y: 1.1427814,\n z: -1.011845,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.0073267,\n y: 0.5585436,\n z: 0.5351328,\n ),\n y_axis: (\n x: -0.43081275,\n y: -1.0677749,\n z: 0.2992042,\n ),\n z_axis: (\n x: 0.66028064,\n y: 0.07184164,\n z: 1.0836264,\n ),\n ),\n translation: (\n x: 1.4930482,\n y: 1.1084933,\n z: 0.5778347,\n ),\n )),\n },\n ),\n 50: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 45,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000009685755,\n y: 0.018314436,\n z: -0.000000033527613,\n ),\n rotation: (\n x: -0.02810176,\n y: 0.28913656,\n z: -0.18168963,\n w: 0.9394674,\n ),\n scale: (\n x: 1.0002248,\n y: 0.99976724,\n z: 1.0000032,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5077476060660990214,\n name: \"DEF-nose.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000009685755,\n y: 0.018314436,\n z: -0.000000033527613,\n ),\n rotation: (\n x: -0.02810176,\n y: 0.28913656,\n z: -0.18168963,\n w: 0.9394674,\n ),\n scale: (\n x: 1.0002248,\n y: 0.99976724,\n z: 1.0000032,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.7904083,\n y: 0.13669947,\n z: 0.06300004,\n ),\n y_axis: (\n x: -0.098419465,\n y: -0.72057945,\n z: 0.34086803,\n ),\n z_axis: (\n x: 0.114570715,\n y: 0.32759097,\n z: 0.72591925,\n ),\n ),\n translation: (\n x: 0.34145132,\n y: 1.1133583,\n z: -1.0064359,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.2207043,\n y: -0.15114772,\n z: 0.17691478,\n ),\n y_axis: (\n x: 0.21250248,\n y: -1.117322,\n z: 0.50621563,\n ),\n z_axis: (\n x: 0.09676429,\n y: 0.5280776,\n z: 1.1211978,\n ),\n ),\n translation: (\n x: 0.2776068,\n y: 1.8270656,\n z: 0.5044066,\n ),\n )),\n },\n ),\n 51: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 46,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.08479953,\n y: 1.4094404,\n z: -0.07159948,\n ),\n rotation: (\n x: 0.408667,\n y: -0.3364701,\n z: -0.07641981,\n w: 0.8449492,\n ),\n scale: (\n x: 1.0000007,\n y: 0.9999981,\n z: 1.0000007,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 580892530821334128,\n name: \"DEF-brow.T.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.08479953,\n y: 1.4094404,\n z: -0.07159948,\n ),\n rotation: (\n x: 0.408667,\n y: -0.3364701,\n z: -0.07641981,\n w: 0.8449492,\n ),\n scale: (\n x: 1.0000007,\n y: 0.9999981,\n z: 1.0000007,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.6126701,\n y: -0.32499292,\n z: 0.4070068,\n ),\n y_axis: (\n x: -0.11729683,\n y: 0.5261489,\n z: 0.59669507,\n ),\n z_axis: (\n x: -0.50746065,\n y: -0.51398945,\n z: 0.35346603,\n ),\n ),\n translation: (\n x: 0.41830325,\n y: 1.1333853,\n z: -1.0533314,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9474676,\n y: -0.18139541,\n z: -0.7847657,\n ),\n y_axis: (\n x: -0.5025873,\n y: 0.81367064,\n z: -0.7948621,\n ),\n z_axis: (\n x: 0.6294182,\n y: 0.92276776,\n z: 0.5466198,\n ),\n ),\n translation: (\n x: 0.83628225,\n y: 0.12565613,\n z: 1.8049269,\n ),\n )),\n },\n ),\n 52: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 47,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000044703484,\n y: 0.03579071,\n z: 0.000000052154064,\n ),\n rotation: (\n x: 0.324906,\n y: 0.0063753426,\n z: 0.17686439,\n w: 0.9290396,\n ),\n scale: (\n x: 1.0007083,\n y: 1.0189823,\n z: 0.98356473,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7534868410743112834,\n name: \"DEF-brow.T.L.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000044703484,\n y: 0.03579071,\n z: 0.000000052154064,\n ),\n rotation: (\n x: 0.324906,\n y: 0.0063753426,\n z: 0.17686439,\n w: 0.9290396,\n ),\n scale: (\n x: 1.0007083,\n y: 1.0189823,\n z: 0.98356473,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.23880628,\n y: -0.09845449,\n z: 0.74912965,\n ),\n y_axis: (\n x: -0.7655127,\n y: -0.21186033,\n z: 0.24737725,\n ),\n z_axis: (\n x: 0.20006108,\n y: -0.7448263,\n z: -0.18659602,\n ),\n ),\n translation: (\n x: 0.3930539,\n y: 1.1618786,\n z: -1.0127358,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.42910355,\n y: -1.1051245,\n z: 0.25762364,\n ),\n y_axis: (\n x: -0.17899862,\n y: -0.37281907,\n z: -1.2128884,\n ),\n z_axis: (\n x: 1.1745684,\n y: 0.30329192,\n z: -0.2415289,\n ),\n ),\n translation: (\n x: 1.2288413,\n y: 1.1746986,\n z: 1.0633641,\n ),\n )),\n },\n ),\n 53: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 48,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0125057995,\n y: 1.4322529,\n z: -0.009139419,\n ),\n rotation: (\n x: 0.7832047,\n y: -0.35427332,\n z: 0.46406353,\n w: 0.21383615,\n ),\n scale: (\n x: 1.000001,\n y: 0.9999975,\n z: 1.000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8313468772091336899,\n name: \"DEF-brow.T.L.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0125057995,\n y: 1.4322529,\n z: -0.009139419,\n ),\n rotation: (\n x: 0.7832047,\n y: -0.35427332,\n z: 0.46406353,\n w: 0.21383615,\n ),\n scale: (\n x: 1.000001,\n y: 0.9999975,\n z: 1.000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.25593415,\n y: -0.28665146,\n z: 0.7063771,\n ),\n y_axis: (\n x: -0.6058398,\n y: -0.52874315,\n z: 0.0049408437,\n ),\n z_axis: (\n x: 0.46270218,\n y: -0.53376,\n z: -0.3842485,\n ),\n ),\n translation: (\n x: 0.36016908,\n y: 1.1517297,\n z: -1.0031048,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.3957908,\n y: -0.9369108,\n z: 0.71554846,\n ),\n y_axis: (\n x: -0.44329375,\n y: -0.81768334,\n z: -0.8254361,\n ),\n z_axis: (\n x: 1.092381,\n y: 0.007640879,\n z: -0.5942233,\n ),\n ),\n translation: (\n x: 1.4637756,\n y: 1.2868611,\n z: 0.096892595,\n ),\n )),\n },\n ),\n 54: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 49,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.08480039,\n y: 1.4094404,\n z: -0.07159948,\n ),\n rotation: (\n x: 0.408667,\n y: 0.3364701,\n z: 0.07641982,\n w: 0.8449492,\n ),\n scale: (\n x: 1.0000008,\n y: 0.99999803,\n z: 1.000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10165994655684084782,\n name: \"DEF-brow.T.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.08480039,\n y: 1.4094404,\n z: -0.07159948,\n ),\n rotation: (\n x: 0.408667,\n y: 0.3364701,\n z: 0.07641982,\n w: 0.8449492,\n ),\n scale: (\n x: 1.0000008,\n y: 0.99999803,\n z: 1.000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.61267024,\n y: 0.32499298,\n z: -0.4070068,\n ),\n y_axis: (\n x: 0.11729681,\n y: 0.52614886,\n z: 0.59669507,\n ),\n z_axis: (\n x: 0.5074608,\n y: -0.51398945,\n z: 0.3534661,\n ),\n ),\n translation: (\n x: 0.28192142,\n y: 1.1333853,\n z: -1.0533314,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9474674,\n y: 0.18139529,\n z: 0.78476554,\n ),\n y_axis: (\n x: 0.5025874,\n y: 0.81367064,\n z: -0.79486203,\n ),\n z_axis: (\n x: -0.6294181,\n y: 0.92276776,\n z: 0.54661965,\n ),\n ),\n translation: (\n x: -1.4997222,\n y: -0.0013613701,\n z: 1.2554142,\n ),\n )),\n },\n ),\n 55: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 50,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000016391277,\n y: 0.035790548,\n z: -0.000000044703484,\n ),\n rotation: (\n x: 0.3249062,\n y: -0.0063747675,\n z: -0.17686741,\n w: 0.92903894,\n ),\n scale: (\n x: 1.0007038,\n y: 1.0189892,\n z: 0.983562,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14650420213419327205,\n name: \"DEF-brow.T.R.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000016391277,\n y: 0.035790548,\n z: -0.000000044703484,\n ),\n rotation: (\n x: 0.3249062,\n y: -0.0063747675,\n z: -0.17686741,\n w: 0.92903894,\n ),\n scale: (\n x: 1.0007038,\n y: 1.0189892,\n z: 0.983562,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.23880568,\n y: 0.09845609,\n z: -0.74912715,\n ),\n y_axis: (\n x: 0.76551706,\n y: -0.21186255,\n z: 0.24737535,\n ),\n z_axis: (\n x: -0.20005722,\n y: -0.744825,\n z: -0.18659441,\n ),\n ),\n translation: (\n x: 0.3071706,\n y: 1.1618786,\n z: -1.0127361,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.42910078,\n y: 1.1051203,\n z: -0.25762564,\n ),\n y_axis: (\n x: 0.17900053,\n y: -0.37281197,\n z: -1.212891,\n ),\n z_axis: (\n x: -1.1745732,\n y: 0.30329084,\n z: -0.24153307,\n ),\n ),\n translation: (\n x: -1.5293167,\n y: 0.40085536,\n z: 1.2437578,\n ),\n )),\n },\n ),\n 56: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 51,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.012506664,\n y: 1.4322529,\n z: -0.009139419,\n ),\n rotation: (\n x: 0.7832033,\n y: 0.35427624,\n z: -0.46406284,\n w: 0.21383783,\n ),\n scale: (\n x: 1.0000008,\n y: 0.9999977,\n z: 1.000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16395509338148304691,\n name: \"DEF-brow.T.R.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.012506664,\n y: 1.4322529,\n z: -0.009139419,\n ),\n rotation: (\n x: 0.7832033,\n y: 0.35427624,\n z: -0.46406284,\n w: 0.21383783,\n ),\n scale: (\n x: 1.0000008,\n y: 0.9999977,\n z: 1.000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.25593182,\n y: 0.2866533,\n z: -0.7063771,\n ),\n y_axis: (\n x: 0.6058438,\n y: -0.52873874,\n z: 0.004940725,\n ),\n z_axis: (\n x: -0.46269834,\n y: -0.5337634,\n z: -0.3842484,\n ),\n ),\n translation: (\n x: 0.34005558,\n y: 1.1517297,\n z: -1.0031048,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.3957873,\n y: 0.9369166,\n z: -0.71554244,\n ),\n y_axis: (\n x: 0.44329667,\n y: -0.81767625,\n z: -0.82544136,\n ),\n z_axis: (\n x: -1.092381,\n y: 0.00764062,\n z: -0.59422314,\n ),\n ),\n translation: (\n x: -1.7409203,\n y: 0.63080263,\n z: 0.59794146,\n ),\n )),\n },\n ),\n 57: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 52,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000010430813,\n y: 0.04844305,\n z: -0.00000021979213,\n ),\n rotation: (\n x: 0.3168123,\n y: -0.012539995,\n z: 0.22005312,\n w: 0.92252004,\n ),\n scale: (\n x: 1.0444245,\n y: 0.92108977,\n z: 1.0395502,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18154003761232898998,\n name: \"DEF-cheek.B.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000010430813,\n y: 0.04844305,\n z: -0.00000021979213,\n ),\n rotation: (\n x: 0.3168123,\n y: -0.012539995,\n z: 0.22005312,\n w: 0.92252004,\n ),\n scale: (\n x: 1.0444245,\n y: 0.92108977,\n z: 1.0395502,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.6577921,\n y: 0.08256523,\n z: 0.50982684,\n ),\n y_axis: (\n x: 0.24302003,\n y: 0.58398676,\n z: -0.3911794,\n ),\n z_axis: (\n x: -0.4567723,\n y: 0.49821156,\n z: 0.49259105,\n ),\n ),\n translation: (\n x: 0.40073505,\n y: 1.0889943,\n z: -1.0239227,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9279685,\n y: 0.4102402,\n z: -0.63465565,\n ),\n y_axis: (\n x: 0.11340157,\n y: 1.0709271,\n z: 0.73308164,\n ),\n z_axis: (\n x: 0.7457957,\n y: -0.7027369,\n z: 0.70012873,\n ),\n ),\n translation: (\n x: 0.268274,\n y: -2.0501795,\n z: 0.1728847,\n ),\n )),\n },\n ),\n 58: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 53,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000044703484,\n y: 0.04844308,\n z: -0.000000011175871,\n ),\n rotation: (\n x: 0.31681293,\n y: 0.012540667,\n z: -0.22005501,\n w: 0.9225194,\n ),\n scale: (\n x: 1.0444295,\n y: 0.9210822,\n z: 1.0395539,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6009775075756531539,\n name: \"DEF-cheek.B.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000044703484,\n y: 0.04844308,\n z: -0.000000011175871,\n ),\n rotation: (\n x: 0.31681293,\n y: 0.012540667,\n z: -0.22005501,\n w: 0.9225194,\n ),\n scale: (\n x: 1.0444295,\n y: 0.9210822,\n z: 1.0395539,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.6577971,\n y: -0.08256969,\n z: -0.50982463,\n ),\n y_axis: (\n x: -0.24301668,\n y: 0.5839824,\n z: -0.39117807,\n ),\n z_axis: (\n x: 0.45677704,\n y: 0.49820888,\n z: 0.49259454,\n ),\n ),\n translation: (\n x: 0.2994893,\n y: 1.0889945,\n z: -1.0239228,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.92796487,\n y: -0.4102307,\n z: 0.634652,\n ),\n y_axis: (\n x: -0.11340551,\n y: 1.070939,\n z: 0.7330794,\n ),\n z_axis: (\n x: -0.7457927,\n y: -0.7027429,\n z: 0.7001272,\n ),\n ),\n translation: (\n x: -0.9180517,\n y: -1.7629414,\n z: -0.27151465,\n ),\n )),\n },\n ),\n 59: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 54,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000022351742,\n y: 0.06995425,\n z: 0.000000048428774,\n ),\n rotation: (\n x: 0.3529464,\n y: 0.032512296,\n z: 0.27209958,\n w: 0.8946137,\n ),\n scale: (\n x: 1.0060209,\n y: 0.9848293,\n z: 1.0101064,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 2543503771479967802,\n name: \"DEF-cheek.T.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000022351742,\n y: 0.06995425,\n z: 0.000000048428774,\n ),\n rotation: (\n x: 0.3529464,\n y: 0.032512296,\n z: 0.27209958,\n w: 0.8946137,\n ),\n scale: (\n x: 1.0060209,\n y: 0.9848293,\n z: 1.0101064,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.11196895,\n y: -0.80327266,\n z: -0.015640507,\n ),\n y_axis: (\n x: -0.7652677,\n y: 0.12006445,\n z: 0.16176848,\n ),\n z_axis: (\n x: -0.18420255,\n y: 0.023775423,\n z: -0.7897366,\n ),\n ),\n translation: (\n x: 0.3893981,\n y: 1.1090399,\n z: -1.0133886,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.1895997,\n y: -1.2197547,\n z: -0.24609777,\n ),\n y_axis: (\n x: -1.2186255,\n y: 0.16438687,\n z: 0.057807293,\n ),\n z_axis: (\n x: 0.007535944,\n y: 0.2894513,\n z: -1.2071034,\n ),\n ),\n translation: (\n x: 1.4329709,\n y: 0.5859852,\n z: -1.1915454,\n ),\n )),\n },\n ),\n 60: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 55,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000022351742,\n y: 0.06995438,\n z: -0.000000026077032,\n ),\n rotation: (\n x: 0.35295117,\n y: -0.032513596,\n z: -0.27210045,\n w: 0.8946115,\n ),\n scale: (\n x: 1.0060182,\n y: 0.9848342,\n z: 1.0101043,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7430735993516121662,\n name: \"DEF-cheek.T.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000022351742,\n y: 0.06995438,\n z: -0.000000026077032,\n ),\n rotation: (\n x: 0.35295117,\n y: -0.032513596,\n z: -0.27210045,\n w: 0.8946115,\n ),\n scale: (\n x: 1.0060182,\n y: 0.9848342,\n z: 1.0101043,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.11196703,\n y: 0.803271,\n z: 0.015640914,\n ),\n y_axis: (\n x: 0.7652728,\n y: 0.12006621,\n z: 0.161763,\n ),\n z_axis: (\n x: 0.18419957,\n y: 0.023771945,\n z: -0.7897353,\n ),\n ),\n translation: (\n x: 0.31082624,\n y: 1.10904,\n z: -1.0133885,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.18960074,\n y: 1.2197499,\n z: 0.24608864,\n ),\n y_axis: (\n x: 1.2186284,\n y: 0.16438362,\n z: 0.057806265,\n ),\n z_axis: (\n x: -0.007540762,\n y: 0.28944525,\n z: -1.2071086,\n ),\n ),\n translation: (\n x: -1.3002164,\n y: -0.26811782,\n z: -1.3638704,\n ),\n )),\n },\n ),\n 61: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 56,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.017039806,\n y: 1.4660373,\n z: -0.0061097145,\n ),\n rotation: (\n x: 0.7139667,\n y: -0.078589894,\n z: 0.69560254,\n w: 0.014568802,\n ),\n scale: (\n x: 0.99999046,\n y: 1.0000076,\n z: 0.99999505,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8208358016359467541,\n name: \"DEF-forehead.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.017039806,\n y: 1.4660373,\n z: -0.0061097145,\n ),\n rotation: (\n x: 0.7139667,\n y: -0.078589894,\n z: 0.69560254,\n w: 0.014568802,\n ),\n scale: (\n x: 0.99999046,\n y: 1.0000076,\n z: 0.99999505,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.016019477,\n y: -0.0739422,\n z: 0.8005638,\n ),\n y_axis: (\n x: -0.106540576,\n y: -0.7938698,\n z: -0.07119203,\n ),\n z_axis: (\n x: 0.7968846,\n y: -0.10464842,\n z: -0.025611382,\n ),\n ),\n translation: (\n x: 0.36381504,\n y: 1.178897,\n z: -1.0006685,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.024773799,\n y: -0.1647581,\n z: 1.2323611,\n ),\n y_axis: (\n x: -0.11435071,\n y: -1.2276682,\n z: -0.16183603,\n ),\n z_axis: (\n x: 1.238062,\n y: -0.11009385,\n z: -0.03960745,\n ),\n ),\n translation: (\n x: 1.3646843,\n y: 1.3970684,\n z: -0.2971974,\n ),\n )),\n },\n ),\n 62: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 57,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.056818724,\n y: 1.4681375,\n z: -0.019107103,\n ),\n rotation: (\n x: 0.8024887,\n y: -0.08386433,\n z: 0.59068036,\n w: 0.008680025,\n ),\n scale: (\n x: 1.1324233,\n y: 0.77981997,\n z: 1.13241,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 669555825103498782,\n name: \"DEF-forehead.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.056818724,\n y: 1.4681375,\n z: -0.019107103,\n ),\n rotation: (\n x: 0.8024887,\n y: -0.08386433,\n z: 0.59068036,\n w: 0.008680025,\n ),\n scale: (\n x: 1.1324233,\n y: 0.77981997,\n z: 1.13241,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.26237565,\n y: -0.1132327,\n z: 0.8646245,\n ),\n y_axis: (\n x: -0.090835884,\n y: -0.6181679,\n z: -0.053391613,\n ),\n z_axis: (\n x: 0.86196285,\n y: -0.102904245,\n z: -0.27504435,\n ),\n ),\n translation: (\n x: 0.3958028,\n y: 1.1805859,\n z: -1.0111202,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.31640553,\n y: -0.23099741,\n z: 1.039488,\n ),\n y_axis: (\n x: -0.13655026,\n y: -1.5720128,\n z: -0.124097824,\n ),\n z_axis: (\n x: 1.0426733,\n y: -0.1357759,\n z: -0.3316911,\n ),\n ),\n translation: (\n x: 1.0902432,\n y: 1.8100399,\n z: -0.60030365,\n ),\n )),\n },\n ),\n 63: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 58,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.08080292,\n y: 1.4689671,\n z: -0.046034575,\n ),\n rotation: (\n x: 0.9464458,\n y: -0.011748734,\n z: 0.32219058,\n w: 0.01718997,\n ),\n scale: (\n x: 1.000001,\n y: 1.0000004,\n z: 1.0000035,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15394171469406213737,\n name: \"DEF-forehead.L.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.08080292,\n y: 1.4689671,\n z: -0.046034575,\n ),\n rotation: (\n x: 0.9464458,\n y: -0.011748734,\n z: 0.32219058,\n w: 0.01718997,\n ),\n scale: (\n x: 1.000001,\n y: 1.0000004,\n z: 1.0000035,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.63696706,\n y: -0.008975952,\n z: 0.49074674,\n ),\n y_axis: (\n x: -0.026790664,\n y: -0.8034416,\n z: 0.020077806,\n ),\n z_axis: (\n x: 0.4900983,\n y: -0.03225363,\n z: -0.6367154,\n ),\n ),\n translation: (\n x: 0.41508943,\n y: 1.181253,\n z: -1.0327736,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9850414,\n y: -0.04143062,\n z: 0.75791156,\n ),\n y_axis: (\n x: -0.013880911,\n y: -1.2424881,\n z: -0.049878556,\n ),\n z_axis: (\n x: 0.758918,\n y: 0.031049471,\n z: -0.98464715,\n ),\n ),\n translation: (\n x: 0.3913071,\n y: 1.5169573,\n z: -1.2725995,\n ),\n )),\n },\n ),\n 64: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 59,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.01704061,\n y: 1.4660373,\n z: -0.0061097145,\n ),\n rotation: (\n x: 0.71396714,\n y: 0.07858958,\n z: -0.6956022,\n w: 0.01456841,\n ),\n scale: (\n x: 0.99999255,\n y: 1.0000072,\n z: 0.9999954,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12846048179723953148,\n name: \"DEF-forehead.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.01704061,\n y: 1.4660373,\n z: -0.0061097145,\n ),\n rotation: (\n x: 0.71396714,\n y: 0.07858958,\n z: -0.6956022,\n w: 0.01456841,\n ),\n scale: (\n x: 0.99999255,\n y: 1.0000072,\n z: 0.9999954,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.016020373,\n y: 0.07394249,\n z: -0.8005654,\n ),\n y_axis: (\n x: 0.106539786,\n y: -0.7938696,\n z: -0.07119204,\n ),\n z_axis: (\n x: -0.796885,\n y: -0.104647614,\n z: -0.025612254,\n ),\n ),\n translation: (\n x: 0.33640966,\n y: 1.178897,\n z: -1.0006685,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.02477518,\n y: 0.16475698,\n z: -1.2323608,\n ),\n y_axis: (\n x: 0.114350684,\n y: -1.2276689,\n z: -0.1618347,\n ),\n z_axis: (\n x: -1.2380595,\n y: -0.110093966,\n z: -0.03960868,\n ),\n ),\n translation: (\n x: -1.3820295,\n y: 1.2817017,\n z: 0.5657294,\n ),\n )),\n },\n ),\n 65: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 60,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.056819618,\n y: 1.4681375,\n z: -0.019107103,\n ),\n rotation: (\n x: 0.8024886,\n y: 0.08386056,\n z: -0.590681,\n w: 0.008677245,\n ),\n scale: (\n x: 1.1324214,\n y: 0.7798188,\n z: 1.1324103,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1262653724065483826,\n name: \"DEF-forehead.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.056819618,\n y: 1.4681375,\n z: -0.019107103,\n ),\n rotation: (\n x: 0.8024886,\n y: 0.08386056,\n z: -0.590681,\n w: 0.008677245,\n ),\n scale: (\n x: 1.1324214,\n y: 0.7798188,\n z: 1.1324103,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.26237494,\n y: 0.11322996,\n z: -0.86462337,\n ),\n y_axis: (\n x: 0.090829894,\n y: -0.6181678,\n z: -0.053391606,\n ),\n z_axis: (\n x: -0.8619644,\n y: -0.102896236,\n z: -0.27504313,\n ),\n ),\n translation: (\n x: 0.30442184,\n y: 1.1805859,\n z: -1.0111202,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.31640583,\n y: 0.23098284,\n z: -1.0394894,\n ),\n y_axis: (\n x: 0.13654743,\n y: -1.5720172,\n z: -0.12408811,\n ),\n z_axis: (\n x: -1.0426756,\n y: -0.13577627,\n z: -0.33168945,\n ),\n ),\n translation: (\n x: -1.3117971,\n y: 1.648299,\n z: 0.12756202,\n ),\n )),\n },\n ),\n 66: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 61,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.08080372,\n y: 1.4689671,\n z: -0.046034575,\n ),\n rotation: (\n x: 0.9464458,\n y: 0.011748736,\n z: -0.32219058,\n w: 0.017189972,\n ),\n scale: (\n x: 1.0000008,\n y: 1.0000005,\n z: 1.0000035,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5479210314646566291,\n name: \"DEF-forehead.R.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.08080372,\n y: 1.4689671,\n z: -0.046034575,\n ),\n rotation: (\n x: 0.9464458,\n y: 0.011748736,\n z: -0.32219058,\n w: 0.017189972,\n ),\n scale: (\n x: 1.0000008,\n y: 1.0000005,\n z: 1.0000035,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.63696694,\n y: 0.008975953,\n z: -0.49074668,\n ),\n y_axis: (\n x: 0.026790673,\n y: -0.80344164,\n z: 0.02007781,\n ),\n z_axis: (\n x: -0.4900983,\n y: -0.032253638,\n z: -0.6367154,\n ),\n ),\n translation: (\n x: 0.2851353,\n y: 1.181253,\n z: -1.0327736,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9850416,\n y: 0.041430634,\n z: -0.7579117,\n ),\n y_axis: (\n x: 0.013880922,\n y: -1.2424883,\n z: -0.04987858,\n ),\n z_axis: (\n x: -0.7589182,\n y: 0.031049475,\n z: -0.9846473,\n ),\n ),\n translation: (\n x: -1.0810578,\n y: 1.4879467,\n z: -0.74189115,\n ),\n )),\n },\n ),\n 67: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 62,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000019229958,\n y: 0.019122286,\n z: -0.00000016296798,\n ),\n rotation: (\n x: -0.33122602,\n y: 0.0000022599404,\n z: -0.000006291961,\n w: 0.9435514,\n ),\n scale: (\n x: 1.0000007,\n y: 0.9999972,\n z: 1.000002,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15407812148518084561,\n name: \"DEF-nose.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000019229958,\n y: 0.019122286,\n z: -0.00000016296798,\n ),\n rotation: (\n x: -0.33122602,\n y: 0.0000022599404,\n z: -0.000006291961,\n w: 0.9435514,\n ),\n scale: (\n x: 1.0000007,\n y: 0.9999972,\n z: 1.000002,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041359,\n y: 0.0000028133904,\n z: 0.0000012139999,\n ),\n y_axis: (\n x: 0.0000018136279,\n y: -0.6938349,\n z: 0.40648195,\n ),\n z_axis: (\n x: 0.0000024695012,\n y: -0.40649605,\n z: -0.6938269,\n ),\n ),\n translation: (\n x: 0.3501123,\n y: 1.1277378,\n z: -1.0052482,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435708,\n y: 0.0000028049421,\n z: 0.0000038191847,\n ),\n y_axis: (\n x: 0.000004350441,\n y: -1.0729812,\n z: -0.62861145,\n ),\n z_axis: (\n x: 0.0000018773594,\n y: 0.62863326,\n z: -1.0729936,\n ),\n ),\n translation: (\n x: -0.43539247,\n y: 1.8419728,\n z: -0.36971742,\n ),\n )),\n },\n ),\n 68: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 63,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000005066395,\n y: 1.3524772,\n z: 0.00041103363,\n ),\n rotation: (\n x: 0.9979433,\n y: -0.00000000764201,\n z: 0.0000001189667,\n w: -0.06410297,\n ),\n scale: (\n x: 1.000018,\n y: 0.99996364,\n z: 1.0000385,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15739933891811764530,\n name: \"DEF-nose.004\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000005066395,\n y: 1.3524772,\n z: 0.00041103363,\n ),\n rotation: (\n x: 0.9979433,\n y: -0.00000000764201,\n z: 0.0000001189667,\n w: -0.06410297,\n ),\n scale: (\n x: 1.000018,\n y: 0.99996364,\n z: 1.0000385,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.80415297,\n y: -0.000000024530545,\n z: 0.00000019015346,\n ),\n y_axis: (\n x: -0.00000000000027853506,\n y: -0.7975007,\n z: -0.10287956,\n ),\n z_axis: (\n x: 0.00000019173312,\n y: 0.102887265,\n z: -0.79756045,\n ),\n ),\n translation: (\n x: 0.35011226,\n y: 1.087579,\n z: -0.9954249,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435445,\n y: -0.00000000000042701088,\n z: 0.00000029648453,\n ),\n y_axis: (\n x: -0.000000037934107,\n y: -1.2333916,\n z: 0.15909865,\n ),\n z_axis: (\n x: 0.00000029405385,\n y: -0.15911058,\n z: -1.2332993,\n ),\n ),\n translation: (\n x: -0.43537983,\n y: 1.1830282,\n z: -1.4006894,\n ),\n )),\n },\n ),\n 69: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 64,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.09779525,\n y: 1.459736,\n z: -0.111150146,\n ),\n rotation: (\n x: 0.9959211,\n y: -0.08977202,\n z: -0.0050241183,\n w: -0.0075612846,\n ),\n scale: (\n x: 1.0000037,\n y: 0.9999994,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4141072786860913776,\n name: \"DEF-temple.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.09779525,\n y: 1.459736,\n z: -0.111150146,\n ),\n rotation: (\n x: 0.9959211,\n y: -0.08977202,\n z: -0.0050241183,\n w: -0.0075612846,\n ),\n scale: (\n x: 1.0000037,\n y: 0.9999994,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.79113966,\n y: -0.1437288,\n z: -0.009138934,\n ),\n y_axis: (\n x: -0.14385039,\n y: -0.79108524,\n z: -0.011385658,\n ),\n z_axis: (\n x: -0.0069555314,\n y: 0.0128364125,\n z: -0.8040064,\n ),\n ),\n translation: (\n x: 0.4287536,\n y: 1.1738299,\n z: -1.0851356,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2234559,\n y: -0.22245884,\n z: -0.010756435,\n ),\n y_axis: (\n x: -0.22226895,\n y: -1.2233812,\n z: 0.019850964,\n ),\n z_axis: (\n x: -0.014132875,\n y: -0.017607454,\n z: -1.2433612,\n ),\n ),\n translation: (\n x: -0.2789913,\n y: 1.5123149,\n z: -1.3679053,\n ),\n )),\n },\n ),\n 70: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 65,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.09779611,\n y: 1.459736,\n z: -0.111150146,\n ),\n rotation: (\n x: 0.9959211,\n y: 0.08977222,\n z: 0.0050241607,\n w: -0.0075612892,\n ),\n scale: (\n x: 1.000004,\n y: 0.99999946,\n z: 1.0000002,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7202422747664485438,\n name: \"DEF-temple.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.09779611,\n y: 1.459736,\n z: -0.111150146,\n ),\n rotation: (\n x: 0.9959211,\n y: 0.08977222,\n z: 0.0050241607,\n w: -0.0075612892,\n ),\n scale: (\n x: 1.000004,\n y: 0.99999946,\n z: 1.0000002,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7911399,\n y: 0.14372917,\n z: 0.009139008,\n ),\n y_axis: (\n x: 0.14385071,\n y: -0.79108524,\n z: -0.011385657,\n ),\n z_axis: (\n x: 0.0069555966,\n y: 0.012836429,\n z: -0.80400646,\n ),\n ),\n translation: (\n x: 0.27147105,\n y: 1.1738299,\n z: -1.0851356,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2234552,\n y: 0.2224593,\n z: 0.010756532,\n ),\n y_axis: (\n x: 0.22226934,\n y: -1.2233808,\n z: 0.01985098,\n ),\n z_axis: (\n x: 0.014132978,\n y: -0.017607452,\n z: -1.243361,\n ),\n ),\n translation: (\n x: -0.5777028,\n y: 1.3565432,\n z: -1.375437,\n ),\n )),\n },\n ),\n 71: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 66,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000044703484,\n y: 0.034127496,\n z: -0.00000012293458,\n ),\n rotation: (\n x: 0.092920005,\n y: 0.06699035,\n z: -0.034767065,\n w: 0.9928089,\n ),\n scale: (\n x: 1.0,\n y: 1.0000026,\n z: 0.9999998,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4437635592505245483,\n name: \"DEF-thumb.03.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000044703484,\n y: 0.034127496,\n z: -0.00000012293458,\n ),\n rotation: (\n x: 0.092920005,\n y: 0.06699035,\n z: -0.034767065,\n w: 0.9928089,\n ),\n scale: (\n x: 1.0,\n y: 1.0000026,\n z: 0.9999998,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.30514792,\n y: 0.73681533,\n z: 0.10308497,\n ),\n y_axis: (\n x: 0.111262225,\n y: -0.15535986,\n z: 0.781104,\n ),\n z_axis: (\n x: 0.73562527,\n y: -0.2821432,\n z: -0.16090226,\n ),\n ),\n translation: (\n x: 0.55893034,\n y: 0.6298509,\n z: -0.8155507,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.47189787,\n y: 0.17206289,\n z: 1.1376135,\n ),\n y_axis: (\n x: 1.139455,\n y: -0.24025755,\n z: -0.43632364,\n ),\n z_axis: (\n x: 0.15941685,\n y: 1.2079434,\n z: -0.24882805,\n ),\n ),\n translation: (\n x: -0.8514323,\n y: 1.0402943,\n z: -0.5639598,\n ),\n )),\n },\n ),\n 72: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 67,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.037395775,\n y: 1.1835858,\n z: -0.1442244,\n ),\n rotation: (\n x: -0.49980098,\n y: -0.49980098,\n z: -0.5001988,\n w: 0.500199,\n ),\n scale: (\n x: 0.99999976,\n y: 0.9999998,\n z: 0.99999976,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14297523442430461242,\n name: \"DEF-shoulder.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.037395775,\n y: 1.1835858,\n z: -0.1442244,\n ),\n rotation: (\n x: -0.49980098,\n y: -0.49980098,\n z: -0.5001988,\n w: 0.500199,\n ),\n scale: (\n x: 0.99999976,\n y: 0.9999998,\n z: 0.99999976,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.00000028758225,\n y: -0.0006399424,\n z: 0.80413795,\n ),\n y_axis: (\n x: 0.80413824,\n y: 0.00000028758228,\n z: -0.00000019172153,\n ),\n z_axis: (\n x: -0.00000019172151,\n y: 0.80413795,\n z: 0.00064001436,\n ),\n ),\n translation: (\n x: 0.38018405,\n y: 0.95176685,\n z: -1.1117318,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.00000029684344,\n y: 1.2435672,\n z: -0.00000044449826,\n ),\n y_axis: (\n x: -0.0009897564,\n y: 0.0000002968434,\n z: 1.2435669,\n ),\n z_axis: (\n x: 1.2435669,\n y: -0.0000004444982,\n z: 0.0009896451,\n ),\n ),\n translation: (\n x: 1.3834547,\n y: -0.4727852,\n z: -1.1824855,\n ),\n )),\n },\n ),\n 73: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000027706847,\n y: 0.024796575,\n z: -0.00000011175871,\n ),\n rotation: (\n x: 0.36724085,\n y: -0.00457793,\n z: -0.010559579,\n w: 0.93005466,\n ),\n scale: (\n x: 1.0,\n y: 1.0000033,\n z: 1.0000013,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18186180437490032373,\n name: \"DEF-f_index.03.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000027706847,\n y: 0.024796575,\n z: -0.00000011175871,\n ),\n rotation: (\n x: 0.36724085,\n y: -0.00457793,\n z: -0.010559579,\n w: 0.93005466,\n ),\n scale: (\n x: 1.0,\n y: 1.0000033,\n z: 1.0000013,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.78484154,\n y: 0.022477789,\n z: -0.17582047,\n ),\n y_axis: (\n x: -0.025891162,\n y: -0.78366375,\n z: -0.18847047,\n ),\n z_axis: (\n x: -0.15941364,\n y: 0.14062452,\n z: -0.7753768,\n ),\n ),\n translation: (\n x: 0.5929768,\n y: 0.61926365,\n z: -0.759405,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2182621,\n y: -0.014016401,\n z: -0.2728399,\n ),\n y_axis: (\n x: 0.019152429,\n y: -1.2229456,\n z: 0.29291788,\n ),\n z_axis: (\n x: -0.24699514,\n y: -0.21891516,\n z: -1.1804767,\n ),\n ),\n translation: (\n x: -0.9218309,\n y: 0.5993918,\n z: -0.9160656,\n ),\n )),\n },\n ),\n 74: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0038647763,\n y: 0.059300855,\n z: 0.027688779,\n ),\n rotation: (\n x: 0.00912221,\n y: -0.65566194,\n z: -0.08880975,\n w: 0.74975806,\n ),\n scale: (\n x: 0.9999998,\n y: 0.99999976,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10380666998417546855,\n name: \"DEF-palm.01.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0038647763,\n y: 0.059300855,\n z: 0.027688779,\n ),\n rotation: (\n x: 0.00912221,\n y: -0.65566194,\n z: -0.08880975,\n w: 0.74975806,\n ),\n scale: (\n x: 0.9999998,\n y: 0.99999976,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.8010393,\n y: -0.015483424,\n z: 0.031937562,\n ),\n y_axis: (\n x: 0.019317199,\n y: -0.035034467,\n z: 0.8125375,\n ),\n z_axis: (\n x: 0.0047608954,\n y: 0.795577,\n z: 0.08002742,\n ),\n ),\n translation: (\n x: 0.5846465,\n y: 0.6472302,\n z: -0.8344294,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.2472748,\n y: 0.05119408,\n z: -0.022019899,\n ),\n y_axis: (\n x: 0.004461827,\n y: -0.12344639,\n z: 1.2516001,\n ),\n z_axis: (\n x: 0.029844986,\n y: 1.2241727,\n z: 0.054489188,\n ),\n ),\n translation: (\n x: 0.75123054,\n y: 1.0714535,\n z: -0.75173223,\n ),\n )),\n },\n ),\n 75: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 2,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000011175871,\n y: 0.02970168,\n z: -0.000000044703484,\n ),\n rotation: (\n x: 0.35216764,\n y: 0.0014819605,\n z: 0.003392919,\n w: 0.93592966,\n ),\n scale: (\n x: 0.99999976,\n y: 1.0000017,\n z: 1.0000007,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17631083612932562369,\n name: \"DEF-f_middle.03.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000011175871,\n y: 0.02970168,\n z: -0.000000044703484,\n ),\n rotation: (\n x: 0.35216764,\n y: 0.0014819605,\n z: 0.003392919,\n w: 0.93592966,\n ),\n scale: (\n x: 0.99999976,\n y: 1.0000017,\n z: 1.0000007,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7853481,\n y: -0.058059637,\n z: -0.15723461,\n ),\n y_axis: (\n x: -0.10758636,\n y: -0.77196366,\n z: -0.22027224,\n ),\n z_axis: (\n x: -0.11709834,\n y: 0.1873778,\n z: -0.77097255,\n ),\n ),\n translation: (\n x: 0.611758,\n y: 0.61683005,\n z: -0.7618709,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2226807,\n y: -0.14259553,\n z: -0.20861687,\n ),\n y_axis: (\n x: -0.109797835,\n y: -1.1985836,\n z: 0.36483625,\n ),\n z_axis: (\n x: -0.2123909,\n y: -0.26964676,\n z: -1.1767074,\n ),\n ),\n translation: (\n x: -0.84207255,\n y: 0.62112033,\n z: -0.99391806,\n ),\n )),\n },\n ),\n 76: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.008794621,\n y: 0.060523085,\n z: 0.006385967,\n ),\n rotation: (\n x: -0.0509373,\n y: -0.6884421,\n z: -0.04473267,\n w: 0.72211623,\n ),\n scale: (\n x: 0.9999995,\n y: 0.99999976,\n z: 1.0000002,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9787264354586395510,\n name: \"DEF-palm.02.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.008794621,\n y: 0.060523085,\n z: 0.006385967,\n ),\n rotation: (\n x: -0.0509373,\n y: -0.6884421,\n z: -0.04473267,\n w: 0.72211623,\n ),\n scale: (\n x: 0.9999995,\n y: 0.99999976,\n z: 1.0000002,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.7863214,\n y: 0.053851865,\n z: 0.15370296,\n ),\n y_axis: (\n x: 0.13013776,\n y: -0.058410082,\n z: 0.79720384,\n ),\n z_axis: (\n x: 0.08259664,\n y: 0.7925266,\n z: 0.09210321,\n ),\n ),\n translation: (\n x: 0.6019973,\n y: 0.649231,\n z: -0.8367235,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.2241157,\n y: 0.22449136,\n z: 0.099723436,\n ),\n y_axis: (\n x: 0.103472576,\n y: -0.16352296,\n z: 1.2427045,\n ),\n z_axis: (\n x: 0.20740934,\n y: 1.2057567,\n z: 0.07477221,\n ),\n ),\n translation: (\n x: 0.8432811,\n y: 0.9799059,\n z: -0.80427194,\n ),\n )),\n },\n ),\n 77: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 4,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000067055225,\n y: 0.02724827,\n z: 0.000000059604645,\n ),\n rotation: (\n x: 0.37087083,\n y: 0.0030514833,\n z: 0.010158486,\n w: 0.9286239,\n ),\n scale: (\n x: 1.0,\n y: 0.9999997,\n z: 0.99999976,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7271722501277847897,\n name: \"DEF-f_ring.03.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000067055225,\n y: 0.02724827,\n z: 0.000000059604645,\n ),\n rotation: (\n x: 0.37087083,\n y: 0.0030514833,\n z: 0.010158486,\n w: 0.9286239,\n ),\n scale: (\n x: 1.0,\n y: 0.9999997,\n z: 0.99999976,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.78387195,\n y: -0.119847395,\n z: -0.11087876,\n ),\n y_axis: (\n x: -0.1620309,\n y: -0.73788637,\n z: -0.3079443,\n ),\n z_axis: (\n x: -0.036747254,\n y: 0.27489874,\n z: -0.7486776,\n ),\n ),\n translation: (\n x: 0.62784135,\n y: 0.6137297,\n z: -0.7701044,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2239387,\n y: -0.23093443,\n z: -0.08627726,\n ),\n y_axis: (\n x: -0.21131065,\n y: -1.1352773,\n z: 0.4982545,\n ),\n z_axis: (\n x: -0.13766329,\n y: -0.40551507,\n z: -1.1485051,\n ),\n ),\n translation: (\n x: -0.74476683,\n y: 0.52945465,\n z: -1.136094,\n ),\n )),\n },\n ),\n 78: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 5,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.010701161,\n y: 0.059267573,\n z: -0.015753657,\n ),\n rotation: (\n x: 0.091741525,\n y: 0.72173065,\n z: -0.0073578698,\n w: -0.68602794,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999964,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 768058927374087067,\n name: \"DEF-palm.03.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.010701161,\n y: 0.059267573,\n z: -0.015753657,\n ),\n rotation: (\n x: 0.091741525,\n y: 0.72173065,\n z: -0.0073578698,\n w: -0.68602794,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999964,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.75077224,\n y: 0.13079089,\n z: 0.26013035,\n ),\n y_axis: (\n x: 0.2278626,\n y: -0.06040892,\n z: 0.77221936,\n ),\n z_axis: (\n x: 0.16272563,\n y: 0.7833611,\n z: 0.060422905,\n ),\n ),\n translation: (\n x: 0.61935866,\n y: 0.6486449,\n z: -0.8410603,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.1691552,\n y: 0.376298,\n z: 0.22422177,\n ),\n y_axis: (\n x: 0.21495868,\n y: -0.16847107,\n z: 1.2276692,\n ),\n z_axis: (\n x: 0.36180413,\n y: 1.1707538,\n z: 0.029875482,\n ),\n ),\n translation: (\n x: 0.8889936,\n y: 0.8608891,\n z: -0.91006804,\n ),\n )),\n },\n ),\n 79: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 6,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000074505806,\n y: 0.024098493,\n z: 0.000000044703484,\n ),\n rotation: (\n x: 0.30671644,\n y: -0.0025948635,\n z: 0.006260824,\n w: 0.95177674,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999803,\n z: 0.9999988,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7703583394558157552,\n name: \"DEF-f_pinky.03.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000074505806,\n y: 0.024098493,\n z: 0.000000044703484,\n ),\n rotation: (\n x: 0.30671644,\n y: -0.0025948635,\n z: 0.006260824,\n w: 0.95177674,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999803,\n z: 0.9999988,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7714637,\n y: -0.1702699,\n z: -0.12746437,\n ),\n y_axis: (\n x: -0.20883867,\n y: -0.75497085,\n z: -0.21143605,\n ),\n z_axis: (\n x: -0.057351608,\n y: 0.18824807,\n z: -0.7789018,\n ),\n ),\n translation: (\n x: 0.64224356,\n y: 0.61668944,\n z: -0.78230137,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2061843,\n y: -0.3008848,\n z: -0.11571114,\n ),\n y_axis: (\n x: -0.28920466,\n y: -1.1684419,\n z: 0.36450556,\n ),\n z_axis: (\n x: -0.15870912,\n y: -0.26023912,\n z: -1.1872437,\n ),\n ),\n translation: (\n x: -0.72047305,\n y: 0.71022177,\n z: -1.0792544,\n ),\n )),\n },\n ),\n 80: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 7,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.011320297,\n y: 0.056157112,\n z: -0.033879787,\n ),\n rotation: (\n x: 0.14219858,\n y: 0.7529955,\n z: -0.03574032,\n w: -0.6414826,\n ),\n scale: (\n x: 0.9999998,\n y: 0.9999999,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11099402993250856045,\n name: \"DEF-palm.04.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.011320297,\n y: 0.056157112,\n z: -0.033879787,\n ),\n rotation: (\n x: 0.14219858,\n y: 0.7529955,\n z: -0.03574032,\n w: -0.6414826,\n ),\n scale: (\n x: 0.9999998,\n y: 0.9999999,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.6993215,\n y: 0.20833524,\n z: 0.34735647,\n ),\n y_axis: (\n x: 0.29776016,\n y: -0.107141815,\n z: 0.7375855,\n ),\n z_axis: (\n x: 0.25366887,\n y: 0.76126665,\n z: 0.05433884,\n ),\n ),\n translation: (\n x: 0.63319373,\n y: 0.6473183,\n z: -0.8462612,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.0898982,\n y: 0.4862578,\n z: 0.36670825,\n ),\n y_axis: (\n x: 0.32836458,\n y: -0.2422812,\n z: 1.1896378,\n ),\n z_axis: (\n x: 0.48768565,\n y: 1.1242809,\n z: 0.024768457,\n ),\n ),\n translation: (\n x: 0.89026976,\n y: 0.80037296,\n z: -0.9813111,\n ),\n )),\n },\n ),\n 81: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 69,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000029802322,\n y: 0.034127716,\n z: -0.000000074505806,\n ),\n rotation: (\n x: 0.09291946,\n y: -0.0669904,\n z: 0.034766853,\n w: 0.99280894,\n ),\n scale: (\n x: 1.0,\n y: 1.0000027,\n z: 0.9999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17735472231268096692,\n name: \"DEF-thumb.03.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000029802322,\n y: 0.034127716,\n z: -0.000000074505806,\n ),\n rotation: (\n x: 0.09291946,\n y: -0.0669904,\n z: 0.034766853,\n w: 0.99280894,\n ),\n scale: (\n x: 1.0,\n y: 1.0000027,\n z: 0.9999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.30514798,\n y: -0.7368157,\n z: -0.10308436,\n ),\n y_axis: (\n x: -0.11126225,\n y: -0.15535969,\n z: 0.78110415,\n ),\n z_axis: (\n x: -0.7356257,\n y: -0.28214294,\n z: -0.16090277,\n ),\n ),\n translation: (\n x: 0.14129454,\n y: 0.6298507,\n z: -0.8155507,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.47189716,\n y: -0.17206392,\n z: -1.1376129,\n ),\n y_axis: (\n x: -1.1394547,\n y: -0.24025685,\n z: -0.4363235,\n ),\n z_axis: (\n x: -0.15941662,\n y: 1.2079432,\n z: -0.24882783,\n ),\n ),\n translation: (\n x: 0.5209975,\n y: 1.1607765,\n z: 0.23262545,\n ),\n )),\n },\n ),\n 82: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 70,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.037396282,\n y: 1.1835858,\n z: -0.1442244,\n ),\n rotation: (\n x: -0.49980104,\n y: 0.49980104,\n z: 0.5001989,\n w: 0.50019884,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999994,\n z: 0.9999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4772357558832716499,\n name: \"DEF-shoulder.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.037396282,\n y: 1.1835858,\n z: -0.1442244,\n ),\n rotation: (\n x: -0.49980104,\n y: 0.49980104,\n z: 0.5001989,\n w: 0.50019884,\n ),\n scale: (\n x: 0.9999999,\n y: 0.99999994,\n z: 0.9999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.0,\n y: 0.0006397987,\n z: -0.8041381,\n ),\n y_axis: (\n x: -0.8041384,\n y: 0.0,\n z: 0.000000047930385,\n ),\n z_axis: (\n x: -0.00000004793038,\n y: 0.8041381,\n z: 0.0006398227,\n ),\n ),\n translation: (\n x: 0.32004088,\n y: 0.95176685,\n z: -1.1117318,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.00000007412235,\n y: -1.243567,\n z: 0.00000000005897418,\n ),\n y_axis: (\n x: 0.0009894597,\n y: -0.00000007412235,\n z: 1.2435666,\n ),\n z_axis: (\n x: -1.2435666,\n y: -0.00000000005897417,\n z: 0.0009894226,\n ),\n ),\n translation: (\n x: -1.3834543,\n y: 0.39799234,\n z: -1.1824856,\n ),\n )),\n },\n ),\n 83: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000002561137,\n y: 0.024796635,\n z: -0.00000010803342,\n ),\n rotation: (\n x: 0.36724076,\n y: 0.004577949,\n z: 0.010560177,\n w: 0.93005466,\n ),\n scale: (\n x: 1.0000001,\n y: 1.0000031,\n z: 1.0000015,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12529760825532613596,\n name: \"DEF-f_index.03.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000002561137,\n y: 0.024796635,\n z: -0.00000010803342,\n ),\n rotation: (\n x: 0.36724076,\n y: 0.004577949,\n z: 0.010560177,\n w: 0.93005466,\n ),\n scale: (\n x: 1.0000001,\n y: 1.0000031,\n z: 1.0000015,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.784842,\n y: -0.022478135,\n z: 0.17582028,\n ),\n y_axis: (\n x: 0.025890127,\n y: -0.78366446,\n z: -0.18847057,\n ),\n z_axis: (\n x: 0.15941371,\n y: 0.14062491,\n z: -0.77537644,\n ),\n ),\n translation: (\n x: 0.10724825,\n y: 0.61926293,\n z: -0.7594044,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2182615,\n y: 0.014015961,\n z: 0.2728397,\n ),\n y_axis: (\n x: -0.019154029,\n y: -1.2229443,\n z: 0.29291752,\n ),\n z_axis: (\n x: 0.2469949,\n y: -0.21891572,\n z: -1.1804771,\n ),\n ),\n translation: (\n x: 0.068774,\n y: 0.5895753,\n z: -1.1071141,\n ),\n )),\n },\n ),\n 84: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.003864672,\n y: 0.05930064,\n z: 0.027688753,\n ),\n rotation: (\n x: 0.009122232,\n y: 0.65566194,\n z: 0.08880975,\n w: 0.74975806,\n ),\n scale: (\n x: 0.9999997,\n y: 0.9999998,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13002447965899336697,\n name: \"DEF-palm.01.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.003864672,\n y: 0.05930064,\n z: 0.027688753,\n ),\n rotation: (\n x: 0.009122232,\n y: 0.65566194,\n z: 0.08880975,\n w: 0.74975806,\n ),\n scale: (\n x: 0.9999997,\n y: 0.9999998,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.8010394,\n y: 0.01548313,\n z: -0.03193733,\n ),\n y_axis: (\n x: -0.019317277,\n y: -0.03503499,\n z: 0.8125377,\n ),\n z_axis: (\n x: -0.0047602453,\n y: 0.7955774,\n z: 0.08002718,\n ),\n ),\n translation: (\n x: 0.11557865,\n y: 0.64722973,\n z: -0.8344292,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.2472742,\n y: -0.051193632,\n z: 0.022019403,\n ),\n y_axis: (\n x: -0.0044608065,\n y: -0.12344585,\n z: 1.2515992,\n ),\n z_axis: (\n x: -0.029845044,\n y: 1.2241721,\n z: 0.05448993,\n ),\n ),\n translation: (\n x: 0.12214184,\n y: 1.1072997,\n z: -0.7671492,\n ),\n )),\n },\n ),\n 85: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 2,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000027008355,\n y: 0.02970141,\n z: 0.00000009313226,\n ),\n rotation: (\n x: 0.3521682,\n y: -0.0014823127,\n z: -0.0033919765,\n w: 0.9359294,\n ),\n scale: (\n x: 0.99999976,\n y: 1.0000006,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7468863661597002299,\n name: \"DEF-f_middle.03.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000027008355,\n y: 0.02970141,\n z: 0.00000009313226,\n ),\n rotation: (\n x: 0.3521682,\n y: -0.0014823127,\n z: -0.0033919765,\n w: 0.9359294,\n ),\n scale: (\n x: 0.99999976,\n y: 1.0000006,\n z: 1.0,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7853484,\n y: 0.05805853,\n z: 0.1572339,\n ),\n y_axis: (\n x: 0.107584395,\n y: -0.77196336,\n z: -0.22027248,\n ),\n z_axis: (\n x: 0.11709836,\n y: 0.18738076,\n z: -0.7709735,\n ),\n ),\n translation: (\n x: 0.08846688,\n y: 0.6168297,\n z: -0.7618707,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2226809,\n y: 0.14259438,\n z: 0.2086158,\n ),\n y_axis: (\n x: 0.109794885,\n y: -1.1985831,\n z: 0.36483535,\n ),\n z_axis: (\n x: 0.2123904,\n y: -0.26965111,\n z: -1.1767049,\n ),\n ),\n translation: (\n x: -0.0140774995,\n y: 0.5212675,\n z: -1.1399938,\n ),\n )),\n },\n ),\n 86: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.008794591,\n y: 0.060522888,\n z: 0.006385822,\n ),\n rotation: (\n x: -0.050937314,\n y: 0.6884421,\n z: 0.044732723,\n w: 0.7221163,\n ),\n scale: (\n x: 0.99999934,\n y: 0.9999997,\n z: 1.0000004,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13279061901413935487,\n name: \"DEF-palm.02.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.008794591,\n y: 0.060522888,\n z: 0.006385822,\n ),\n rotation: (\n x: -0.050937314,\n y: 0.6884421,\n z: 0.044732723,\n w: 0.7221163,\n ),\n scale: (\n x: 0.99999934,\n y: 0.9999997,\n z: 1.0000004,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.7863215,\n y: -0.053852055,\n z: -0.15370272,\n ),\n y_axis: (\n x: -0.13013783,\n y: -0.058410693,\n z: 0.797204,\n ),\n z_axis: (\n x: -0.0825962,\n y: 0.79252696,\n z: 0.09210301,\n ),\n ),\n translation: (\n x: 0.09822774,\n y: 0.64923054,\n z: -0.8367233,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.2241155,\n y: -0.22449087,\n z: -0.09972381,\n ),\n y_axis: (\n x: -0.10347188,\n y: -0.16352235,\n z: 1.2427038,\n ),\n z_axis: (\n x: -0.2074094,\n y: 1.2057562,\n z: 0.07477301,\n ),\n ),\n translation: (\n x: 0.013874918,\n y: 1.1370993,\n z: -0.7344413,\n ),\n )),\n },\n ),\n 87: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 4,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000014901161,\n y: 0.027248329,\n z: 0.000000081025064,\n ),\n rotation: (\n x: 0.3708715,\n y: -0.0030517012,\n z: -0.010160423,\n w: 0.92862356,\n ),\n scale: (\n x: 1.0000001,\n y: 1.000003,\n z: 0.9999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1838253180881492874,\n name: \"DEF-f_ring.03.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000014901161,\n y: 0.027248329,\n z: 0.000000081025064,\n ),\n rotation: (\n x: 0.3708715,\n y: -0.0030517012,\n z: -0.010160423,\n w: 0.92862356,\n ),\n scale: (\n x: 1.0000001,\n y: 1.000003,\n z: 0.9999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7838716,\n y: 0.11984875,\n z: 0.11087899,\n ),\n y_axis: (\n x: 0.16203208,\n y: -0.73788816,\n z: -0.30794558,\n ),\n z_axis: (\n x: 0.03674745,\n y: 0.27489966,\n z: -0.7486773,\n ),\n ),\n translation: (\n x: 0.072383404,\n y: 0.61372924,\n z: -0.7701042,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2239385,\n y: 0.23093595,\n z: 0.08627662,\n ),\n y_axis: (\n x: 0.21131144,\n y: -1.1352729,\n z: 0.4982551,\n ),\n z_axis: (\n x: 0.1376642,\n y: -0.40551493,\n z: -1.1485046,\n ),\n ),\n translation: (\n x: -0.11226507,\n y: 0.36774546,\n z: -1.196507,\n ),\n )),\n },\n ),\n 88: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 5,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.010700943,\n y: 0.059267476,\n z: -0.015753713,\n ),\n rotation: (\n x: -0.09174143,\n y: 0.72173065,\n z: -0.0073578465,\n w: 0.686028,\n ),\n scale: (\n x: 0.99999946,\n y: 0.9999995,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 680878717189443433,\n name: \"DEF-palm.03.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.010700943,\n y: 0.059267476,\n z: -0.015753713,\n ),\n rotation: (\n x: -0.09174143,\n y: 0.72173065,\n z: -0.0073578465,\n w: 0.686028,\n ),\n scale: (\n x: 0.99999946,\n y: 0.9999995,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.75077224,\n y: -0.13079108,\n z: -0.26012996,\n ),\n y_axis: (\n x: -0.22786267,\n y: -0.06040938,\n z: 0.77221954,\n ),\n z_axis: (\n x: -0.16272518,\n y: 0.78336143,\n z: 0.06042264,\n ),\n ),\n translation: (\n x: 0.080866545,\n y: 0.64864427,\n z: -0.8410599,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.1691552,\n y: -0.3762974,\n z: -0.22422214,\n ),\n y_axis: (\n x: -0.21495804,\n y: -0.16847022,\n z: 1.2276685,\n ),\n z_axis: (\n x: -0.36180428,\n y: 1.1707535,\n z: 0.029876016,\n ),\n ),\n translation: (\n x: -0.070322245,\n y: 1.124381,\n z: -0.7530605,\n ),\n )),\n },\n ),\n 89: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 6,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.024098795,\n z: 0.000000053085387,\n ),\n rotation: (\n x: 0.30671674,\n y: 0.002595044,\n z: -0.006262747,\n w: 0.9517767,\n ),\n scale: (\n x: 0.99999994,\n y: 0.9999989,\n z: 0.999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13997968890414248519,\n name: \"DEF-f_pinky.03.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0,\n y: 0.024098795,\n z: 0.000000053085387,\n ),\n rotation: (\n x: 0.30671674,\n y: 0.002595044,\n z: -0.006262747,\n w: 0.9517767,\n ),\n scale: (\n x: 0.99999994,\n y: 0.9999989,\n z: 0.999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.77146333,\n y: 0.17027237,\n z: 0.1274648,\n ),\n y_axis: (\n x: 0.20884056,\n y: -0.7549709,\n z: -0.21143633,\n ),\n z_axis: (\n x: 0.0573518,\n y: 0.18824911,\n z: -0.7789021,\n ),\n ),\n translation: (\n x: 0.057981282,\n y: 0.6166886,\n z: -0.78230083,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2061832,\n y: 0.30088848,\n z: 0.115710475,\n ),\n y_axis: (\n x: 0.28920698,\n y: -1.16844,\n z: 0.36450586,\n ),\n z_axis: (\n x: 0.15871023,\n y: -0.26023972,\n z: -1.1872427,\n ),\n ),\n translation: (\n x: -0.12412757,\n y: 0.49953198,\n z: -1.1602767,\n ),\n )),\n },\n ),\n 90: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 7,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.011320211,\n y: 0.056157038,\n z: -0.03387999,\n ),\n rotation: (\n x: -0.14219856,\n y: 0.7529955,\n z: -0.03574034,\n w: 0.6414826,\n ),\n scale: (\n x: 0.9999997,\n y: 0.99999976,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17272412654463990329,\n name: \"DEF-palm.04.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.011320211,\n y: 0.056157038,\n z: -0.03387999,\n ),\n rotation: (\n x: -0.14219856,\n y: 0.7529955,\n z: -0.03574034,\n w: 0.6414826,\n ),\n scale: (\n x: 0.9999997,\n y: 0.99999976,\n z: 1.0,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.69932175,\n y: -0.20833533,\n z: -0.34735632,\n ),\n y_axis: (\n x: -0.2977604,\n y: -0.10714232,\n z: 0.7375857,\n ),\n z_axis: (\n x: -0.25366843,\n y: 0.7612668,\n z: 0.0543385,\n ),\n ),\n translation: (\n x: 0.067031235,\n y: 0.6473177,\n z: -0.84626085,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.089898,\n y: -0.48625752,\n z: -0.3667085,\n ),\n y_axis: (\n x: -0.32836398,\n y: -0.24228023,\n z: 1.1896377,\n ),\n z_axis: (\n x: -0.4876859,\n y: 1.1242806,\n z: 0.02476902,\n ),\n ),\n translation: (\n x: -0.12709644,\n y: 1.1408613,\n z: -0.7245316,\n ),\n )),\n },\n ),\n 91: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 72,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.08342433,\n y: 1.090158,\n z: -0.049183846,\n ),\n rotation: (\n x: 0.000000000000003210044,\n y: 0.7068253,\n z: 0.70738816,\n w: -0.000000000000030133783,\n ),\n scale: (\n x: 1.0000001,\n y: 0.9999997,\n z: 0.9999998,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9437407176679433380,\n name: \"DEF-breast.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.08342433,\n y: 1.090158,\n z: -0.049183846,\n ),\n rotation: (\n x: 0.000000000000003210044,\n y: 0.7068253,\n z: 0.70738816,\n w: -0.000000000000030133783,\n ),\n scale: (\n x: 1.0000001,\n y: 0.9999997,\n z: 0.9999998,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.8041386,\n y: -0.000000000000030633404,\n z: 0.0000000000000379072,\n ),\n y_axis: (\n x: 0.00000000000003793156,\n y: -0.0006401581,\n z: 0.804138,\n ),\n z_axis: (\n x: -0.000000000000030603212,\n y: 0.8041381,\n z: 0.0006400623,\n ),\n ),\n translation: (\n x: 0.4171974,\n y: 0.876638,\n z: -1.0353061,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.2435668,\n y: 0.00000000000005865961,\n z: -0.00000000000004732661,\n ),\n y_axis: (\n x: -0.00000000000004737328,\n y: -0.0009898302,\n z: 1.2435666,\n ),\n z_axis: (\n x: 0.000000000000058621903,\n y: 1.2435669,\n z: 0.0009899783,\n ),\n ),\n translation: (\n x: 0.51881284,\n y: 1.2883401,\n z: -1.0891328,\n ),\n )),\n },\n ),\n 92: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 73,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.083424896,\n y: 1.090158,\n z: -0.049183846,\n ),\n rotation: (\n x: 0.000000000000003210044,\n y: 0.7068253,\n z: 0.70738816,\n w: -0.000000000000030133783,\n ),\n scale: (\n x: 1.0000001,\n y: 0.9999997,\n z: 0.9999998,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15422138856466697281,\n name: \"DEF-breast.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.083424896,\n y: 1.090158,\n z: -0.049183846,\n ),\n rotation: (\n x: 0.000000000000003210044,\n y: 0.7068253,\n z: 0.70738816,\n w: -0.000000000000030133783,\n ),\n scale: (\n x: 1.0000001,\n y: 0.9999997,\n z: 0.9999998,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.8041386,\n y: -0.000000000000030633404,\n z: 0.0000000000000379072,\n ),\n y_axis: (\n x: 0.00000000000003793156,\n y: -0.0006401581,\n z: 0.804138,\n ),\n z_axis: (\n x: -0.000000000000030603212,\n y: 0.8041381,\n z: 0.0006400623,\n ),\n ),\n translation: (\n x: 0.2830275,\n y: 0.876638,\n z: -1.0353061,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.2435668,\n y: 0.00000000000005865961,\n z: -0.00000000000004732661,\n ),\n y_axis: (\n x: -0.00000000000004737328,\n y: -0.0009898302,\n z: 1.2435666,\n ),\n z_axis: (\n x: 0.000000000000058621903,\n y: 1.2435669,\n z: 0.0009899783,\n ),\n ),\n translation: (\n x: 0.35196358,\n y: 1.2883401,\n z: -1.0891328,\n ),\n )),\n },\n ),\n 93: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 2.1812353,\n y: -0.9436786,\n z: -7.8514776,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 0.7999999,\n y: 0.79200006,\n z: 0.7999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6353791311592226093,\n name: \"Room\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 219,\n 220,\n 221,\n 222,\n ]),\n },\n ),\n 94: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 2.7644851,\n y: -1.8783703,\n z: 1.8211865,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13233653607929491890,\n name: \"DeskChair\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 223,\n ]),\n },\n ),\n 95: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.419451,\n y: -1.7797666,\n z: 0.916337,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13638365500142878701,\n name: \"Desk\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 224,\n ]),\n },\n ),\n 96: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 3.4457884,\n y: -0.13778687,\n z: 0.80219483,\n ),\n rotation: (\n x: 0.025473887,\n y: 0.030383414,\n z: 0.6419525,\n w: -0.7657183,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0,\n z: 1.7282777,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13429567360513571507,\n name: \"BookCase\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 225,\n ]),\n },\n ),\n 97: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 6,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000007450581,\n y: 0.037451226,\n z: -0.0000000018626451,\n ),\n rotation: (\n x: 0.42144138,\n y: 0.018712075,\n z: 0.00896326,\n w: 0.90661836,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0000024,\n z: 0.9999991,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9044000858463622875,\n name: \"DEF-f_pinky.02.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 89,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000007450581,\n y: 0.037451226,\n z: -0.0000000018626451,\n ),\n rotation: (\n x: 0.42144138,\n y: 0.018712075,\n z: 0.00896326,\n w: 0.90661836,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0000024,\n z: 0.9999991,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7742777,\n y: 0.16026123,\n z: 0.12374066,\n ),\n y_axis: (\n x: 0.1280752,\n y: -0.72453904,\n z: 0.28183433,\n ),\n z_axis: (\n x: 0.16171087,\n y: -0.28943464,\n z: -0.7569017,\n ),\n ),\n translation: (\n x: 0.054894805,\n y: 0.63414913,\n z: -0.78909266,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2102652,\n y: 0.16423148,\n z: 0.25900996,\n ),\n y_axis: (\n x: 0.273791,\n y: -1.1643212,\n z: -0.38877785,\n ),\n z_axis: (\n x: 0.15387523,\n y: 0.4803172,\n z: -1.1171721,\n ),\n ),\n translation: (\n x: -0.11863977,\n y: 1.1083527,\n z: -0.6492275,\n ),\n )),\n },\n ),\n 98: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 5,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 1.8643713,\n y: 0.824899,\n z: 0.15418126,\n ),\n rotation: (\n x: 0.0,\n y: 0.8021092,\n z: 0.0,\n w: -0.59717745,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6234127825786918958,\n name: \"BoomBox\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 227,\n ]),\n },\n ),\n 99: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 6,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 1.8131375,\n y: 0.85924256,\n z: -0.38482028,\n ),\n rotation: (\n x: 0.0,\n y: -0.63699,\n z: 0.0,\n w: 0.7708721,\n ),\n scale: (\n x: 2.0,\n y: 2.0,\n z: 2.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10067850846471362618,\n name: \"Radio\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 228,\n ]),\n },\n ),\n 100: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 7,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -1.8123102,\n y: 4.389607,\n z: 4.3180876,\n ),\n rotation: (\n x: 0.4843165,\n y: 0.12131094,\n z: -0.43075013,\n w: 0.751781,\n ),\n scale: (\n x: 0.3931088,\n y: 0.39310884,\n z: 0.39310884,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14847531744333314353,\n name: \"Monitor\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 229,\n ]),\n },\n ),\n 101: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 8,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.010634474,\n y: 0.73900187,\n z: -2.070066,\n ),\n rotation: (\n x: 0.0,\n y: 0.2954401,\n z: 0.0,\n w: 0.9553613,\n ),\n scale: (\n x: 0.49999994,\n y: 0.5,\n z: 0.49999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15248759462573312337,\n name: \"Mannequin\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 230,\n ]),\n },\n ),\n 102: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 6,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.004802873,\n y: 0.0932176,\n z: -0.043029357,\n ),\n rotation: (\n x: 0.16402297,\n y: -0.6709287,\n z: 0.10720765,\n w: 0.7151627,\n ),\n scale: (\n x: 0.9999995,\n y: 1.0000007,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15671076097669110724,\n name: \"DEF-f_pinky.01.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 97,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.004802873,\n y: 0.0932176,\n z: -0.043029357,\n ),\n rotation: (\n x: 0.16402297,\n y: -0.6709287,\n z: 0.10720765,\n w: 0.7151627,\n ),\n scale: (\n x: 0.9999995,\n y: 1.0000007,\n z: 0.99999994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.78025806,\n y: 0.14846428,\n z: 0.09209904,\n ),\n y_axis: (\n x: -0.016166182,\n y: -0.24083309,\n z: 0.76378685,\n ),\n z_axis: (\n x: 0.18164714,\n y: -0.74455905,\n z: -0.27530044,\n ),\n ),\n translation: (\n x: 0.05550024,\n y: 0.64316857,\n z: -0.8176974,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.219889,\n y: -0.053216968,\n z: 0.260458,\n ),\n y_axis: (\n x: 0.2579866,\n y: -0.44480821,\n z: -1.1477581,\n ),\n z_axis: (\n x: 0.107166894,\n y: 1.167885,\n z: -0.356392,\n ),\n ),\n translation: (\n x: -0.14600292,\n y: 1.2440166,\n z: 0.43232566,\n ),\n )),\n },\n ),\n 103: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 10,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.24029964,\n y: 0.039698,\n z: -2.394653,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1705223073573951885,\n name: \"Baseboard_North\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 232,\n ]),\n },\n ),\n 104: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 11,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 2.153424,\n y: 0.039698,\n z: -0.4814305,\n ),\n rotation: (\n x: 0.0,\n y: -0.70710665,\n z: 0.0,\n w: 0.7071068,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16448957151321728339,\n name: \"Baseboard_East\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 233,\n ]),\n },\n ),\n 105: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 12,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.7477564,\n y: 0.72486275,\n z: -2.0256147,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15635982943659836433,\n name: \"Notepad\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 234,\n ]),\n },\n ),\n 106: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 4,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000007450581,\n y: 0.04093395,\n z: 0.000000034458935,\n ),\n rotation: (\n x: 0.37381062,\n y: 0.0077556428,\n z: 0.01086071,\n w: 0.927409,\n ),\n scale: (\n x: 0.99999976,\n y: 0.999999,\n z: 0.99999905,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1369997159922386572,\n name: \"DEF-f_ring.02.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 87,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000007450581,\n y: 0.04093395,\n z: 0.000000034458935,\n ),\n rotation: (\n x: 0.37381062,\n y: 0.0077556428,\n z: 0.01086071,\n w: 0.927409,\n ),\n scale: (\n x: 0.99999976,\n y: 0.999999,\n z: 0.99999905,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7859008,\n y: 0.103937946,\n z: 0.11562575,\n ),\n y_axis: (\n x: 0.07554897,\n y: -0.7266143,\n z: 0.29013103,\n ),\n z_axis: (\n x: 0.13679053,\n y: -0.30925363,\n z: -0.7550475,\n ),\n ),\n translation: (\n x: 0.07032481,\n y: 0.63352835,\n z: -0.7780098,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2263589,\n y: 0.082071505,\n z: 0.21933739,\n ),\n y_axis: (\n x: 0.18583152,\n y: -1.1703705,\n z: -0.4212634,\n ),\n z_axis: (\n x: 0.14606394,\n y: 0.49423102,\n z: -1.1121413,\n ),\n ),\n translation: (\n x: -0.09033383,\n y: 1.1202078,\n z: -0.61379933,\n ),\n )),\n },\n ),\n 107: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 4,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0054815477,\n y: 0.10121223,\n z: -0.02157775,\n ),\n rotation: (\n x: -0.18912506,\n y: 0.68433076,\n z: -0.13977826,\n w: -0.6902066,\n ),\n scale: (\n x: 0.9999994,\n y: 1.000001,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12940192426512144989,\n name: \"DEF-f_ring.01.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 106,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0054815477,\n y: 0.10121223,\n z: -0.02157775,\n ),\n rotation: (\n x: -0.18912506,\n y: 0.68433076,\n z: -0.13977826,\n w: -0.6902066,\n ),\n scale: (\n x: 0.9999994,\n y: 1.000001,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7876154,\n y: 0.1073655,\n z: 0.09442983,\n ),\n y_axis: (\n x: -0.020014655,\n y: -0.30631176,\n z: 0.73536587,\n ),\n z_axis: (\n x: 0.14601612,\n y: -0.7273625,\n z: -0.34345776,\n ),\n ),\n translation: (\n x: 0.071144074,\n y: 0.64606684,\n z: -0.80811113,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2296807,\n y: -0.061109547,\n z: 0.2072472,\n ),\n y_axis: (\n x: 0.19307542,\n y: -0.5461784,\n z: -1.1163203,\n ),\n z_axis: (\n x: 0.11389283,\n y: 1.130697,\n z: -0.45935506,\n ),\n ),\n translation: (\n x: -0.12018606,\n y: 1.2709441,\n z: 0.3352632,\n ),\n )),\n },\n ),\n 108: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 15,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 1.1971267,\n y: 0.38694215,\n z: -0.8188069,\n ),\n rotation: (\n x: 0.0,\n y: -0.2626093,\n z: 0.0,\n w: 0.9649021,\n ),\n scale: (\n x: 2.2788744,\n y: 2.2788746,\n z: 2.2788744,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9874645199171359513,\n name: \"RecordPlayer\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 237,\n ]),\n },\n ),\n 109: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 2,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000007916242,\n y: 0.040812954,\n z: 0.000000044703484,\n ),\n rotation: (\n x: 0.39240488,\n y: 0.0037930708,\n z: 0.0075233243,\n w: 0.9197541,\n ),\n scale: (\n x: 0.99999976,\n y: 0.99999845,\n z: 0.9999983,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17112179495409933697,\n name: \"DEF-f_middle.02.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 85,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000007916242,\n y: 0.040812954,\n z: 0.000000044703484,\n ),\n rotation: (\n x: 0.39240488,\n y: 0.0037930708,\n z: 0.0075233243,\n w: 0.9197541,\n ),\n scale: (\n x: 0.99999976,\n y: 0.99999845,\n z: 0.9999983,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7852933,\n y: 0.05299385,\n z: 0.16004217,\n ),\n y_axis: (\n x: -0.002101379,\n y: -0.7044141,\n z: 0.34143278,\n ),\n z_axis: (\n x: 0.15927663,\n y: -0.36796927,\n z: -0.7248813,\n ),\n ),\n translation: (\n x: 0.08852929,\n y: 0.63775176,\n z: -0.7720116,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.222326,\n y: -0.039337747,\n z: 0.2513412,\n ),\n y_axis: (\n x: 0.1015491,\n y: -1.1425645,\n z: -0.51574916,\n ),\n z_axis: (\n x: 0.2170301,\n y: 0.57135296,\n z: -1.0625014,\n ),\n ),\n translation: (\n x: -0.005425021,\n y: 1.1732461,\n z: -0.5135945,\n ),\n )),\n },\n ),\n 110: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0031145858,\n y: 0.10229091,\n z: 0.005880978,\n ),\n rotation: (\n x: -0.119379885,\n y: 0.7123179,\n z: -0.12289206,\n w: -0.6806242,\n ),\n scale: (\n x: 0.9999992,\n y: 1.0000023,\n z: 1.0000004,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 2550873139557924423,\n name: \"DEF-f_middle.01.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 109,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0031145858,\n y: 0.10229091,\n z: 0.005880978,\n ),\n rotation: (\n x: -0.119379885,\n y: 0.7123179,\n z: -0.12289206,\n w: -0.6806242,\n ),\n scale: (\n x: 0.9999992,\n y: 1.0000023,\n z: 1.0000004,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7872565,\n y: 0.055897888,\n z: 0.14697292,\n ),\n y_axis: (\n x: -0.10321059,\n y: -0.220919,\n z: 0.76213896,\n ),\n z_axis: (\n x: 0.1078614,\n y: -0.7632046,\n z: -0.2553193,\n ),\n ),\n translation: (\n x: 0.09274164,\n y: 0.64676815,\n z: -0.80311674,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2258176,\n y: -0.18807542,\n z: 0.14422089,\n ),\n y_axis: (\n x: 0.10730197,\n y: -0.41660452,\n z: -1.1818144,\n ),\n z_axis: (\n x: 0.1971063,\n y: 1.1658673,\n z: -0.3230384,\n ),\n ),\n translation: (\n x: -0.02478446,\n y: 1.2232165,\n z: 0.49154714,\n ),\n )),\n },\n ),\n 111: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 18,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 3.2734413,\n y: -4.1047897,\n z: -1.0052221,\n ),\n rotation: (\n x: -0.49982512,\n y: 0.740724,\n z: 0.25108522,\n w: 0.37210032,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14475911846627277336,\n name: \"Couch\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 240,\n ]),\n },\n ),\n 112: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000002561137,\n y: 0.04212814,\n z: 0.00000005122274,\n ),\n rotation: (\n x: 0.34092632,\n y: -0.0026616517,\n z: 0.0038947405,\n w: 0.9400782,\n ),\n scale: (\n x: 0.99999994,\n y: 0.99999607,\n z: 0.9999995,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9596041477818104271,\n name: \"DEF-f_index.02.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 83,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000002561137,\n y: 0.04212814,\n z: 0.00000005122274,\n ),\n rotation: (\n x: 0.34092632,\n y: -0.0026616517,\n z: 0.0038947405,\n w: 0.9400782,\n ),\n scale: (\n x: 0.99999994,\n y: 0.99999607,\n z: 0.9999995,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.78680634,\n y: -0.0074253967,\n z: 0.16622536,\n ),\n y_axis: (\n x: -0.07192471,\n y: -0.6686743,\n z: 0.39604318,\n ),\n z_axis: (\n x: 0.13350025,\n y: -0.4326967,\n z: -0.69509673,\n ),\n ),\n translation: (\n x: 0.10903178,\n y: 0.63584375,\n z: -0.7692251,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2221503,\n y: -0.14809379,\n z: 0.20788594,\n ),\n y_axis: (\n x: 0.0055275634,\n y: -1.0933145,\n z: -0.62161267,\n ),\n z_axis: (\n x: 0.23128523,\n y: 0.6521438,\n z: -1.011769,\n ),\n ),\n translation: (\n x: 0.04114251,\n y: 1.2129695,\n z: -0.40569583,\n ),\n )),\n },\n ),\n 113: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 20,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -1.42389,\n y: 0.015660167,\n z: -2.1356716,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 0.7147456,\n y: 0.7147456,\n z: 0.7147456,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6132158258125559600,\n name: \"PottedPlant.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 243,\n 244,\n 245,\n 246,\n 247,\n ]),\n },\n ),\n 114: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0011459216,\n y: 0.0999801,\n z: 0.033068236,\n ),\n rotation: (\n x: -0.1134205,\n y: 0.733894,\n z: -0.14063163,\n w: -0.65479636,\n ),\n scale: (\n x: 0.99999964,\n y: 1.0000001,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9885556327741512499,\n name: \"DEF-f_index.01.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 112,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0011459216,\n y: 0.0999801,\n z: 0.033068236,\n ),\n rotation: (\n x: -0.1134205,\n y: 0.733894,\n z: -0.14063163,\n w: -0.65479636,\n ),\n scale: (\n x: 0.99999964,\n y: 1.0000001,\n z: 0.99999994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7871151,\n y: -0.0002987022,\n z: 0.16423167,\n ),\n y_axis: (\n x: -0.13644509,\n y: -0.23589046,\n z: 0.75045115,\n ),\n z_axis: (\n x: 0.062389657,\n y: -0.76076674,\n z: -0.27837625,\n ),\n ),\n translation: (\n x: 0.114779934,\n y: 0.6457814,\n z: -0.8008402,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2229607,\n y: -0.24018937,\n z: 0.07399519,\n ),\n y_axis: (\n x: 0.016977627,\n y: -0.44063097,\n z: -1.1778439,\n ),\n z_axis: (\n x: 0.22769216,\n y: 1.1503569,\n z: -0.35677984,\n ),\n ),\n translation: (\n x: 0.031009838,\n y: 1.2333722,\n z: 0.4664129,\n ),\n )),\n },\n ),\n 115: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 22,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.23912162,\n y: 0.7980224,\n z: -0.4810695,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: -0.8698548,\n w: 0.49330795,\n ),\n scale: (\n x: 0.8,\n y: 0.8,\n z: 0.8,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1489012337981181736,\n name: \"WindowFrame\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 250,\n ]),\n },\n ),\n 116: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 23,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -1.369106,\n y: -0.12206435,\n z: 0.21434355,\n ),\n rotation: (\n x: 0.0,\n y: 0.47265288,\n z: 0.0,\n w: 0.8812487,\n ),\n scale: (\n x: 1.744413,\n y: 1.744413,\n z: 1.744413,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9645133002790414131,\n name: \"WickerBasket\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 251,\n ]),\n },\n ),\n 117: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 24,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.07248839,\n y: 0.76233387,\n z: -2.217077,\n ),\n rotation: (\n x: 0.0,\n y: 0.33842337,\n z: 0.0,\n w: 0.940994,\n ),\n scale: (\n x: 0.6608651,\n y: 0.66086507,\n z: 0.6608651,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15390124259403968010,\n name: \"DeskLamp\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 252,\n ]),\n },\n ),\n 118: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 25,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.8473456,\n y: 0.73900187,\n z: 0.8150909,\n ),\n rotation: (\n x: 0.0,\n y: -0.62874997,\n z: 0.0,\n w: 0.77760744,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1561803185303684793,\n name: \"PottedPlant.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 253,\n ]),\n },\n ),\n 119: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 26,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -1.215474,\n y: 0.40508628,\n z: -2.3355005,\n ),\n rotation: (\n x: 0.09599932,\n y: 0.0,\n z: 0.0,\n w: 0.99538124,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15443276149788489367,\n name: \"Cabinet\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 254,\n ]),\n },\n ),\n 120: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 27,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 1.2583761,\n y: 2.2868338,\n z: -2.3932757,\n ),\n rotation: (\n x: 0.6296553,\n y: -0.3217674,\n z: -0.3217674,\n w: 0.6296553,\n ),\n scale: (\n x: 1.0,\n y: 1.0000001,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5821398879068258117,\n name: \"SoundDamping\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 255,\n ]),\n },\n ),\n 121: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 28,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 2.183007,\n y: 1.8904047,\n z: 2.7839916,\n ),\n rotation: (\n x: -0.52536356,\n y: 0.06577978,\n z: 0.11015199,\n w: -0.8411495,\n ),\n scale: (\n x: 0.11602068,\n y: 0.8444027,\n z: 0.53142613,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9249022766590542002,\n name: \"WindowGlow\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 256,\n ]),\n },\n ),\n 122: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 29,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 4.288921,\n y: 0.4595691,\n z: -1.6383805,\n ),\n rotation: (\n x: 0.0,\n y: -0.70710665,\n z: 0.0,\n w: 0.7071068,\n ),\n scale: (\n x: 0.6226665,\n y: 0.62266654,\n z: 0.6226665,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10285417804828783084,\n name: \"Curtain\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 257,\n ]),\n },\n ),\n 123: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 30,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.5765413,\n y: 1.2501562,\n z: 2.285594,\n ),\n rotation: (\n x: 0.025290845,\n y: -0.6953099,\n z: 0.024496824,\n w: 0.71784705,\n ),\n scale: (\n x: 0.062256712,\n y: 0.06225672,\n z: 0.062256724,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15117750533420360168,\n name: \"KitsuneMask\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 258,\n 259,\n 260,\n ]),\n },\n ),\n 124: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 31,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.82148117,\n y: 0.426226,\n z: -2.3980668,\n ),\n rotation: (\n x: 0.70710677,\n y: 0.0,\n z: 0.0,\n w: 0.7071067,\n ),\n scale: (\n x: 0.048908196,\n y: 1.0000001,\n z: 0.08151366,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1975187030674379270,\n name: \"Outlet\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 261,\n ]),\n },\n ),\n 125: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 32,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 2.157037,\n y: 0.426226,\n z: 0.59452164,\n ),\n rotation: (\n x: 0.5,\n y: -0.5,\n z: 0.49999994,\n w: 0.50000006,\n ),\n scale: (\n x: 0.048908196,\n y: 1.0,\n z: 0.08151365,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11568187364738202027,\n name: \"Outlet.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 262,\n ]),\n },\n ),\n 126: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 33,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 3.3845227,\n y: 0.004259348,\n z: -3.888702,\n ),\n rotation: (\n x: 0.0,\n y: -0.35574248,\n z: 0.0,\n w: 0.9345841,\n ),\n scale: (\n x: 0.40171644,\n y: 0.4017164,\n z: 0.40171644,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12655005651174309918,\n name: \"PottedPlant.Hanging\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 263,\n 264,\n 265,\n 266,\n ]),\n },\n ),\n 127: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 34,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.11092639,\n y: 0.3552581,\n z: 0.46040297,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9894652360885939467,\n name: \"Candle\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 267,\n 268,\n 269,\n 270,\n ]),\n },\n ),\n 128: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 35,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 3.063862,\n y: -0.5328591,\n z: 1.6095524,\n ),\n rotation: (\n x: 0.0,\n y: -0.70710665,\n z: 0.0,\n w: 0.7071068,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10831817149998930255,\n name: \"Books\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 271,\n 272,\n 273,\n ]),\n },\n ),\n 129: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 36,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.42415488,\n y: 0.8716657,\n z: -2.2955422,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 0.045855366,\n y: 0.045855366,\n z: 0.045855366,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18417166895556635729,\n name: \"MonitorStand\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 274,\n ]),\n },\n ),\n 130: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.42163727,\n y: 0.75192964,\n z: -1.9986508,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.1121004,\n y: 1.1121004,\n z: 1.1121004,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13400654538445729192,\n name: \"Keyboard\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 275,\n 276,\n 277,\n 278,\n 279,\n 280,\n 281,\n 282,\n 283,\n 284,\n 285,\n 286,\n 287,\n 288,\n 289,\n 290,\n 291,\n 292,\n 293,\n 294,\n 295,\n 296,\n 297,\n 298,\n 299,\n 300,\n 301,\n 302,\n 303,\n 304,\n 305,\n 306,\n 307,\n 308,\n 309,\n 310,\n 311,\n 312,\n 313,\n 314,\n 315,\n 316,\n 317,\n 318,\n 319,\n 320,\n 321,\n 322,\n 323,\n 324,\n 325,\n 326,\n 327,\n 328,\n 329,\n 330,\n 331,\n 332,\n 333,\n 334,\n 335,\n 336,\n 337,\n 338,\n 339,\n 340,\n ]),\n },\n ),\n 131: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 38,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 1.9138453,\n y: 1.3213503,\n z: -0.36268377,\n ),\n rotation: (\n x: 0.0,\n y: 0.70710677,\n z: 0.0,\n w: -0.7071067,\n ),\n scale: (\n x: 0.04585537,\n y: 0.045855366,\n z: 0.04585537,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13395076145067180508,\n name: \"MaskStand\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 341,\n ]),\n },\n ),\n 132: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000014901161,\n y: 0.12935498,\n z: -0.000000039115548,\n ),\n rotation: (\n x: 0.15585105,\n y: -0.27614477,\n z: -0.14933468,\n w: 0.93656313,\n ),\n scale: (\n x: 0.99059707,\n y: 1.0240182,\n z: 0.98633975,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11531795606737597020,\n name: \"DEF-hand.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 114,\n 84,\n 110,\n 86,\n 107,\n 88,\n 102,\n 90,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000014901161,\n y: 0.12935498,\n z: -0.000000039115548,\n ),\n rotation: (\n x: 0.15585105,\n y: -0.27614477,\n z: -0.14933468,\n w: 0.93656313,\n ),\n scale: (\n x: 0.99059707,\n y: 1.0240182,\n z: 0.98633975,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.10202823,\n y: 0.78965443,\n z: -0.023651166,\n ),\n y_axis: (\n x: -0.13575657,\n y: 0.049539626,\n z: 0.80317533,\n ),\n z_axis: (\n x: 0.783084,\n y: 0.09166241,\n z: 0.14829743,\n ),\n ),\n translation: (\n x: 0.10234077,\n y: 0.6387022,\n z: -0.88607275,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.12732162,\n y: -0.22913618,\n z: 1.2206901,\n ),\n y_axis: (\n x: 1.2469779,\n y: 0.006513251,\n z: 0.16359824,\n ),\n z_axis: (\n x: -0.098433755,\n y: 1.2059268,\n z: 0.19623624,\n ),\n ),\n translation: (\n x: -0.8706369,\n y: 1.0878289,\n z: -0.055537358,\n ),\n )),\n },\n ),\n 133: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18045778666172745289,\n name: \"body\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 361,\n 356,\n ]),\n },\n ),\n 134: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14880833708853073172,\n name: \"body.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 357,\n ]),\n },\n ),\n 135: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1357593118992772985,\n name: \"eye.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 366,\n 362,\n 365,\n ]),\n },\n ),\n 136: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17046802271367873778,\n name: \"eye.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 355,\n 351,\n 358,\n ]),\n },\n ),\n 137: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 4,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5715830347716040209,\n name: \"hair\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 352,\n 363,\n ]),\n },\n ),\n 138: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 5,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3119583216072405829,\n name: \"Shoe Collapsed\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 359,\n 353,\n 354,\n 360,\n 364,\n ]),\n },\n ),\n 139: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 6,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000002682209,\n y: 0.5970744,\n z: -0.0808239,\n ),\n rotation: (\n x: 0.03861155,\n y: 0.000000099462,\n z: 0.0000000038432515,\n w: 0.9992543,\n ),\n scale: (\n x: 1.0,\n y: 0.9999999,\n z: 1.0000002,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3375322073687174018,\n name: \"DEF-spine\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 140,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000002682209,\n y: 0.5970744,\n z: -0.0808239,\n ),\n rotation: (\n x: 0.03861155,\n y: 0.000000099462,\n z: 0.0000000038432515,\n w: 0.9992543,\n ),\n scale: (\n x: 1.0,\n y: 0.9999999,\n z: 1.0000002,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041385,\n y: 0.000000012352801,\n z: -0.00000015960448,\n ),\n y_axis: (\n x: -0.0000000000000057137467,\n y: 0.80174065,\n z: 0.062051754,\n ),\n z_axis: (\n x: 0.00000016008185,\n y: -0.062051773,\n z: 0.80174094,\n ),\n ),\n translation: (\n x: 0.35011247,\n y: 0.4801305,\n z: -1.060749,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435669,\n y: -0.000000000000010248468,\n z: 0.00000024755985,\n ),\n y_axis: (\n x: 0.0000000191031,\n y: 1.2398592,\n z: -0.095960476,\n ),\n z_axis: (\n x: -0.00000024682177,\n y: 0.0959605,\n z: 1.2398587,\n ),\n ),\n translation: (\n x: -0.43538854,\n y: -0.49350423,\n z: 1.3612524,\n ),\n )),\n },\n ),\n 140: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 6,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0000000027670204,\n y: 0.13062902,\n z: 0.00000005314621,\n ),\n rotation: (\n x: -0.084218055,\n y: 0.0000000081815745,\n z: -0.00000015355982,\n w: 0.9964473,\n ),\n scale: (\n x: 0.99999976,\n y: 1.0000004,\n z: 0.99999964,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7688341712200164148,\n name: \"DEF-spine.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 141,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0000000027670204,\n y: 0.13062902,\n z: 0.00000005314621,\n ),\n rotation: (\n x: -0.084218055,\n y: 0.0000000081815745,\n z: -0.00000015355982,\n w: 0.9964473,\n ),\n scale: (\n x: 0.99999976,\n y: 1.0000004,\n z: 0.99999964,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041383,\n y: -0.00000023470075,\n z: -0.00000017101492,\n ),\n y_axis: (\n x: 0.00000021811347,\n y: 0.8007826,\n z: -0.073390864,\n ),\n z_axis: (\n x: 0.00000019172151,\n y: 0.073390745,\n z: 0.8007823,\n ),\n ),\n translation: (\n x: 0.35011247,\n y: 0.5848611,\n z: -1.0526433,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435672,\n y: 0.00000033730325,\n z: 0.00000029648947,\n ),\n y_axis: (\n x: -0.00000036295526,\n y: 1.2383766,\n z: 0.11349593,\n ),\n z_axis: (\n x: -0.00000026446767,\n y: -0.113495745,\n z: 1.2383771,\n ),\n ),\n translation: (\n x: -0.43538845,\n y: -0.843749,\n z: 1.2371899,\n ),\n )),\n },\n ),\n 141: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 6,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000058852834,\n y: 0.1366367,\n z: -0.000000015404574,\n ),\n rotation: (\n x: -0.023675302,\n y: 0.0000000022134032,\n z: 0.00000023702127,\n w: 0.9997197,\n ),\n scale: (\n x: 0.99999994,\n y: 0.9999999,\n z: 0.9999996,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9317573219792888488,\n name: \"DEF-spine.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 142,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000058852834,\n y: 0.1366367,\n z: -0.000000015404574,\n ),\n rotation: (\n x: -0.023675302,\n y: 0.0000000022134032,\n z: 0.00000023702127,\n w: 0.9997197,\n ),\n scale: (\n x: 0.99999994,\n y: 0.9999999,\n z: 0.9999996,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.80413824,\n y: 0.00000014356544,\n z: -0.00000021831903,\n ),\n y_axis: (\n x: -0.00000017237981,\n y: 0.7964107,\n z: -0.11121548,\n ),\n z_axis: (\n x: 0.00000019636525,\n y: 0.111215346,\n z: 0.7964101,\n ),\n ),\n translation: (\n x: 0.35011253,\n y: 0.6942774,\n z: -1.0626712,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435671,\n y: -0.00000026657872,\n z: 0.00000030367104,\n ),\n y_axis: (\n x: 0.00000022201755,\n y: 1.2316158,\n z: 0.1719902,\n ),\n z_axis: (\n x: -0.00000033762146,\n y: -0.17199,\n z: 1.2316167,\n ),\n ),\n translation: (\n x: -0.43538892,\n y: -1.0378517,\n z: 1.1893946,\n ),\n )),\n },\n ),\n 142: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 6,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000016260245,\n y: 0.17288758,\n z: 0.000000016912061,\n ),\n rotation: (\n x: 0.026351118,\n y: -0.00000012711658,\n z: -0.000000019034031,\n w: 0.9996528,\n ),\n scale: (\n x: 1.0000004,\n y: 0.9999992,\n z: 1.0000004,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1927201636905016304,\n name: \"DEF-spine.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 143,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000016260245,\n y: 0.17288758,\n z: 0.000000016912061,\n ),\n rotation: (\n x: 0.026351118,\n y: -0.00000012711658,\n z: -0.000000019034031,\n w: 0.9996528,\n ),\n scale: (\n x: 1.0000004,\n y: 0.9999992,\n z: 1.0000004,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041385,\n y: 0.00000013607604,\n z: -0.00000001173702,\n ),\n y_axis: (\n x: -0.00000013658084,\n y: 0.80116326,\n z: -0.069102935,\n ),\n z_axis: (\n x: -0.00000000000009141996,\n y: 0.06910287,\n z: 0.8011636,\n ),\n ),\n translation: (\n x: 0.3501125,\n y: 0.8319669,\n z: -1.0818989,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435669,\n y: -0.00000021121744,\n z: 0.000000000000029037353,\n ),\n y_axis: (\n x: 0.00000021043545,\n y: 1.2389677,\n z: 0.10686493,\n ),\n z_axis: (\n x: -0.000000018150574,\n y: -0.106864825,\n z: 1.2389671,\n ),\n ),\n translation: (\n x: -0.4353885,\n y: -1.1463969,\n z: 1.2515291,\n ),\n )),\n },\n ),\n 143: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 6,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000006644628,\n y: 0.21820268,\n z: 0.000000029802337,\n ),\n rotation: (\n x: 0.07974755,\n y: 0.000000022860096,\n z: 0.0000010199825,\n w: 0.996815,\n ),\n scale: (\n x: 0.9999975,\n y: 1.0000046,\n z: 0.9999977,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11877166334003091052,\n name: \"DEF-spine.004\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 144,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000006644628,\n y: 0.21820268,\n z: 0.000000029802337,\n ),\n rotation: (\n x: 0.07974755,\n y: 0.000000022860096,\n z: 0.0000010199825,\n w: 0.996815,\n ),\n scale: (\n x: 0.9999975,\n y: 1.0000046,\n z: 0.9999977,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041365,\n y: 0.000001776225,\n z: -0.000000058685043,\n ),\n y_axis: (\n x: -0.0000017671094,\n y: 0.8019632,\n z: 0.05915099,\n ),\n z_axis: (\n x: 0.00000018918136,\n y: -0.059150588,\n z: 0.80195796,\n ),\n ),\n translation: (\n x: 0.35011247,\n y: 1.0067829,\n z: -1.0969774,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.24357,\n y: -0.0000027327374,\n z: 0.0000002925628,\n ),\n y_axis: (\n x: 0.0000027468748,\n y: 1.2401931,\n z: -0.091474436,\n ),\n z_axis: (\n x: -0.00000009075414,\n y: 0.09147381,\n z: 1.2402012,\n ),\n ),\n translation: (\n x: -0.4353922,\n y: -1.1482596,\n z: 1.4525675,\n ),\n )),\n },\n ),\n 144: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 6,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000006359967,\n y: 0.05059528,\n z: 0.0000000800804,\n ),\n rotation: (\n x: -0.027318873,\n y: 0.000000058820557,\n z: -0.0000019413212,\n w: 0.9996268,\n ),\n scale: (\n x: 1.0000049,\n y: 0.9999905,\n z: 1.0000048,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3395757788831111167,\n name: \"DEF-spine.005\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 11,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000006359967,\n y: 0.05059528,\n z: 0.0000000800804,\n ),\n rotation: (\n x: -0.027318873,\n y: 0.000000058820557,\n z: -0.0000019413212,\n w: 0.9996268,\n ),\n scale: (\n x: 1.0000049,\n y: 0.9999905,\n z: 1.0000048,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041404,\n y: -0.0000013382512,\n z: -0.00000029769794,\n ),\n y_axis: (\n x: 0.000001343608,\n y: 0.8039892,\n z: 0.015261704,\n ),\n z_axis: (\n x: 0.00000027224397,\n y: -0.015261249,\n z: 0.80399555,\n ),\n ),\n translation: (\n x: 0.35011232,\n y: 1.0473584,\n z: -1.0939845,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435641,\n y: 0.0000020779216,\n z: 0.00000042101456,\n ),\n y_axis: (\n x: -0.0000020694763,\n y: 1.24335,\n z: -0.023601672,\n ),\n z_axis: (\n x: -0.00000046037022,\n y: 0.023600968,\n z: 1.24334,\n ),\n ),\n translation: (\n x: -0.43538547,\n y: -1.2764148,\n z: 1.3849139,\n ),\n )),\n },\n ),\n 145: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 9,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.09798455,\n y: 0.64492065,\n z: -0.047456503,\n ),\n rotation: (\n x: 0.6550848,\n y: 0.0042179003,\n z: 0.14093779,\n w: 0.7422821,\n ),\n scale: (\n x: 1.0162966,\n y: 0.9681862,\n z: 1.0162964,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8749012787742165333,\n name: \"DEF-thigh.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 146,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.09798455,\n y: 0.64492065,\n z: -0.047456503,\n ),\n rotation: (\n x: 0.6550848,\n y: 0.0042179003,\n z: 0.14093779,\n w: 0.7422821,\n ),\n scale: (\n x: 1.0162966,\n y: 0.9681862,\n z: 1.0162964,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7847476,\n y: 0.175509,\n z: 0.14578855,\n ),\n y_axis: (\n x: -0.15859573,\n y: 0.07941343,\n z: 0.7580831,\n ),\n z_axis: (\n x: 0.15602326,\n y: -0.7938098,\n z: 0.11579703,\n ),\n ),\n translation: (\n x: 0.4289058,\n y: 0.51860553,\n z: -1.0339171,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.1749716,\n y: -0.26164475,\n z: 0.23360758,\n ),\n y_axis: (\n x: 0.2627827,\n y: 0.13101302,\n z: -1.1885405,\n ),\n z_axis: (\n x: 0.21828343,\n y: 1.2506546,\n z: 0.17337842,\n ),\n ),\n translation: (\n x: -0.4145457,\n y: 1.3373499,\n z: 0.69544697,\n ),\n )),\n },\n ),\n 146: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 9,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000014901161,\n y: 0.2435241,\n z: 0.000000074505806,\n ),\n rotation: (\n x: 0.00000015671459,\n y: -0.16373833,\n z: -0.00000022185505,\n w: 0.9865038,\n ),\n scale: (\n x: 1.0000001,\n y: 0.9999996,\n z: 1.0000007,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13335340874493887649,\n name: \"DEF-thigh.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 147,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000014901161,\n y: 0.2435241,\n z: 0.000000074505806,\n ),\n rotation: (\n x: 0.00000015671459,\n y: -0.16373833,\n z: -0.00000022185505,\n w: 0.9865038,\n ),\n scale: (\n x: 1.0000001,\n y: 0.9999996,\n z: 1.0000007,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.79307365,\n y: -0.09034768,\n z: 0.17538,\n ),\n y_axis: (\n x: -0.1585953,\n y: 0.07941315,\n z: 0.75808287,\n ),\n z_axis: (\n x: -0.10586097,\n y: -0.8079453,\n z: 0.062489796,\n ),\n ),\n translation: (\n x: 0.39028394,\n y: 0.5379445,\n z: -0.8493055,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.1874374,\n y: -0.2616443,\n z: -0.1585011,\n ),\n y_axis: (\n x: -0.13527414,\n y: 0.13101271,\n z: -1.2097033,\n ),\n z_axis: (\n x: 0.26258942,\n y: 1.2506552,\n z: 0.09356342,\n ),\n ),\n translation: (\n x: -0.16764915,\n y: 1.0938264,\n z: 0.79207766,\n ),\n )),\n },\n ),\n 147: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 9,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000052154064,\n y: 0.24352384,\n z: -0.000000059604645,\n ),\n rotation: (\n x: 0.6358372,\n y: -0.16266237,\n z: 0.14035551,\n w: 0.74130255,\n ),\n scale: (\n x: 1.000478,\n y: 0.952541,\n z: 1.048816,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1059339150765978368,\n name: \"DEF-shin.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 148,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000052154064,\n y: 0.24352384,\n z: -0.000000059604645,\n ),\n rotation: (\n x: 0.6358372,\n y: -0.16266237,\n z: 0.14035551,\n w: 0.74130255,\n ),\n scale: (\n x: 1.000478,\n y: 0.952541,\n z: 1.048816,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.67556083,\n y: -0.42116466,\n z: 0.18644099,\n ),\n y_axis: (\n x: -0.4268843,\n y: -0.64314884,\n z: 0.09385221,\n ),\n z_axis: (\n x: 0.09688817,\n y: -0.19374716,\n z: -0.7882832,\n ),\n ),\n translation: (\n x: 0.35166225,\n y: 0.5572836,\n z: -0.6646942,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.0104909,\n y: -0.70831054,\n z: 0.15466575,\n ),\n y_axis: (\n x: -0.62998515,\n y: -1.0594219,\n z: -0.27513477,\n ),\n z_axis: (\n x: 0.27903986,\n y: 0.17332993,\n z: -1.1819459,\n ),\n ),\n translation: (\n x: 0.18120505,\n y: 0.95469594,\n z: -0.6866946,\n ),\n )),\n },\n ),\n 148: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 9,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000044703484,\n y: 0.24763492,\n z: -0.000000029802322,\n ),\n rotation: (\n x: 0.0000000205467,\n y: 0.07482631,\n z: 0.000000009806377,\n w: 0.9971967,\n ),\n scale: (\n x: 0.99999994,\n y: 0.9999993,\n z: 1.0000002,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8919010978818784700,\n name: \"DEF-shin.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 149,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000044703484,\n y: 0.24763492,\n z: -0.000000029802322,\n ),\n rotation: (\n x: 0.0000000205467,\n y: 0.07482631,\n z: 0.000000009806377,\n w: 0.9971967,\n ),\n scale: (\n x: 0.99999994,\n y: 0.9999993,\n z: 1.0000002,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.653537,\n y: -0.38753498,\n z: 0.30199116,\n ),\n y_axis: (\n x: -0.42688414,\n y: -0.64314836,\n z: 0.09385208,\n ),\n z_axis: (\n x: 0.1966193,\n y: -0.2544293,\n z: -0.7516331,\n ),\n ),\n translation: (\n x: 0.24595073,\n y: 0.3980175,\n z: -0.64145315,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.9760941,\n y: -0.70831096,\n z: 0.30373242,\n ),\n y_axis: (\n x: -0.5818716,\n y: -1.0594226,\n z: -0.36606833,\n ),\n z_axis: (\n x: 0.45230064,\n y: 0.17332996,\n z: -1.1270683,\n ),\n ),\n translation: (\n x: 0.2816537,\n y: 0.7070614,\n z: -0.6519631,\n ),\n )),\n },\n ),\n 149: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 9,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000014901161,\n y: 0.2476349,\n z: 0.00000009685755,\n ),\n rotation: (\n x: -0.5217934,\n y: -0.07385024,\n z: -0.057993162,\n w: 0.8478876,\n ),\n scale: (\n x: 0.98352784,\n y: 0.99360996,\n z: 1.0238868,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5739438537571414746,\n name: \"DEF-foot.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 14,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000014901161,\n y: 0.2476349,\n z: 0.00000009685755,\n ),\n rotation: (\n x: -0.5217934,\n y: -0.07385024,\n z: -0.057993162,\n w: 0.8478876,\n ),\n scale: (\n x: 0.98352784,\n y: 0.99360996,\n z: 1.0238868,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.67629033,\n y: -0.40745574,\n z: 0.15249604,\n ),\n y_axis: (\n x: -0.24762085,\n y: -0.13277784,\n z: 0.74891174,\n ),\n z_axis: (\n x: -0.34429857,\n y: -0.6784526,\n z: -0.27628246,\n ),\n ),\n translation: (\n x: 0.14023936,\n y: 0.23875152,\n z: -0.61821216,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.047627,\n y: -0.4154357,\n z: -0.5478658,\n ),\n y_axis: (\n x: -0.62740576,\n y: -0.25834274,\n z: -1.0465841,\n ),\n z_axis: (\n x: 0.23515283,\n y: 1.1521081,\n z: -0.36670032,\n ),\n ),\n translation: (\n x: 0.14824988,\n y: 0.8321874,\n z: 0.10000731,\n ),\n )),\n },\n ),\n 150: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 10,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.097985536,\n y: 0.64492065,\n z: -0.047456503,\n ),\n rotation: (\n x: 0.7278779,\n y: -0.011962119,\n z: -0.14293233,\n w: 0.6705379,\n ),\n scale: (\n x: 1.0130223,\n y: 0.97445583,\n z: 1.0130222,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10608977633458449108,\n name: \"DEF-thigh.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 151,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.097985536,\n y: 0.64492065,\n z: -0.047456503,\n ),\n rotation: (\n x: 0.7278779,\n y: -0.011962119,\n z: -0.14293233,\n w: 0.6705379,\n ),\n scale: (\n x: 1.0130223,\n y: 0.97445583,\n z: 1.0130222,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7810927,\n y: -0.17033255,\n z: -0.1564316,\n ),\n y_axis: (\n x: 0.13655686,\n y: -0.07872949,\n z: 0.76757985,\n ),\n z_axis: (\n x: -0.18256772,\n y: -0.7923875,\n z: -0.048794117,\n ),\n ),\n translation: (\n x: 0.27131873,\n y: 0.51860553,\n z: -1.0339171,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.1770717,\n y: 0.22239627,\n z: -0.2751214,\n ),\n y_axis: (\n x: -0.25668347,\n y: -0.12821871,\n z: -1.1940925,\n ),\n z_axis: (\n x: -0.23573543,\n y: 1.2500794,\n z: -0.073530555,\n ),\n ),\n translation: (\n x: -0.42997503,\n y: 1.2986331,\n z: 0.6178841,\n ),\n )),\n },\n ),\n 151: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 10,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000014901161,\n y: 0.24352425,\n z: 0.000000044703484,\n ),\n rotation: (\n x: -0.000000009793206,\n y: 0.054043677,\n z: -0.00000018537132,\n w: 0.9985385,\n ),\n scale: (\n x: 0.9999999,\n y: 0.9999996,\n z: 0.9999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17631905202772458387,\n name: \"DEF-thigh.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 152,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000014901161,\n y: 0.24352425,\n z: 0.000000044703484,\n ),\n rotation: (\n x: -0.000000009793206,\n y: 0.054043677,\n z: -0.00000018537132,\n w: 0.9985385,\n ),\n scale: (\n x: 0.9999999,\n y: 0.9999996,\n z: 0.9999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7962343,\n y: -0.08381564,\n z: -0.15025176,\n ),\n y_axis: (\n x: 0.1365571,\n y: -0.07872949,\n z: 0.7675795,\n ),\n z_axis: (\n x: -0.0971984,\n y: -0.80614257,\n z: -0.06539264,\n ),\n ),\n translation: (\n x: 0.30457363,\n y: 0.49943292,\n z: -0.84699273,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.1998895,\n y: 0.22239676,\n z: -0.1464737,\n ),\n y_axis: (\n x: -0.12630638,\n y: -0.12821878,\n z: -1.2148211,\n ),\n z_axis: (\n x: -0.22642276,\n y: 1.2500798,\n z: -0.09854383,\n ),\n ),\n translation: (\n x: -0.4941516,\n y: 1.0551089,\n z: 0.56786776,\n ),\n )),\n },\n ),\n 152: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 10,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000063329935,\n y: 0.24352409,\n z: -0.000000026077032,\n ),\n rotation: (\n x: 0.5167277,\n y: 0.053519428,\n z: -0.032436393,\n w: 0.85385936,\n ),\n scale: (\n x: 1.0001523,\n y: 0.96987426,\n z: 1.0312893,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14917869540202926306,\n name: \"DEF-shin.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 153,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000063329935,\n y: 0.24352409,\n z: -0.000000026077032,\n ),\n rotation: (\n x: 0.5167277,\n y: 0.053519428,\n z: -0.032436393,\n w: 0.85385936,\n ),\n scale: (\n x: 1.0001523,\n y: 0.96987426,\n z: 1.0312893,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.80225015,\n y: 0.01755151,\n z: -0.1409908,\n ),\n y_axis: (\n x: 0.06406815,\n y: -0.73163587,\n z: 0.27346098,\n ),\n z_axis: (\n x: -0.1233732,\n y: -0.3157156,\n z: -0.7412804,\n ),\n ),\n translation: (\n x: 0.33782852,\n y: 0.48026043,\n z: -0.66006863,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2085856,\n y: 0.1105838,\n z: -0.18907702,\n ),\n y_axis: (\n x: 0.026442159,\n y: -1.1766804,\n z: -0.43911093,\n ),\n z_axis: (\n x: -0.21240988,\n y: 0.48275033,\n z: -1.1305288,\n ),\n ),\n translation: (\n x: -0.5611989,\n y: 0.84640306,\n z: -0.47146338,\n ),\n )),\n },\n ),\n 153: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 10,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000024214387,\n y: 0.2476349,\n z: -0.00000009685755,\n ),\n rotation: (\n x: 0.00000019167345,\n y: -0.054669533,\n z: -0.00000029660418,\n w: 0.9985045,\n ),\n scale: (\n x: 1.0000004,\n y: 0.9999994,\n z: 1.0000005,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3056556147272866219,\n name: \"DEF-shin.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 154,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000024214387,\n y: 0.2476349,\n z: -0.00000009685755,\n ),\n rotation: (\n x: 0.00000019167345,\n y: -0.054669533,\n z: -0.00000029660418,\n w: 0.9985045,\n ),\n scale: (\n x: 1.0000004,\n y: 0.9999994,\n z: 1.0000005,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.78398573,\n y: -0.017021399,\n z: -0.22107796,\n ),\n y_axis: (\n x: 0.06406854,\n y: -0.7316355,\n z: 0.27346045,\n ),\n z_axis: (\n x: -0.21022196,\n y: -0.3157445,\n z: -0.72145706,\n ),\n ),\n translation: (\n x: 0.35369402,\n y: 0.2990819,\n z: -0.5923501,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.1807181,\n y: 0.11058444,\n z: -0.31989467,\n ),\n y_axis: (\n x: -0.021655321,\n y: -1.1766815,\n z: -0.43937242,\n ),\n z_axis: (\n x: -0.33456644,\n y: 0.48275003,\n z: -1.1005807,\n ),\n ),\n translation: (\n x: -0.6093167,\n y: 0.5987681,\n z: -0.407376,\n ),\n )),\n },\n ),\n 154: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 10,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000013038516,\n y: 0.24763495,\n z: 0.000000070780516,\n ),\n rotation: (\n x: -0.44218013,\n y: 0.09668952,\n z: 0.09688291,\n w: 0.88642025,\n ),\n scale: (\n x: 0.9873154,\n y: 1.0008614,\n z: 1.0126342,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10083770916238856724,\n name: \"DEF-foot.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 15,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000013038516,\n y: 0.24763495,\n z: 0.000000070780516,\n ),\n rotation: (\n x: -0.44218013,\n y: 0.09668952,\n z: 0.09688291,\n w: 0.88642025,\n ),\n scale: (\n x: 0.9873154,\n y: 1.0008614,\n z: 1.0126342,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.80385476,\n y: 0.0016678816,\n z: -0.003678363,\n ),\n y_axis: (\n x: -0.0030261062,\n y: -0.1859771,\n z: 0.7709749,\n ),\n z_axis: (\n x: -0.0055133365,\n y: -0.78486896,\n z: -0.228152,\n ),\n ),\n translation: (\n x: 0.36955962,\n y: 0.117903315,\n z: -0.52463174,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2440374,\n y: 0.0062775086,\n z: 0.0011561601,\n ),\n y_axis: (\n x: -0.009492554,\n y: -0.3523816,\n z: -1.1906203,\n ),\n z_axis: (\n x: 0.0025930696,\n y: 1.2120812,\n z: -0.28720084,\n ),\n ),\n translation: (\n x: -0.45726636,\n y: 0.67512333,\n z: -0.010723874,\n ),\n )),\n },\n ),\n 155: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 13,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.11219418,\n y: 1.4238409,\n z: -0.15483594,\n ),\n rotation: (\n x: 0.8973498,\n y: -0.11879962,\n z: 0.42422304,\n w: -0.026169406,\n ),\n scale: (\n x: 1.0000046,\n y: 0.99999034,\n z: 1.0000045,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11260636570938896637,\n name: \"DEF-ear.L.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 18,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.11219418,\n y: 1.4238409,\n z: -0.15483594,\n ),\n rotation: (\n x: 0.8973498,\n y: -0.11879962,\n z: 0.42422304,\n w: -0.026169406,\n ),\n scale: (\n x: 1.0000046,\n y: 0.99999034,\n z: 1.0000045,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.49200875,\n y: -0.18930548,\n z: 0.60723597,\n ),\n y_axis: (\n x: -0.15359403,\n y: -0.78033143,\n z: -0.118819386,\n ),\n z_axis: (\n x: 0.61723596,\n y: -0.04328604,\n z: -0.5136056,\n ),\n ),\n translation: (\n x: 0.44033235,\n y: 1.1449653,\n z: -1.120265,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.76086414,\n y: -0.23753136,\n z: 0.9545211,\n ),\n y_axis: (\n x: -0.2927504,\n y: -1.2067734,\n z: -0.06693947,\n ),\n z_axis: (\n x: 0.93905663,\n y: -0.18375279,\n z: -0.7942625,\n ),\n ),\n translation: (\n x: 1.0521482,\n y: 1.2804546,\n z: -1.2334477,\n ),\n )),\n },\n ),\n 156: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 17,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.112195134,\n y: 1.4238412,\n z: -0.15483594,\n ),\n rotation: (\n x: 0.8973501,\n y: 0.11879767,\n z: -0.42422298,\n w: -0.026170086,\n ),\n scale: (\n x: 1.0000036,\n y: 0.9999934,\n z: 1.000004,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9471286358175518815,\n name: \"DEF-ear.R.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 22,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.112195134,\n y: 1.4238412,\n z: -0.15483594,\n ),\n rotation: (\n x: 0.8973501,\n y: 0.11879767,\n z: -0.42422298,\n w: -0.026170086,\n ),\n scale: (\n x: 1.0000036,\n y: 0.9999934,\n z: 1.000004,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.49200904,\n y: 0.18930298,\n z: -0.6072354,\n ),\n y_axis: (\n x: 0.15359126,\n y: -0.78033453,\n z: -0.1188194,\n ),\n z_axis: (\n x: -0.6172358,\n y: -0.043283686,\n z: -0.5136054,\n ),\n ),\n translation: (\n x: 0.25989226,\n y: 1.1449655,\n z: -1.120265,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.7608663,\n y: 0.23752566,\n z: -0.9545218,\n ),\n y_axis: (\n x: 0.2927471,\n y: -1.2067707,\n z: -0.06693587,\n ),\n z_axis: (\n x: -0.9390576,\n y: -0.18375167,\n z: -0.7942629,\n ),\n ),\n translation: (\n x: -1.584922,\n y: 1.1141291,\n z: -0.5650729,\n ),\n )),\n },\n ),\n 157: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 20,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000044703484,\n y: 1.3598864,\n z: 0.013112426,\n ),\n rotation: (\n x: 0.8856472,\n y: 0.0056502013,\n z: 0.0015266455,\n w: -0.46432194,\n ),\n scale: (\n x: 1.0000137,\n y: 0.9999721,\n z: 1.0000132,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15914853988901991770,\n name: \"DEF-nose.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 25,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000044703484,\n y: 1.3598864,\n z: 0.013112426,\n ),\n rotation: (\n x: 0.8856472,\n y: 0.0056502013,\n z: 0.0015266455,\n w: -0.46432194,\n ),\n scale: (\n x: 1.0000137,\n y: 0.9999721,\n z: 1.0000132,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.80409443,\n y: 0.0069080135,\n z: 0.0063939244,\n ),\n y_axis: (\n x: 0.009187733,\n y: -0.45733815,\n z: -0.6613321,\n ),\n z_axis: (\n x: -0.0020448598,\n y: 0.66138697,\n z: -0.45740458,\n ),\n ),\n translation: (\n x: 0.35011232,\n y: 1.093537,\n z: -0.98521125,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2434646,\n y: 0.014209241,\n z: -0.0031622066,\n ),\n y_axis: (\n x: 0.010682665,\n y: -0.7072939,\n z: 1.0227805,\n ),\n z_axis: (\n x: 0.009887667,\n y: -1.0227795,\n z: -0.70733845,\n ),\n ),\n translation: (\n x: -0.4372927,\n y: -0.23917663,\n z: -1.814219,\n ),\n )),\n },\n ),\n 158: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 24,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.018242925,\n y: 1.4010086,\n z: -0.032601953,\n ),\n rotation: (\n x: 0.84439254,\n y: 0.3964294,\n z: 0.35813716,\n w: -0.03978361,\n ),\n scale: (\n x: 1.0020323,\n y: 0.9959472,\n z: 1.0020324,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9064924801960136579,\n name: \"DEF-lid.B.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 159,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.018242925,\n y: 1.4010086,\n z: -0.032601953,\n ),\n rotation: (\n x: 0.84439254,\n y: 0.3964294,\n z: 0.35813716,\n w: -0.03978361,\n ),\n scale: (\n x: 1.0020323,\n y: 0.9959472,\n z: 1.0020324,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.34580785,\n y: 0.5164907,\n z: 0.51276106,\n ),\n y_axis: (\n x: 0.5589978,\n y: -0.5466178,\n z: 0.17360362,\n ),\n z_axis: (\n x: 0.4619285,\n y: 0.2829376,\n z: -0.5965216,\n ),\n ),\n translation: (\n x: 0.3647825,\n y: 1.1266049,\n z: -1.021972,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.5326105,\n y: 0.8715171,\n z: 0.7114586,\n ),\n y_axis: (\n x: 0.795495,\n y: -0.85221577,\n z: 0.4357781,\n ),\n z_axis: (\n x: 0.7897507,\n y: 0.27066028,\n z: -0.91875803,\n ),\n ),\n translation: (\n x: -0.28339243,\n y: 0.9188035,\n z: -1.6894224,\n ),\n )),\n },\n ),\n 159: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 24,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000014901161,\n y: 0.013266653,\n z: 0.000000029802322,\n ),\n rotation: (\n x: 0.27003708,\n y: -0.0089937365,\n z: -0.20569514,\n w: 0.9405792,\n ),\n scale: (\n x: 0.9985941,\n y: 1.0022501,\n z: 0.9992143,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1701392538338790666,\n name: \"DEF-lid.B.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 160,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000014901161,\n y: 0.013266653,\n z: 0.000000029802322,\n ),\n rotation: (\n x: 0.27003708,\n y: -0.0089937365,\n z: -0.20569514,\n w: 0.9405792,\n ),\n scale: (\n x: 0.9985941,\n y: 1.0022501,\n z: 0.9992143,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.05389601,\n y: 0.6592943,\n z: 0.456802,\n ),\n y_axis: (\n x: 0.80045736,\n y: -0.07870136,\n z: 0.02433953,\n ),\n z_axis: (\n x: 0.068272956,\n y: 0.45080793,\n z: -0.6620912,\n ),\n ),\n translation: (\n x: 0.37219855,\n y: 1.1193532,\n z: -1.0196688,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.07910351,\n y: 1.235431,\n z: 0.099992946,\n ),\n y_axis: (\n x: 1.0223498,\n y: -0.12859489,\n z: 0.7006309,\n ),\n z_axis: (\n x: 0.7042596,\n y: 0.0398358,\n z: -1.023006,\n ),\n ),\n translation: (\n x: -0.45570123,\n y: -0.2752632,\n z: -1.8645979,\n ),\n )),\n },\n ),\n 160: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 24,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000013038516,\n y: 0.017634612,\n z: -0.000000048428774,\n ),\n rotation: (\n x: 0.30330867,\n y: -0.0027076665,\n z: -0.082139984,\n w: 0.9493416,\n ),\n scale: (\n x: 1.0012859,\n y: 0.99772704,\n z: 1.0009902,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 835581841731844831,\n name: \"DEF-lid.B.L.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 29,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000013038516,\n y: 0.017634612,\n z: -0.000000048428774,\n ),\n rotation: (\n x: 0.30330867,\n y: -0.0027076665,\n z: -0.082139984,\n w: 0.9493416,\n ),\n scale: (\n x: 1.0012859,\n y: 0.99772704,\n z: 1.0009902,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.076133065,\n y: 0.6434729,\n z: 0.4769944,\n ),\n y_axis: (\n x: 0.6884745,\n y: 0.29771703,\n z: -0.29089725,\n ),\n z_axis: (\n x: -0.40827316,\n y: 0.37727702,\n z: -0.5799513,\n ),\n ),\n translation: (\n x: 0.3863143,\n y: 1.1179652,\n z: -1.0192397,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.12098218,\n y: 1.0637041,\n z: -0.633047,\n ),\n y_axis: (\n x: 0.9962161,\n y: 0.45940506,\n z: 0.58892846,\n ),\n z_axis: (\n x: 0.73323953,\n y: -0.44996688,\n z: -0.89551437,\n ),\n ),\n translation: (\n x: -0.31965095,\n y: -1.3831471,\n z: -1.3265902,\n ),\n )),\n },\n ),\n 161: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 25,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.06737614,\n y: 1.4075269,\n z: -0.04146564,\n ),\n rotation: (\n x: -0.3622999,\n y: 0.7980127,\n z: 0.032751456,\n w: -0.4804601,\n ),\n scale: (\n x: 0.987295,\n y: 1.0259022,\n z: 0.987295,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3543819719715199535,\n name: \"DEF-lid.T.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 162,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.06737614,\n y: 1.4075269,\n z: -0.04146564,\n ),\n rotation: (\n x: -0.3622999,\n y: 0.7980127,\n z: 0.032751456,\n w: -0.4804601,\n ),\n scale: (\n x: 0.987295,\n y: 1.0259022,\n z: 0.987295,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.21895872,\n y: -0.48406318,\n z: 0.58995926,\n ),\n y_axis: (\n x: -0.451066,\n y: 0.60662514,\n z: 0.33032802,\n ),\n z_axis: (\n x: -0.6276415,\n y: -0.23489699,\n z: -0.42567784,\n ),\n ),\n translation: (\n x: 0.4042924,\n y: 1.1318465,\n z: -1.0290996,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.3473815,\n y: -0.66277564,\n z: -0.9957632,\n ),\n y_axis: (\n x: -0.76797396,\n y: 0.8913471,\n z: -0.3726678,\n ),\n z_axis: (\n x: 0.9359797,\n y: 0.48536876,\n z: -0.6753446,\n ),\n ),\n translation: (\n x: 1.9728887,\n y: -0.24142012,\n z: 0.12938541,\n ),\n )),\n },\n ),\n 162: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 25,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000013411045,\n y: 0.013119072,\n z: 0.0,\n ),\n rotation: (\n x: 0.23024927,\n y: -0.024674837,\n z: -0.19967982,\n w: 0.9521042,\n ),\n scale: (\n x: 1.0052661,\n y: 0.9912479,\n z: 1.0041293,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16524063129014319148,\n name: \"DEF-lid.T.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 163,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000013411045,\n y: 0.013119072,\n z: 0.0,\n ),\n rotation: (\n x: 0.23024927,\n y: -0.024674837,\n z: -0.19967982,\n w: 0.9521042,\n ),\n scale: (\n x: 1.0052661,\n y: 0.9912479,\n z: 1.0041293,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.0036453966,\n y: -0.6753994,\n z: 0.43425637,\n ),\n y_axis: (\n x: -0.7230228,\n y: 0.20823209,\n z: 0.29316124,\n ),\n z_axis: (\n x: -0.3379752,\n y: -0.40410435,\n z: -0.6060601,\n ),\n ),\n translation: (\n x: 0.39837483,\n y: 1.1398047,\n z: -1.0247658,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.0148636885,\n y: -1.1240236,\n z: -0.5543589,\n ),\n y_axis: (\n x: -1.0326493,\n y: 0.27784258,\n z: -0.6055206,\n ),\n z_axis: (\n x: 0.6968313,\n y: 0.44156456,\n z: -0.9371133,\n ),\n ),\n translation: (\n x: 1.8970288,\n y: 0.5835967,\n z: -0.04930377,\n ),\n )),\n },\n ),\n 163: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 25,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000021065352,\n y: 0.016781032,\n z: -0.00000008940697,\n ),\n rotation: (\n x: 0.2542787,\n y: -0.0025956635,\n z: -0.1475912,\n w: 0.9557994,\n ),\n scale: (\n x: 0.9998963,\n y: 1.0010301,\n z: 0.99907726,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8754618059612548641,\n name: \"DEF-lid.T.L.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 30,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000021065352,\n y: 0.016781032,\n z: -0.00000008940697,\n ),\n rotation: (\n x: 0.2542787,\n y: -0.0025956635,\n z: -0.1475912,\n w: 0.9557994,\n ),\n scale: (\n x: 0.9998963,\n y: 1.0010301,\n z: 0.99907726,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.232098,\n y: -0.67659354,\n z: 0.37467745,\n ),\n y_axis: (\n x: -0.76232773,\n y: -0.21438661,\n z: 0.06943889,\n ),\n z_axis: (\n x: 0.056283195,\n y: -0.39848593,\n z: -0.70405304,\n ),\n ),\n translation: (\n x: 0.3862418,\n y: 1.1432992,\n z: -1.0198463,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.34328872,\n y: -1.2025225,\n z: 0.064087085,\n ),\n y_axis: (\n x: -1.0240637,\n y: -0.3546043,\n z: -0.5799519,\n ),\n z_axis: (\n x: 0.6070513,\n y: 0.10457026,\n z: -1.0869781,\n ),\n ),\n translation: (\n x: 1.6573179,\n y: 0.9765289,\n z: -0.47024512,\n ),\n )),\n },\n ),\n 164: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 26,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.03892359,\n y: 1.4065201,\n z: -0.052212834,\n ),\n rotation: (\n x: -0.50265837,\n y: 0.5031861,\n z: 0.49697173,\n w: -0.49714923,\n ),\n scale: (\n x: 1.0,\n y: 0.9999996,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3790295425622944765,\n name: \"DEF-eye.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 31,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.03892359,\n y: 1.4065201,\n z: -0.052212834,\n ),\n rotation: (\n x: -0.50265837,\n y: 0.5031861,\n z: 0.49697173,\n w: -0.49714923,\n ),\n scale: (\n x: 1.0,\n y: 0.9999996,\n z: 1.0,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.00028489824,\n y: -0.8041382,\n z: 0.0005654348,\n ),\n y_axis: (\n x: -0.009427065,\n y: 0.0005688376,\n z: 0.80408263,\n ),\n z_axis: (\n x: -0.8040831,\n y: 0.0002783078,\n z: -0.009427236,\n ),\n ),\n translation: (\n x: 0.38141263,\n y: 1.131037,\n z: -1.0377418,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.00044067478,\n y: -0.014578532,\n z: -1.2434815,\n ),\n y_axis: (\n x: -1.2435666,\n y: 0.000879527,\n z: 0.000430302,\n ),\n z_axis: (\n x: 0.00087457825,\n y: 1.2434818,\n z: -0.014578882,\n ),\n ),\n translation: (\n x: 1.4075955,\n y: 1.2949787,\n z: 0.45866373,\n ),\n )),\n },\n ),\n 165: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 28,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.01824379,\n y: 1.4010084,\n z: -0.03260207,\n ),\n rotation: (\n x: 0.8443957,\n y: -0.39642486,\n z: -0.3581336,\n w: -0.03979391,\n ),\n scale: (\n x: 1.0020038,\n y: 0.9960049,\n z: 1.0020038,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8382297776592532362,\n name: \"DEF-lid.B.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 166,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.01824379,\n y: 1.4010084,\n z: -0.03260207,\n ),\n rotation: (\n x: 0.8443957,\n y: -0.39642486,\n z: -0.3581336,\n w: -0.03979391,\n ),\n scale: (\n x: 1.0020038,\n y: 0.9960049,\n z: 1.0020038,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.34580788,\n y: -0.51646614,\n z: -0.5127498,\n ),\n y_axis: (\n x: -0.5590318,\n y: -0.5466539,\n z: 0.17359468,\n ),\n z_axis: (\n x: -0.46190608,\n y: 0.28293884,\n z: -0.5965075,\n ),\n ),\n translation: (\n x: 0.33544216,\n y: 1.1266048,\n z: -1.0219721,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.5326409,\n y: -0.87146896,\n z: -0.71146446,\n ),\n y_axis: (\n x: -0.7955023,\n y: -0.8521732,\n z: 0.43580496,\n ),\n z_axis: (\n x: -0.7897781,\n y: 0.27061504,\n z: -0.9187883,\n ),\n ),\n translation: (\n x: -0.08958471,\n y: 1.5289509,\n z: -1.1913007,\n ),\n )),\n },\n ),\n 166: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 28,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000009685755,\n y: 0.013266712,\n z: 0.000000014901161,\n ),\n rotation: (\n x: 0.27003393,\n y: 0.008990101,\n z: 0.20570548,\n w: 0.9405778,\n ),\n scale: (\n x: 0.9986063,\n y: 1.0022333,\n z: 0.99921745,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5619393305838553419,\n name: \"DEF-lid.B.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 167,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000009685755,\n y: 0.013266712,\n z: 0.000000014901161,\n ),\n rotation: (\n x: 0.27003393,\n y: 0.008990101,\n z: 0.20570548,\n w: 0.9405778,\n ),\n scale: (\n x: 0.9986063,\n y: 1.0022333,\n z: 0.99921745,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.05386807,\n y: -0.6592958,\n z: -0.45679888,\n ),\n y_axis: (\n x: -0.8004593,\n y: -0.07872536,\n z: 0.024349812,\n ),\n z_axis: (\n x: -0.068242446,\n y: 0.45083112,\n z: -0.66207516,\n ),\n ),\n translation: (\n x: 0.32802567,\n y: 1.1193523,\n z: -1.019669,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.07912164,\n y: -1.2354305,\n z: -0.10002668,\n ),\n y_axis: (\n x: -1.0223278,\n y: -0.12853047,\n z: 0.70062816,\n ),\n z_axis: (\n x: -0.70429564,\n y: 0.039819144,\n z: -1.0230092,\n ),\n ),\n translation: (\n x: 0.4002427,\n y: 0.5897261,\n z: -1.7945693,\n ),\n )),\n },\n ),\n 167: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 28,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000010617077,\n y: 0.01763463,\n z: -0.00000010430813,\n ),\n rotation: (\n x: 0.30331582,\n y: 0.0027119496,\n z: 0.08212884,\n w: 0.94934034,\n ),\n scale: (\n x: 1.0012901,\n y: 0.9977224,\n z: 1.0009915,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9637986944968754362,\n name: \"DEF-lid.B.R.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 33,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000010617077,\n y: 0.01763463,\n z: -0.00000010430813,\n ),\n rotation: (\n x: 0.30331582,\n y: 0.0027119496,\n z: 0.08212884,\n w: 0.94934034,\n ),\n scale: (\n x: 1.0012901,\n y: 0.9977224,\n z: 1.0009915,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.076143764,\n y: -0.6434869,\n z: -0.47698405,\n ),\n y_axis: (\n x: -0.6884466,\n y: 0.29770064,\n z: -0.2908989,\n ),\n z_axis: (\n x: 0.40830863,\n y: 0.3773055,\n z: -0.5799403,\n ),\n ),\n translation: (\n x: 0.31390986,\n y: 1.1179641,\n z: -1.0192395,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.12094043,\n y: -1.0637242,\n z: 0.63303554,\n ),\n y_axis: (\n x: -0.9961911,\n y: 0.45943955,\n z: 0.5888827,\n ),\n z_axis: (\n x: -0.7332641,\n y: -0.45000955,\n z: -0.89550155,\n ),\n ),\n translation: (\n x: 0.40429848,\n y: -0.638391,\n z: -1.7697964,\n ),\n )),\n },\n ),\n 168: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 29,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.06737724,\n y: 1.4075266,\n z: -0.04146576,\n ),\n rotation: (\n x: 0.36228704,\n y: 0.79801816,\n z: 0.03274498,\n w: 0.48046124,\n ),\n scale: (\n x: 0.9873295,\n y: 1.0258315,\n z: 0.98732954,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9229106874308148906,\n name: \"DEF-lid.T.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 169,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.06737724,\n y: 1.4075266,\n z: -0.04146576,\n ),\n rotation: (\n x: 0.36228704,\n y: 0.79801816,\n z: 0.03274498,\n w: 0.48046124,\n ),\n scale: (\n x: 0.9873295,\n y: 1.0258315,\n z: 0.98732954,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.21897954,\n y: 0.48406214,\n z: -0.58998984,\n ),\n y_axis: (\n x: 0.45102635,\n y: 0.60659945,\n z: 0.33028758,\n ),\n z_axis: (\n x: 0.6276647,\n y: -0.23490398,\n z: -0.42569184,\n ),\n ),\n translation: (\n x: 0.29593205,\n y: 1.1318463,\n z: -1.0290997,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.34739015,\n y: 0.66280866,\n z: 0.9957299,\n ),\n y_axis: (\n x: 0.7679185,\n y: 0.89143205,\n z: -0.37265268,\n ),\n z_axis: (\n x: -0.9359626,\n y: 0.48537612,\n z: -0.6753193,\n ),\n ),\n translation: (\n x: -1.7295607,\n y: -0.70561004,\n z: -0.56785375,\n ),\n )),\n },\n ),\n 169: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 29,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000012665987,\n y: 0.013119027,\n z: 0.00000008940697,\n ),\n rotation: (\n x: 0.23023833,\n y: 0.02466957,\n z: 0.19969213,\n w: 0.95210433,\n ),\n scale: (\n x: 1.0052416,\n y: 0.99128866,\n z: 1.0041091,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6947752156430873687,\n name: \"DEF-lid.T.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 170,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000012665987,\n y: 0.013119027,\n z: 0.00000008940697,\n ),\n rotation: (\n x: 0.23023833,\n y: 0.02466957,\n z: 0.19969213,\n w: 0.95210433,\n ),\n scale: (\n x: 1.0052416,\n y: 0.99128866,\n z: 1.0041091,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.003630002,\n y: 0.67537683,\n z: -0.43428317,\n ),\n y_axis: (\n x: 0.7230305,\n y: 0.20820984,\n z: 0.29317057,\n ),\n z_axis: (\n x: 0.33802065,\n y: -0.4040866,\n z: -0.6060403,\n ),\n ),\n translation: (\n x: 0.3018491,\n y: 1.1398044,\n z: -1.0247667,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.014832656,\n y: 1.1239796,\n z: 0.55435145,\n ),\n y_axis: (\n x: 1.0326644,\n y: 0.27791652,\n z: -0.6055568,\n ),\n z_axis: (\n x: -0.69681764,\n y: 0.44159767,\n z: -0.93709993,\n ),\n ),\n translation: (\n x: -1.8866336,\n y: -0.20350811,\n z: -0.43742305,\n ),\n )),\n },\n ),\n 170: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 29,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000048661605,\n y: 0.016780913,\n z: -0.000000044703484,\n ),\n rotation: (\n x: 0.2542746,\n y: 0.0025960915,\n z: 0.1475873,\n w: 0.95580095,\n ),\n scale: (\n x: 0.99989486,\n y: 1.0010346,\n z: 0.9990739,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8745358964321892386,\n name: \"DEF-lid.T.R.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 34,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000048661605,\n y: 0.016780913,\n z: -0.000000044703484,\n ),\n rotation: (\n x: 0.2542746,\n y: 0.0025960915,\n z: 0.1475873,\n w: 0.95580095,\n ),\n scale: (\n x: 0.99989486,\n y: 1.0010346,\n z: 0.9990739,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.23208201,\n y: 0.67656773,\n z: -0.3746991,\n ),\n y_axis: (\n x: 0.76236635,\n y: -0.214382,\n z: 0.06946707,\n ),\n z_axis: (\n x: -0.05624183,\n y: -0.39846194,\n z: -0.70403963,\n ),\n ),\n translation: (\n x: 0.3139822,\n y: 1.1432983,\n z: -1.019847,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.34329605,\n y: 1.2024721,\n z: -0.06405963,\n ),\n y_axis: (\n x: 1.024101,\n y: -0.35454997,\n z: -0.58002305,\n ),\n z_axis: (\n x: -0.60702956,\n y: 0.10460411,\n z: -1.0869843,\n ),\n ),\n translation: (\n x: -1.8977189,\n y: 0.13448176,\n z: -0.42530477,\n ),\n )),\n },\n ),\n 171: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 30,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.038924336,\n y: 1.4065201,\n z: -0.052212834,\n ),\n rotation: (\n x: 0.502658,\n y: 0.5031859,\n z: 0.49697208,\n w: 0.4971496,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7482753679643798026,\n name: \"DEF-eye.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 35,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.038924336,\n y: 1.4065201,\n z: -0.052212834,\n ),\n rotation: (\n x: 0.502658,\n y: 0.5031859,\n z: 0.49697208,\n w: 0.4971496,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.00028518582,\n y: 0.8041383,\n z: -0.0005655786,\n ),\n y_axis: (\n x: 0.009426062,\n y: 0.00056883786,\n z: 0.8040831,\n ),\n z_axis: (\n x: 0.80408335,\n y: 0.00027842764,\n z: -0.009426375,\n ),\n ),\n translation: (\n x: 0.31881213,\n y: 1.131037,\n z: -1.0377418,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.00044085892,\n y: 0.014577187,\n z: 1.243481,\n ),\n y_axis: (\n x: 1.2435664,\n y: 0.0008797534,\n z: 0.00043074499,\n ),\n z_axis: (\n x: -0.0008745764,\n y: 1.2434809,\n z: -0.014577317,\n ),\n ),\n translation: (\n x: -1.4072866,\n y: 1.2847697,\n z: -0.4120515,\n ),\n )),\n },\n ),\n 172: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 32,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000004172325,\n y: 1.3350253,\n z: -0.01794219,\n ),\n rotation: (\n x: -0.6962853,\n y: 0.0000009078948,\n z: 0.00000087313373,\n w: 0.71776515,\n ),\n scale: (\n x: 1.0000027,\n y: 0.99999434,\n z: 1.0000026,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11811946510282771168,\n name: \"DEF-tongue\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 173,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000004172325,\n y: 1.3350253,\n z: -0.01794219,\n ),\n rotation: (\n x: -0.6962853,\n y: 0.0000009078948,\n z: 0.00000087313373,\n w: 0.71776515,\n ),\n scale: (\n x: 1.0000027,\n y: 0.99999434,\n z: 1.0000026,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041407,\n y: -0.0000000087632674,\n z: -0.0000020257999,\n ),\n y_axis: (\n x: -0.0000020245818,\n y: 0.024424374,\n z: -0.803763,\n ),\n z_axis: (\n x: 0.00000007028997,\n y: 0.8037696,\n z: 0.024424575,\n ),\n ),\n translation: (\n x: 0.35011235,\n y: 1.0735452,\n z: -1.0101835,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435637,\n y: -0.0000031309676,\n z: 0.00000010869981,\n ),\n y_axis: (\n x: -0.000000013552119,\n y: 0.037771706,\n z: 1.2429899,\n ),\n z_axis: (\n x: -0.0000031327982,\n y: -1.2430001,\n z: 0.0377714,\n ),\n ),\n translation: (\n x: -0.43539014,\n y: -1.2962067,\n z: -1.2962499,\n ),\n )),\n },\n ),\n 173: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 32,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000000016692683,\n y: 0.014720379,\n z: -0.000000040179806,\n ),\n rotation: (\n x: -0.015288617,\n y: -0.000000024453955,\n z: -0.0000012593733,\n w: 0.9998832,\n ),\n scale: (\n x: 0.9999992,\n y: 1.0000012,\n z: 0.999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11044746408711180308,\n name: \"DEF-tongue.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 37,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000000016692683,\n y: 0.014720379,\n z: -0.000000040179806,\n ),\n rotation: (\n x: -0.015288617,\n y: -0.000000024453955,\n z: -0.0000012593733,\n w: 0.9998832,\n ),\n scale: (\n x: 0.9999992,\n y: 1.0000012,\n z: 0.999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.80414003,\n y: 0.0000000000011656045,\n z: -0.000000000027122981,\n ),\n y_axis: (\n x: 0.0000000000068409627,\n y: -0.00016122735,\n z: -0.8041349,\n ),\n z_axis: (\n x: -0.000000000000039996232,\n y: 0.80413985,\n z: -0.00016081994,\n ),\n ),\n translation: (\n x: 0.35011232,\n y: 1.0739048,\n z: -1.0220151,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435645,\n y: -0.000000000041944313,\n z: -0.0000000000018109623,\n ),\n y_axis: (\n x: 0.00000000000006396805,\n y: -0.00024870207,\n z: 1.2435648,\n ),\n z_axis: (\n x: 0.0000000000105792805,\n y: -1.2435725,\n z: -0.0002493321,\n ),\n ),\n translation: (\n x: -0.43538725,\n y: -1.2706828,\n z: -1.3357251,\n ),\n )),\n },\n ),\n 174: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 34,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000004172325,\n y: 1.2932496,\n z: -0.03295386,\n ),\n rotation: (\n x: 0.5506809,\n y: -0.0000019682677,\n z: 0.000003416445,\n w: 0.8347159,\n ),\n scale: (\n x: 0.9999939,\n y: 1.0000118,\n z: 0.99999386,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4870206502454443254,\n name: \"DEF-chin\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 39,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000004172325,\n y: 1.2932496,\n z: -0.03295386,\n ),\n rotation: (\n x: 0.5506809,\n y: -0.0000019682677,\n z: 0.000003416445,\n w: 0.8347159,\n ),\n scale: (\n x: 0.9999939,\n y: 1.0000118,\n z: 0.99999386,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041336,\n y: 0.000002843213,\n z: 0.000005668041,\n ),\n y_axis: (\n x: -0.000006329687,\n y: 0.31643316,\n z: 0.73927265,\n ),\n z_axis: (\n x: 0.00000038345354,\n y: -0.73925936,\n z: 0.3164275,\n ),\n ),\n translation: (\n x: 0.35011235,\n y: 1.0399518,\n z: -1.022255,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435745,\n y: -0.000009788369,\n z: 0.00000059300226,\n ),\n y_axis: (\n x: 0.0000043969644,\n y: 0.48933926,\n z: -1.1432481,\n ),\n z_axis: (\n x: 0.000008765496,\n y: 1.1432275,\n z: 0.489348,\n ),\n ),\n translation: (\n x: -0.4353864,\n y: 0.6597841,\n z: 1.6891611,\n ),\n )),\n },\n ),\n 175: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 36,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.07963103,\n y: 1.3598447,\n z: -0.11258781,\n ),\n rotation: (\n x: 0.9578738,\n y: -0.19645132,\n z: -0.03841698,\n w: 0.20593384,\n ),\n scale: (\n x: 0.99999857,\n y: 1.0000026,\n z: 0.9999985,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4799320848903434444,\n name: \"DEF-jaw.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 176,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.07963103,\n y: 1.3598447,\n z: -0.11258781,\n ),\n rotation: (\n x: 0.9578738,\n y: -0.19645132,\n z: -0.03841698,\n w: 0.20593384,\n ),\n scale: (\n x: 0.99999857,\n y: 1.0000026,\n z: 0.9999985,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7396954,\n y: -0.31536165,\n z: 0.005882027,\n ),\n y_axis: (\n x: -0.28991556,\n y: -0.6738668,\n z: 0.32938516,\n ),\n z_axis: (\n x: -0.124246605,\n y: -0.30510828,\n z: -0.7335587,\n ),\n ),\n translation: (\n x: 0.41414705,\n y: 1.0935035,\n z: -1.0862917,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.1439116,\n y: -0.44834003,\n z: -0.19214283,\n ),\n y_axis: (\n x: -0.4876952,\n y: -1.0421017,\n z: -0.47183883,\n ),\n z_axis: (\n x: 0.009096343,\n y: 0.5093779,\n z: -1.1344218,\n ),\n ),\n translation: (\n x: 0.069430076,\n y: 1.8785536,\n z: -0.63678026,\n ),\n )),\n },\n ),\n 176: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 36,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000007450581,\n y: 0.038819134,\n z: 0.000000007450581,\n ),\n rotation: (\n x: -0.26749176,\n y: 0.0068356446,\n z: 0.12418476,\n w: 0.95549965,\n ),\n scale: (\n x: 1.000002,\n y: 0.99999624,\n z: 1.0000014,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16919223249079559928,\n name: \"DEF-jaw.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 41,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000007450581,\n y: 0.038819134,\n z: 0.000000007450581,\n ),\n rotation: (\n x: -0.26749176,\n y: 0.0068356446,\n z: 0.12418476,\n w: 0.95549965,\n ),\n scale: (\n x: 1.000002,\n y: 0.99999624,\n z: 1.0000014,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.6589486,\n y: -0.43880582,\n z: 0.1409822,\n ),\n y_axis: (\n x: -0.3544305,\n y: -0.32520807,\n z: 0.64440227,\n ),\n z_axis: (\n x: -0.29462594,\n y: -0.5901954,\n z: -0.45989668,\n ),\n ),\n translation: (\n x: 0.40289277,\n y: 1.0673444,\n z: -1.0735052,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.0190363,\n y: -0.5481147,\n z: -0.45562494,\n ),\n y_axis: (\n x: -0.6785923,\n y: -0.50291914,\n z: -0.9127086,\n ),\n z_axis: (\n x: 0.21802196,\n y: 0.9965486,\n z: -0.7112134,\n ),\n ),\n translation: (\n x: 0.54777706,\n y: 1.8274194,\n z: 0.3942511,\n ),\n )),\n },\n ),\n 177: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 37,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.079631925,\n y: 1.3598447,\n z: -0.11258781,\n ),\n rotation: (\n x: 0.9578738,\n y: 0.19645175,\n z: 0.038416885,\n w: 0.20593378,\n ),\n scale: (\n x: 0.9999985,\n y: 1.0000026,\n z: 0.9999985,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5951197593234333266,\n name: \"DEF-jaw.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 178,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.079631925,\n y: 1.3598447,\n z: -0.11258781,\n ),\n rotation: (\n x: 0.9578738,\n y: 0.19645175,\n z: 0.038416885,\n w: 0.20593378,\n ),\n scale: (\n x: 0.9999985,\n y: 1.0000026,\n z: 0.9999985,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7396951,\n y: 0.31536224,\n z: -0.0058823023,\n ),\n y_axis: (\n x: 0.28991625,\n y: -0.6738668,\n z: 0.32938507,\n ),\n z_axis: (\n x: 0.12424658,\n y: -0.3051082,\n z: -0.733559,\n ),\n ),\n translation: (\n x: 0.2860776,\n y: 1.0935035,\n z: -1.0862917,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.1439114,\n y: 0.44834098,\n z: 0.19214268,\n ),\n y_axis: (\n x: 0.487696,\n y: -1.042101,\n z: -0.47183838,\n ),\n z_axis: (\n x: -0.00909671,\n y: 0.5093774,\n z: -1.1344216,\n ),\n ),\n translation: (\n x: -0.87042636,\n y: 1.5646132,\n z: -0.77132344,\n ),\n )),\n },\n ),\n 178: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 37,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000027939677,\n y: 0.03881909,\n z: 0.000000007450581,\n ),\n rotation: (\n x: -0.2674914,\n y: -0.006835606,\n z: -0.12418409,\n w: 0.9554999,\n ),\n scale: (\n x: 1.0000007,\n y: 0.9999994,\n z: 0.9999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11254195899712889555,\n name: \"DEF-jaw.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 42,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000027939677,\n y: 0.03881909,\n z: 0.000000007450581,\n ),\n rotation: (\n x: -0.2674914,\n y: -0.006835606,\n z: -0.12418409,\n w: 0.9554999,\n ),\n scale: (\n x: 1.0000007,\n y: 0.9999994,\n z: 0.9999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.6589477,\n y: 0.43880528,\n z: -0.1409815,\n ),\n y_axis: (\n x: 0.35443148,\n y: -0.32521003,\n z: 0.6444041,\n ),\n z_axis: (\n x: 0.29462537,\n y: -0.59019417,\n z: -0.45989668,\n ),\n ),\n translation: (\n x: 0.29733184,\n y: 1.0673445,\n z: -1.0735052,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.0190382,\n y: 0.54811287,\n z: 0.4556255,\n ),\n y_axis: (\n x: 0.6785933,\n y: -0.50291866,\n z: -0.9127092,\n ),\n z_axis: (\n x: -0.21802135,\n y: 0.99654466,\n z: -0.7112155,\n ),\n ),\n translation: (\n x: -1.2613324,\n y: 1.443612,\n z: 0.07520968,\n ),\n )),\n },\n ),\n 179: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 38,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000005066395,\n y: 1.3436707,\n z: -0.0027959347,\n ),\n rotation: (\n x: -0.55178607,\n y: -0.40108174,\n z: -0.47478837,\n w: 0.5560949,\n ),\n scale: (\n x: 1.0012087,\n y: 0.9975864,\n z: 1.0012089,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9888334339540491642,\n name: \"DEF-lip.T.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 43,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000005066395,\n y: 1.3436707,\n z: -0.0027959347,\n ),\n rotation: (\n x: -0.55178607,\n y: -0.40108174,\n z: -0.47478837,\n w: 0.5560949,\n ),\n scale: (\n x: 1.0012087,\n y: 0.9975864,\n z: 1.0012089,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.18309732,\n y: -0.06878231,\n z: 0.78099114,\n ),\n y_axis: (\n x: 0.7786751,\n y: -0.04795834,\n z: -0.18677801,\n ),\n z_axis: (\n x: 0.06270539,\n y: 0.80072165,\n z: 0.055819258,\n ),\n ),\n translation: (\n x: 0.35011226,\n y: 1.0804974,\n z: -0.9980038,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.28246912,\n y: 1.210023,\n z: 0.0967372,\n ),\n y_axis: (\n x: -0.106112435,\n y: -0.07452498,\n z: 1.2352947,\n ),\n z_axis: (\n x: 1.2048563,\n y: -0.29024398,\n z: 0.08611379,\n ),\n ),\n translation: (\n x: 1.2182094,\n y: -0.6327845,\n z: -1.2826596,\n ),\n )),\n },\n ),\n 180: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 39,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000005066395,\n y: 1.3436707,\n z: -0.0027959347,\n ),\n rotation: (\n x: -0.5517828,\n y: 0.4010859,\n z: 0.4747908,\n w: 0.55609316,\n ),\n scale: (\n x: 1.0011843,\n y: 0.9976355,\n z: 1.0011843,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 975962637795697634,\n name: \"DEF-lip.T.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 44,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000005066395,\n y: 1.3436707,\n z: -0.0027959347,\n ),\n rotation: (\n x: -0.5517828,\n y: 0.4010859,\n z: 0.4747908,\n w: 0.55609316,\n ),\n scale: (\n x: 1.0011843,\n y: 0.9976355,\n z: 1.0011843,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.18308376,\n y: 0.068779916,\n z: -0.78097445,\n ),\n y_axis: (\n x: -0.77871585,\n y: -0.047958594,\n z: -0.186778,\n ),\n z_axis: (\n x: -0.062700905,\n y: 0.80070233,\n z: 0.055818275,\n ),\n ),\n translation: (\n x: 0.35011226,\n y: 1.0804974,\n z: -0.9980038,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.28246203,\n y: -1.209967,\n z: -0.09673511,\n ),\n y_axis: (\n x: 0.10611364,\n y: -0.074517965,\n z: 1.2353252,\n ),\n z_axis: (\n x: -1.2048888,\n y: -0.2902152,\n z: 0.086116694,\n ),\n ),\n translation: (\n x: -1.4160326,\n y: 0.21450487,\n z: -1.2149527,\n ),\n )),\n },\n ),\n 181: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 40,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000005066395,\n y: 1.3350853,\n z: -0.004753232,\n ),\n rotation: (\n x: -0.49764517,\n y: -0.4741766,\n z: -0.46267518,\n w: 0.5598551,\n ),\n scale: (\n x: 0.9992434,\n y: 1.0015144,\n z: 0.99924344,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14100542747364585497,\n name: \"DEF-lip.B.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 45,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000005066395,\n y: 1.3350853,\n z: -0.004753232,\n ),\n rotation: (\n x: -0.49764517,\n y: -0.4741766,\n z: -0.46267518,\n w: 0.5598551,\n ),\n scale: (\n x: 0.9992434,\n y: 1.0015144,\n z: 0.99924344,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.098172516,\n y: -0.03705779,\n z: 0.79664904,\n ),\n y_axis: (\n x: 0.79730713,\n y: 0.06165963,\n z: -0.095385514,\n ),\n z_axis: (\n x: -0.056604058,\n y: 0.80031425,\n z: 0.044203598,\n ),\n ),\n translation: (\n x: 0.35011226,\n y: 1.0735935,\n z: -0.9995777,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.15204985,\n y: 1.229276,\n z: -0.08766815,\n ),\n y_axis: (\n x: -0.05739495,\n y: 0.09506609,\n z: 1.2395272,\n ),\n z_axis: (\n x: 1.2338507,\n y: -0.14706372,\n z: 0.0684627,\n ),\n ),\n translation: (\n x: 1.241714,\n y: -0.67944854,\n z: -1.2316209,\n ),\n )),\n },\n ),\n 182: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 41,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0000005066395,\n y: 1.3350853,\n z: -0.004753232,\n ),\n rotation: (\n x: -0.49764085,\n y: 0.47418126,\n z: 0.46268183,\n w: 0.5598493,\n ),\n scale: (\n x: 0.9992164,\n y: 1.0015688,\n z: 0.99921626,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7183653190012610732,\n name: \"DEF-lip.B.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 46,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0000005066395,\n y: 1.3350853,\n z: -0.004753232,\n ),\n rotation: (\n x: -0.49764085,\n y: 0.47418126,\n z: 0.46268183,\n w: 0.5598493,\n ),\n scale: (\n x: 0.9992164,\n y: 1.0015688,\n z: 0.99921626,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.09815281,\n y: 0.03705801,\n z: -0.7966294,\n ),\n y_axis: (\n x: -0.79735255,\n y: 0.06166,\n z: -0.09537358,\n ),\n z_axis: (\n x: 0.056600217,\n y: 0.80029255,\n z: 0.044202104,\n ),\n ),\n translation: (\n x: 0.35011226,\n y: 1.0735935,\n z: -0.9995777,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.15202741,\n y: -1.2292129,\n z: 0.087667234,\n ),\n y_axis: (\n x: 0.057398554,\n y: 0.095056154,\n z: 1.2395613,\n ),\n z_axis: (\n x: -1.2338873,\n y: -0.1470296,\n z: 0.06846403,\n ),\n ),\n translation: (\n x: -1.3482156,\n y: 0.18134332,\n z: -1.2930433,\n ),\n )),\n },\n ),\n 183: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 42,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.06897235,\n y: 1.4165152,\n z: -0.038869143,\n ),\n rotation: (\n x: 0.005826399,\n y: 0.60157526,\n z: 0.40445444,\n w: 0.6888323,\n ),\n scale: (\n x: 0.9753515,\n y: 1.0511817,\n z: 0.97535133,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10548875852665732556,\n name: \"DEF-brow.B.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 184,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.06897235,\n y: 1.4165152,\n z: -0.038869143,\n ),\n rotation: (\n x: 0.005826399,\n y: 0.60157526,\n z: 0.40445444,\n w: 0.6888323,\n ),\n scale: (\n x: 0.9753515,\n y: 1.0511817,\n z: 0.97535133,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.039962895,\n y: 0.4425219,\n z: -0.64632165,\n ),\n y_axis: (\n x: -0.46507537,\n y: 0.5686856,\n z: 0.4181224,\n ),\n z_axis: (\n x: 0.6537145,\n y: 0.37536868,\n z: 0.21658657,\n ),\n ),\n translation: (\n x: 0.405576,\n y: 1.1390744,\n z: -1.0270116,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.06496389,\n y: -0.6508876,\n z: 1.0626842,\n ),\n y_axis: (\n x: 0.7193673,\n y: 0.7958935,\n z: 0.6102029,\n ),\n z_axis: (\n x: -1.0506659,\n y: 0.58517563,\n z: 0.35208505,\n ),\n ),\n translation: (\n x: -1.8721111,\n y: -0.041615367,\n z: -0.7644703,\n ),\n )),\n },\n ),\n 184: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 42,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000024214387,\n y: 0.008807838,\n z: 0.0,\n ),\n rotation: (\n x: -0.24678554,\n y: -0.04055769,\n z: 0.08411449,\n w: 0.9645601,\n ),\n scale: (\n x: 1.015693,\n y: 0.9842842,\n z: 1.0023556,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14554186573288080400,\n name: \"DEF-brow.B.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 185,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000024214387,\n y: 0.008807838,\n z: 0.0,\n ),\n rotation: (\n x: -0.24678554,\n y: -0.04055769,\n z: 0.08411449,\n w: 0.9645601,\n ),\n scale: (\n x: 1.015693,\n y: 0.9842842,\n z: 1.0023556,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.101604946,\n y: 0.5609186,\n z: -0.55952305,\n ),\n y_axis: (\n x: -0.70065343,\n y: 0.2432702,\n z: 0.34314543,\n ),\n z_axis: (\n x: 0.35932824,\n y: 0.5435529,\n z: 0.46419138,\n ),\n ),\n translation: (\n x: 0.4014797,\n y: 1.1440833,\n z: -1.0233287,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.14123544,\n y: -1.0833522,\n z: 0.6306082,\n ),\n y_axis: (\n x: 0.86080146,\n y: 0.29533046,\n z: 0.8192676,\n ),\n z_axis: (\n x: -0.89864063,\n y: 0.4927953,\n z: 0.70679766,\n ),\n ),\n translation: (\n x: -1.8477302,\n y: 0.6013528,\n z: -0.46720034,\n ),\n )),\n },\n ),\n 185: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 42,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000059604645,\n y: 0.018304884,\n z: -0.00000011920929,\n ),\n rotation: (\n x: -0.25520796,\n y: -0.041106936,\n z: 0.15429027,\n w: 0.95361054,\n ),\n scale: (\n x: 1.0009031,\n y: 1.0009562,\n z: 0.99829876,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 855462483178653962,\n name: \"DEF-brow.B.L.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 47,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000059604645,\n y: 0.018304884,\n z: -0.00000011920929,\n ),\n rotation: (\n x: -0.25520796,\n y: -0.041106936,\n z: 0.15429027,\n w: 0.95361054,\n ),\n scale: (\n x: 1.0009031,\n y: 1.0009562,\n z: 0.99829876,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.31771636,\n y: 0.60936576,\n z: -0.4233625,\n ),\n y_axis: (\n x: -0.72841156,\n y: -0.22496869,\n z: 0.20338434,\n ),\n z_axis: (\n x: -0.0048642876,\n y: 0.49723762,\n z: 0.65164506,\n ),\n ),\n translation: (\n x: 0.3886543,\n y: 1.1485362,\n z: -1.0170475,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.47535035,\n y: -1.165881,\n z: 0.055055175,\n ),\n y_axis: (\n x: 0.90890163,\n y: -0.40122154,\n z: 0.7157225,\n ),\n z_axis: (\n x: -0.69708556,\n y: 0.29744917,\n z: 0.98885673,\n ),\n ),\n translation: (\n x: -1.5681286,\n y: 1.216462,\n z: 0.16228366,\n ),\n )),\n },\n ),\n 186: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 43,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.014979869,\n y: 1.4013441,\n z: -0.019144893,\n ),\n rotation: (\n x: -0.3753413,\n y: 0.19614421,\n z: 0.9047362,\n w: 0.045812067,\n ),\n scale: (\n x: 1.0005981,\n y: 0.9988059,\n z: 1.0005984,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8945706704844143936,\n name: \"DEF-brow.B.L.004\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 48,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.014979869,\n y: 1.4013441,\n z: -0.019144893,\n ),\n rotation: (\n x: -0.3753413,\n y: 0.19614421,\n z: 0.9047362,\n w: 0.045812067,\n ),\n scale: (\n x: 1.0005981,\n y: 0.9988059,\n z: 1.0005984,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.57453066,\n y: -0.051774334,\n z: -0.56093335,\n ),\n y_axis: (\n x: -0.1848416,\n y: -0.73800623,\n z: 0.25744048,\n ),\n z_axis: (\n x: -0.53201306,\n y: 0.31324476,\n z: 0.51599675,\n ),\n ),\n translation: (\n x: 0.36215857,\n y: 1.1268747,\n z: -1.0111506,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.88742626,\n y: -0.28653383,\n z: -0.8217525,\n ),\n y_axis: (\n x: -0.07997119,\n y: -1.1440269,\n z: 0.48384085,\n ),\n z_axis: (\n x: -0.8664237,\n y: 0.3990736,\n z: 0.79701346,\n ),\n ),\n translation: (\n x: -0.46457833,\n y: 1.7964692,\n z: 0.55827737,\n ),\n )),\n },\n ),\n 187: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 44,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.06897324,\n y: 1.4165152,\n z: -0.038869143,\n ),\n rotation: (\n x: 0.0058383313,\n y: -0.60158384,\n z: -0.40443975,\n w: 0.68883324,\n ),\n scale: (\n x: 0.9753577,\n y: 1.0511678,\n z: 0.9753576,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 2917146725001570405,\n name: \"DEF-brow.B.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 188,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.06897324,\n y: 1.4165152,\n z: -0.038869143,\n ),\n rotation: (\n x: 0.0058383313,\n y: -0.60158384,\n z: -0.40443975,\n w: 0.68883324,\n ),\n scale: (\n x: 0.9753577,\n y: 1.0511678,\n z: 0.9753576,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.039960627,\n y: -0.44252077,\n z: 0.64632845,\n ),\n y_axis: (\n x: 0.46504056,\n y: 0.568698,\n z: 0.41812176,\n ),\n z_axis: (\n x: -0.65373635,\n y: 0.37534976,\n z: 0.21657154,\n ),\n ),\n translation: (\n x: 0.29464865,\n y: 1.1390744,\n z: -1.0270116,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.06495955,\n y: 0.6508562,\n z: -1.0627062,\n ),\n y_axis: (\n x: -0.7193566,\n y: 0.79593194,\n z: 0.6101642,\n ),\n z_axis: (\n x: 1.050664,\n y: 0.5851901,\n z: 0.3520562,\n ),\n ),\n translation: (\n x: 1.9175851,\n y: -0.4974026,\n z: -0.02033168,\n ),\n )),\n },\n ),\n 188: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 44,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000009685755,\n y: 0.008807719,\n z: -0.000000027939677,\n ),\n rotation: (\n x: -0.24680513,\n y: 0.040556625,\n z: -0.08412444,\n w: 0.9645543,\n ),\n scale: (\n x: 1.0156862,\n y: 0.98429495,\n z: 1.0023504,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16812480302897306702,\n name: \"DEF-brow.B.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 189,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000009685755,\n y: 0.008807719,\n z: -0.000000027939677,\n ),\n rotation: (\n x: -0.24680513,\n y: 0.040556625,\n z: -0.08412444,\n w: 0.9645543,\n ),\n scale: (\n x: 1.0156862,\n y: 0.98429495,\n z: 1.0023504,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.10161084,\n y: -0.5609209,\n z: 0.5595188,\n ),\n y_axis: (\n x: 0.700654,\n y: 0.24325928,\n z: 0.34315068,\n ),\n z_axis: (\n x: -0.35933334,\n y: 0.5435493,\n z: 0.46419027,\n ),\n ),\n translation: (\n x: 0.2987446,\n y: 1.1440834,\n z: -1.0233289,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.14124902,\n y: 1.0833466,\n z: -0.63060266,\n ),\n y_axis: (\n x: -0.86080885,\n y: 0.29532847,\n z: 0.81926876,\n ),\n z_axis: (\n x: 0.8986327,\n y: 0.49280855,\n z: 0.7068018,\n ),\n ),\n translation: (\n x: 1.9466313,\n y: -0.15721905,\n z: -0.025631964,\n ),\n )),\n },\n ),\n 189: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 44,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000017881393,\n y: 0.018305004,\n z: 0.000000033527613,\n ),\n rotation: (\n x: -0.25520974,\n y: 0.041108508,\n z: -0.1542843,\n w: 0.95361096,\n ),\n scale: (\n x: 1.0009038,\n y: 1.0009549,\n z: 0.9982994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12911751422408168518,\n name: \"DEF-brow.B.R.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 49,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000017881393,\n y: 0.018305004,\n z: 0.000000033527613,\n ),\n rotation: (\n x: -0.25520974,\n y: 0.041108508,\n z: -0.1542843,\n w: 0.95361096,\n ),\n scale: (\n x: 1.0009038,\n y: 1.0009549,\n z: 0.9982994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.3177135,\n y: -0.6093673,\n z: 0.42336002,\n ),\n y_axis: (\n x: 0.72841585,\n y: -0.2249709,\n z: 0.2033799,\n ),\n z_axis: (\n x: 0.004862442,\n y: 0.4972287,\n z: 0.65164685,\n ),\n ),\n translation: (\n x: 0.31157005,\n y: 1.1485361,\n z: -1.0170474,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.47534698,\n y: 1.1658773,\n z: -0.055049945,\n ),\n y_axis: (\n x: -0.90891176,\n y: -0.40121818,\n z: 0.7157199,\n ),\n z_axis: (\n x: 0.69707745,\n y: 0.2974436,\n z: 0.9888657,\n ),\n ),\n translation: (\n x: 1.9009826,\n y: 0.40007532,\n z: 0.200845,\n ),\n )),\n },\n ),\n 190: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 45,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.014980733,\n y: 1.4013441,\n z: -0.019144893,\n ),\n rotation: (\n x: 0.37534195,\n y: 0.1961357,\n z: 0.9047379,\n w: -0.045810737,\n ),\n scale: (\n x: 1.0005904,\n y: 0.9988198,\n z: 1.0005912,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8847874219302529424,\n name: \"DEF-brow.B.R.004\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 50,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.014980733,\n y: 1.4013441,\n z: -0.019144893,\n ),\n rotation: (\n x: 0.37534195,\n y: 0.1961357,\n z: 0.9047379,\n w: -0.045810737,\n ),\n scale: (\n x: 1.0005904,\n y: 0.9988198,\n z: 1.0005912,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.5745258,\n y: 0.05177083,\n z: 0.5609301,\n ),\n y_axis: (\n x: 0.18483746,\n y: -0.73802227,\n z: 0.25743303,\n ),\n z_axis: (\n x: 0.5320122,\n y: 0.3132299,\n z: 0.5159976,\n ),\n ),\n translation: (\n x: 0.3380661,\n y: 1.1268747,\n z: -1.0111506,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.88743204,\n y: 0.28651938,\n z: 0.82176304,\n ),\n y_axis: (\n x: 0.07996699,\n y: -1.1440194,\n z: 0.48382485,\n ),\n z_axis: (\n x: 0.8664316,\n y: 0.39905077,\n z: 0.79702634,\n ),\n ),\n translation: (\n x: 1.0859908,\n y: 1.5958045,\n z: -0.017106593,\n ),\n )),\n },\n ),\n 191: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 47,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.07959628,\n y: 1.4327805,\n z: -0.045130253,\n ),\n rotation: (\n x: 0.55022275,\n y: -0.38695148,\n z: 0.19020341,\n w: 0.71508473,\n ),\n scale: (\n x: 0.97644085,\n y: 1.048837,\n z: 0.9764408,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15676345888289556124,\n name: \"DEF-brow.T.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 52,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.07959628,\n y: 1.4327805,\n z: -0.045130253,\n ),\n rotation: (\n x: 0.55022275,\n y: -0.38695148,\n z: 0.19020341,\n w: 0.71508473,\n ),\n scale: (\n x: 0.97644085,\n y: 1.048837,\n z: 0.9764408,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.49324486,\n y: -0.12075956,\n z: 0.59887874,\n ),\n y_axis: (\n x: -0.58856714,\n y: 0.27170894,\n z: 0.53954023,\n ),\n z_axis: (\n x: -0.2701833,\n y: -0.7334578,\n z: 0.07463029,\n ),\n ),\n translation: (\n x: 0.41411912,\n y: 1.152154,\n z: -1.0320464,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.800035,\n y: -0.82740545,\n z: -0.4382329,\n ),\n y_axis: (\n x: -0.19586998,\n y: 0.38196743,\n z: -1.1896566,\n ),\n z_axis: (\n x: 0.9713714,\n y: 0.75848365,\n z: 0.12104906,\n ),\n ),\n translation: (\n x: 0.896863,\n y: 0.68534946,\n z: 1.6770765,\n ),\n )),\n },\n ),\n 192: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 50,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.079597086,\n y: 1.4327805,\n z: -0.045130253,\n ),\n rotation: (\n x: 0.55022305,\n y: 0.38695017,\n z: -0.1902016,\n w: 0.7150857,\n ),\n scale: (\n x: 0.9764431,\n y: 1.0488319,\n z: 0.9764431,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15347270855563057235,\n name: \"DEF-brow.T.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 55,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.079597086,\n y: 1.4327805,\n z: -0.045130253,\n ),\n rotation: (\n x: 0.55022305,\n y: 0.38695017,\n z: -0.1902016,\n w: 0.7150857,\n ),\n scale: (\n x: 0.9764431,\n y: 1.0488319,\n z: 0.9764431,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.4932487,\n y: 0.120760635,\n z: -0.5988777,\n ),\n y_axis: (\n x: 0.5885614,\n y: 0.27170825,\n z: 0.5395405,\n ),\n z_axis: (\n x: 0.27018455,\n y: -0.73345923,\n z: 0.074631505,\n ),\n ),\n translation: (\n x: 0.2861056,\n y: 1.152154,\n z: -1.0320464,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.8000375,\n y: 0.8274052,\n z: 0.43823278,\n ),\n y_axis: (\n x: 0.19587088,\n y: 0.38197002,\n z: -1.1896532,\n ),\n z_axis: (\n x: -0.9713652,\n y: 0.7584912,\n z: 0.12105055,\n ),\n ),\n translation: (\n x: -1.4570626,\n y: 0.10598463,\n z: 1.3702126,\n ),\n )),\n },\n ),\n 193: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 52,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0210661,\n y: 1.342549,\n z: -0.01191926,\n ),\n rotation: (\n x: -0.50217867,\n y: -0.33895493,\n z: -0.35936028,\n w: 0.709779,\n ),\n scale: (\n x: 0.991823,\n y: 1.0165563,\n z: 0.99182296,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12352656104255677988,\n name: \"DEF-cheek.B.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 57,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0210661,\n y: 1.342549,\n z: -0.01191926,\n ),\n rotation: (\n x: -0.50217867,\n y: -0.33895493,\n z: -0.35936028,\n w: 0.709779,\n ),\n scale: (\n x: 0.991823,\n y: 1.0165563,\n z: 0.99182296,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.40830407,\n y: -0.13534719,\n z: 0.6716217,\n ),\n y_axis: (\n x: 0.6952958,\n y: 0.19402514,\n z: -0.38359582,\n ),\n z_axis: (\n x: -0.09589902,\n y: 0.76285756,\n z: 0.212034,\n ),\n ),\n translation: (\n x: 0.36705273,\n y: 1.0795953,\n z: -1.0053402,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.6418797,\n y: 1.0405071,\n z: -0.15075938,\n ),\n y_axis: (\n x: -0.21277444,\n y: 0.2903578,\n z: 1.1992604,\n ),\n z_axis: (\n x: 1.0558318,\n y: -0.5740496,\n z: 0.3333308,\n ),\n ),\n translation: (\n x: 1.0555768,\n y: -1.272505,\n z: -0.9042684,\n ),\n )),\n },\n ),\n 194: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 53,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.021067202,\n y: 1.342549,\n z: -0.01191926,\n ),\n rotation: (\n x: -0.5021782,\n y: 0.3389549,\n z: 0.35935962,\n w: 0.7097796,\n ),\n scale: (\n x: 0.99182063,\n y: 1.0165617,\n z: 0.9918204,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11555013577163372040,\n name: \"DEF-cheek.B.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 58,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.021067202,\n y: 1.342549,\n z: -0.01191926,\n ),\n rotation: (\n x: -0.5021782,\n y: 0.3389549,\n z: 0.35935962,\n w: 0.7097796,\n ),\n scale: (\n x: 0.99182063,\n y: 1.0165617,\n z: 0.9918204,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.40830383,\n y: 0.13534671,\n z: -0.6716196,\n ),\n y_axis: (\n x: -0.69529885,\n y: 0.19402775,\n z: -0.38359815,\n ),\n z_axis: (\n x: 0.09589984,\n y: 0.7628552,\n z: 0.2120342,\n ),\n ),\n translation: (\n x: 0.33317173,\n y: 1.0795953,\n z: -1.0053402,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.64188236,\n y: -1.0405006,\n z: 0.15076171,\n ),\n y_axis: (\n x: 0.21277487,\n y: 0.2903585,\n z: 1.1992631,\n ),\n z_axis: (\n x: -1.0558337,\n y: -0.5740472,\n z: 0.33333287,\n ),\n ),\n translation: (\n x: -1.5050399,\n y: -0.54391706,\n z: -1.0098355,\n ),\n )),\n },\n ),\n 195: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 54,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.08479953,\n y: 1.4094404,\n z: -0.07159948,\n ),\n rotation: (\n x: 0.7590683,\n y: -0.4684133,\n z: -0.3810325,\n w: 0.24334829,\n ),\n scale: (\n x: 1.0114408,\n y: 0.9775049,\n z: 1.0114408,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11873700034589242573,\n name: \"DEF-cheek.T.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 59,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.08479953,\n y: 1.4094404,\n z: -0.07159948,\n ),\n rotation: (\n x: 0.7590683,\n y: -0.4684133,\n z: -0.3810325,\n w: 0.24334829,\n ),\n scale: (\n x: 1.0114408,\n y: 0.9775049,\n z: 1.0114408,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.22025727,\n y: -0.7292088,\n z: -0.2850623,\n ),\n y_axis: (\n x: -0.41320106,\n y: -0.3480162,\n z: 0.57098407,\n ),\n z_axis: (\n x: -0.6559042,\n y: -0.010146045,\n z: -0.48083872,\n ),\n ),\n translation: (\n x: 0.41830325,\n y: 1.1333853,\n z: -1.0533314,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.33295652,\n y: -0.6687473,\n z: -0.99151206,\n ),\n y_axis: (\n x: -1.1023246,\n y: -0.5632488,\n z: -0.015337575,\n ),\n z_axis: (\n x: -0.43092066,\n y: 0.92411214,\n z: -0.72687066,\n ),\n ),\n translation: (\n x: 0.6561794,\n y: 1.8915133,\n z: -0.33349955,\n ),\n )),\n },\n ),\n 196: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 55,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.08480039,\n y: 1.4094404,\n z: -0.07159948,\n ),\n rotation: (\n x: 0.7590681,\n y: 0.46841165,\n z: 0.381034,\n w: 0.24334995,\n ),\n scale: (\n x: 1.0114425,\n y: 0.977501,\n z: 1.0114428,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 570496060658288973,\n name: \"DEF-cheek.T.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 60,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.08480039,\n y: 1.4094404,\n z: -0.07159948,\n ),\n rotation: (\n x: 0.7590681,\n y: 0.46841165,\n z: 0.381034,\n w: 0.24334995,\n ),\n scale: (\n x: 1.0114425,\n y: 0.977501,\n z: 1.0114428,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.22025836,\n y: 0.72920954,\n z: 0.28506386,\n ),\n y_axis: (\n x: 0.41319576,\n y: -0.34801602,\n z: 0.5709838,\n ),\n z_axis: (\n x: 0.6559078,\n y: -0.010147907,\n z: -0.48083657,\n ),\n ),\n translation: (\n x: 0.28192142,\n y: 1.1333853,\n z: -1.0533314,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.3329569,\n y: 0.66874385,\n z: 0.9915133,\n ),\n y_axis: (\n x: 1.1023215,\n y: -0.56325275,\n z: -0.015340339,\n ),\n z_axis: (\n x: 0.43092144,\n y: 0.9241189,\n z: -0.7268644,\n ),\n ),\n translation: (\n x: -0.88931954,\n y: 1.4232526,\n z: -1.0277714,\n ),\n )),\n },\n ),\n 197: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 62,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000032782555,\n y: 1.4213384,\n z: -0.009037375,\n ),\n rotation: (\n x: 0.9973641,\n y: -0.0000048648044,\n z: 0.00000009265708,\n w: -0.07255939,\n ),\n scale: (\n x: 0.99999607,\n y: 1.0000075,\n z: 0.9999868,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1346561564114057024,\n name: \"DEF-nose\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 67,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000032782555,\n y: 1.4213384,\n z: -0.009037375,\n ),\n rotation: (\n x: 0.9973641,\n y: -0.0000048648044,\n z: 0.00000009265708,\n w: -0.07255939,\n ),\n scale: (\n x: 0.99999607,\n y: 1.0000075,\n z: 0.9999868,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.8041353,\n y: -0.000007814112,\n z: -0.00000041907413,\n ),\n y_axis: (\n x: -0.000007792576,\n y: -0.7956772,\n z: -0.11638887,\n ),\n z_axis: (\n x: 0.0000007163173,\n y: 0.116386466,\n z: -0.7956607,\n ),\n ),\n translation: (\n x: 0.3501124,\n y: 1.1429529,\n z: -1.0030228,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2435719,\n y: -0.000012050714,\n z: 0.000001107784,\n ),\n y_axis: (\n x: -0.000012084295,\n y: -1.230463,\n z: 0.17999157,\n ),\n z_axis: (\n x: -0.00000064808586,\n y: -0.17998785,\n z: -1.2304887,\n ),\n ),\n translation: (\n x: -0.4353768,\n y: 1.2258337,\n z: -1.4399306,\n ),\n )),\n },\n ),\n 198: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 66,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.2853343,\n y: 0.7922379,\n z: 0.16886854,\n ),\n rotation: (\n x: 0.6732967,\n y: -0.26380607,\n z: 0.30552664,\n w: 0.6194606,\n ),\n scale: (\n x: 1.0,\n y: 1.0000013,\n z: 0.9999999,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17600805163160078026,\n name: \"DEF-thumb.01.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 199,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.2853343,\n y: 0.7922379,\n z: 0.16886854,\n ),\n rotation: (\n x: 0.6732967,\n y: -0.26380607,\n z: 0.30552664,\n w: 0.6194606,\n ),\n scale: (\n x: 1.0,\n y: 1.0000013,\n z: 0.9999999,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.5420855,\n y: 0.018723503,\n z: 0.59365934,\n ),\n y_axis: (\n x: -0.59004784,\n y: -0.07506637,\n z: 0.54115534,\n ),\n z_axis: (\n x: 0.06801825,\n y: -0.80040807,\n z: -0.03686508,\n ),\n ),\n translation: (\n x: 0.579561,\n y: 0.637069,\n z: -0.85996175,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.83831286,\n y: -0.91248196,\n z: 0.10518743,\n ),\n y_axis: (\n x: 0.02895506,\n y: -0.11608676,\n z: -1.2377982,\n ),\n z_axis: (\n x: 0.91806954,\n y: 0.8368719,\n z: -0.05701025,\n ),\n ),\n translation: (\n x: 0.2852049,\n y: 1.3224721,\n z: 0.67857367,\n ),\n )),\n },\n ),\n 199: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 66,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000004284084,\n y: 0.032225676,\n z: -0.000000055879354,\n ),\n rotation: (\n x: 0.22023416,\n y: 0.40398645,\n z: -0.3017118,\n w: 0.83502203,\n ),\n scale: (\n x: 1.0,\n y: 0.9999975,\n z: 0.9999995,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14581917137876132908,\n name: \"DEF-thumb.02.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 71,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000004284084,\n y: 0.032225676,\n z: -0.000000055879354,\n ),\n rotation: (\n x: 0.22023416,\n y: 0.40398645,\n z: -0.3017118,\n w: 0.83502203,\n ),\n scale: (\n x: 1.0,\n y: 0.9999975,\n z: 0.9999995,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.4038353,\n y: 0.6800547,\n z: 0.14519435,\n ),\n y_axis: (\n x: -0.047347117,\n y: -0.1406228,\n z: 0.7903289,\n ),\n z_axis: (\n x: 0.6937683,\n y: -0.4054493,\n z: -0.030580053,\n ),\n ),\n translation: (\n x: 0.5605462,\n y: 0.63465,\n z: -0.8425227,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.6245138,\n y: -0.07321894,\n z: 1.0728834,\n ),\n y_axis: (\n x: 1.0516765,\n y: -0.21746835,\n z: -0.62701136,\n ),\n z_axis: (\n x: 0.22453767,\n y: 1.2222153,\n z: -0.047289364,\n ),\n ),\n translation: (\n x: -0.8283372,\n y: 1.208803,\n z: -0.24331033,\n ),\n )),\n },\n ),\n 200: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.11189699,\n y: 1.183586,\n z: -0.14422429,\n ),\n rotation: (\n x: -0.013988186,\n y: 0.08882578,\n z: 0.9793839,\n w: -0.18089052,\n ),\n scale: (\n x: 1.0121922,\n y: 0.9760548,\n z: 1.0121922,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17367705777053090335,\n name: \"DEF-upper_arm.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 201,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.11189699,\n y: 1.183586,\n z: -0.14422429,\n ),\n rotation: (\n x: -0.013988186,\n y: 0.08882578,\n z: 0.9793839,\n w: -0.18089052,\n ),\n scale: (\n x: 1.0121922,\n y: 0.9760548,\n z: 1.0121922,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.7603574,\n y: -0.29042092,\n z: 0.0038547318,\n ),\n y_axis: (\n x: 0.27615133,\n y: -0.72113264,\n z: 0.14053313,\n ),\n z_axis: (\n x: -0.04845815,\n y: 0.13749807,\n z: 0.8007801,\n ),\n ),\n translation: (\n x: 0.44009334,\n y: 0.951767,\n z: -1.1117318,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.1477048,\n y: 0.4482675,\n z: -0.07314409,\n ),\n y_axis: (\n x: -0.43836945,\n y: -1.1705911,\n z: 0.2075434,\n ),\n z_axis: (\n x: 0.005818453,\n y: 0.22812283,\n z: 1.2087196,\n ),\n ),\n translation: (\n x: 0.9287914,\n y: 1.1704619,\n z: 1.1784292,\n ),\n )),\n },\n ),\n 201: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.00000007171184,\n y: 0.16913636,\n z: -0.00000017136335,\n ),\n rotation: (\n x: 0.000000044527845,\n y: -0.050663546,\n z: 0.00000031057297,\n w: 0.9987158,\n ),\n scale: (\n x: 1.0000005,\n y: 0.9999993,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14317134145244049012,\n name: \"DEF-upper_arm.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 202,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.00000007171184,\n y: 0.16913636,\n z: -0.00000017136335,\n ),\n rotation: (\n x: 0.000000044527845,\n y: -0.050663546,\n z: 0.00000031057297,\n w: 0.9987158,\n ),\n scale: (\n x: 1.0000005,\n y: 0.9999993,\n z: 1.0,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.761358,\n y: -0.27501622,\n z: 0.08487158,\n ),\n y_axis: (\n x: 0.27615163,\n y: -0.7211319,\n z: 0.14053309,\n ),\n z_axis: (\n x: 0.028736433,\n y: 0.166182,\n z: 0.7962792,\n ),\n ),\n translation: (\n x: 0.48680067,\n y: 0.8297973,\n z: -1.0879626,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.1492141,\n y: 0.44826853,\n z: 0.043375563,\n ),\n y_axis: (\n x: -0.41511688,\n y: -1.1705917,\n z: 0.25083977,\n ),\n z_axis: (\n x: 0.12810741,\n y: 0.22812304,\n z: 1.2019258,\n ),\n ),\n translation: (\n x: 1.0432771,\n y: 1.0013258,\n z: 1.0783889,\n ),\n )),\n },\n ),\n 202: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000014901161,\n y: 0.16913645,\n z: -0.00000006891787,\n ),\n rotation: (\n x: 0.44678867,\n y: -0.050217733,\n z: 0.025021713,\n w: 0.8928784,\n ),\n scale: (\n x: 1.003839,\n y: 0.96975994,\n z: 1.0277617,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16755445813566473714,\n name: \"DEF-forearm.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 203,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000014901161,\n y: 0.16913645,\n z: -0.00000006891787,\n ),\n rotation: (\n x: 0.44678867,\n y: -0.050217733,\n z: 0.025021713,\n w: 0.8928784,\n ),\n scale: (\n x: 1.003839,\n y: 0.96975994,\n z: 1.0277617,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.75629026,\n y: -0.25550613,\n z: 0.17418812,\n ),\n y_axis: (\n x: 0.24883512,\n y: -0.2671911,\n z: 0.6884955,\n ),\n z_axis: (\n x: -0.15688933,\n y: 0.713968,\n z: 0.3660524,\n ),\n ),\n translation: (\n x: 0.53350794,\n y: 0.70782757,\n z: -1.0641934,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.1328558,\n y: 0.41882327,\n z: -0.24867463,\n ),\n y_axis: (\n x: -0.38270786,\n y: -0.47960204,\n z: 1.084181,\n ),\n z_axis: (\n x: 0.260914,\n y: 1.114948,\n z: 0.51062423,\n ),\n ),\n translation: (\n x: 1.1529417,\n y: 1.3025503,\n z: -0.0913403,\n ),\n )),\n },\n ),\n 203: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000029802322,\n y: 0.12935503,\n z: -0.00000010430813,\n ),\n rotation: (\n x: -0.00000090836517,\n y: 0.27765375,\n z: 0.0000010528128,\n w: 0.9606812,\n ),\n scale: (\n x: 1.0000011,\n y: 0.9999973,\n z: 1.0000013,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1091823564551632899,\n name: \"DEF-forearm.L.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 204,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000029802322,\n y: 0.12935503,\n z: -0.00000010430813,\n ),\n rotation: (\n x: -0.00000090836517,\n y: 0.27765375,\n z: 0.0000010528128,\n w: 0.9606812,\n ),\n scale: (\n x: 1.0000011,\n y: 0.9999973,\n z: 1.0000013,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.5559868,\n y: -0.59699535,\n z: -0.047946997,\n ),\n y_axis: (\n x: 0.24883656,\n y: -0.2671906,\n z: 0.6884927,\n ),\n z_axis: (\n x: -0.5361605,\n y: 0.46758035,\n z: 0.40254015,\n ),\n ),\n translation: (\n x: 0.5656961,\n y: 0.67326504,\n z: -0.97513306,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.82552564,\n y: 0.41882765,\n z: -0.81467956,\n ),\n y_axis: (\n x: -0.9020824,\n y: -0.47960365,\n z: 0.7128518,\n ),\n z_axis: (\n x: -0.051717278,\n y: 1.1149498,\n z: 0.5710872,\n ),\n ),\n translation: (\n x: 1.0239059,\n y: 1.1731956,\n z: 0.5378089,\n ),\n )),\n },\n ),\n 204: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000059604645,\n y: 0.12935491,\n z: -0.000000059604645,\n ),\n rotation: (\n x: 0.15585244,\n y: 0.2761444,\n z: 0.1493344,\n w: 0.93656313,\n ),\n scale: (\n x: 0.99059665,\n y: 1.0240184,\n z: 0.986339,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 2198449108074178016,\n name: \"DEF-hand.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 205,\n 74,\n 207,\n 76,\n 209,\n 78,\n 211,\n 80,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000059604645,\n y: 0.12935491,\n z: -0.000000059604645,\n ),\n rotation: (\n x: 0.15585244,\n y: 0.2761444,\n z: 0.1493344,\n w: 0.93656313,\n ),\n scale: (\n x: 0.99059665,\n y: 1.0240184,\n z: 0.986339,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.102028795,\n y: -0.78965414,\n z: 0.02365089,\n ),\n y_axis: (\n x: 0.13575648,\n y: 0.049540076,\n z: 0.8031751,\n ),\n z_axis: (\n x: -0.7830838,\n y: 0.0916621,\n z: 0.14829758,\n ),\n ),\n translation: (\n x: 0.5978844,\n y: 0.6387026,\n z: -0.8860732,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.12732106,\n y: 0.22913642,\n z: -1.2206904,\n ),\n y_axis: (\n x: -1.2469783,\n y: 0.0065126424,\n z: 0.16359912,\n ),\n z_axis: (\n x: 0.098434396,\n y: 1.205927,\n z: 0.19623606,\n ),\n ),\n translation: (\n x: 0.9597916,\n y: 0.9273829,\n z: 0.7992201,\n ),\n )),\n },\n ),\n 205: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0011457577,\n y: 0.09997988,\n z: 0.03306835,\n ),\n rotation: (\n x: 0.11342043,\n y: 0.733894,\n z: -0.14063096,\n w: 0.6547964,\n ),\n scale: (\n x: 0.9999997,\n y: 1.0000019,\n z: 0.99999976,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6636294474717971420,\n name: \"DEF-f_index.01.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 206,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.0011457577,\n y: 0.09997988,\n z: 0.03306835,\n ),\n rotation: (\n x: 0.11342043,\n y: 0.733894,\n z: -0.14063096,\n w: 0.6547964,\n ),\n scale: (\n x: 0.9999997,\n y: 1.0000019,\n z: 0.99999976,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7871149,\n y: 0.00029874413,\n z: -0.16423115,\n ),\n y_axis: (\n x: 0.13644452,\n y: -0.2358894,\n z: 0.75045264,\n ),\n z_axis: (\n x: -0.062390063,\n y: -0.7607665,\n z: -0.27837542,\n ),\n ),\n translation: (\n x: 0.5854451,\n y: 0.645782,\n z: -0.8008408,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2229612,\n y: 0.24018848,\n z: -0.07399454,\n ),\n y_axis: (\n x: -0.016978895,\n y: -0.44062957,\n z: -1.1778452,\n ),\n z_axis: (\n x: -0.22769126,\n y: 1.150356,\n z: -0.35677812,\n ),\n ),\n translation: (\n x: -0.8873564,\n y: 1.0651855,\n z: 0.51822853,\n ),\n )),\n },\n ),\n 206: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000012805685,\n y: 0.04212822,\n z: -0.000000014901161,\n ),\n rotation: (\n x: 0.34092674,\n y: 0.002661585,\n z: -0.003895428,\n w: 0.940078,\n ),\n scale: (\n x: 0.9999998,\n y: 0.99999535,\n z: 0.9999988,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8472209496582293702,\n name: \"DEF-f_index.02.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 73,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000012805685,\n y: 0.04212822,\n z: -0.000000014901161,\n ),\n rotation: (\n x: 0.34092674,\n y: 0.002661585,\n z: -0.003895428,\n w: 0.940078,\n ),\n scale: (\n x: 0.9999998,\n y: 0.99999535,\n z: 0.9999988,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.786806,\n y: 0.0074259927,\n z: -0.16622575,\n ),\n y_axis: (\n x: 0.071924694,\n y: -0.6686733,\n z: 0.3960436,\n ),\n z_axis: (\n x: -0.13350062,\n y: -0.43269634,\n z: -0.69509673,\n ),\n ),\n translation: (\n x: 0.59119326,\n y: 0.63584435,\n z: -0.7692256,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2221507,\n y: 0.148095,\n z: -0.20788592,\n ),\n y_axis: (\n x: -0.005527972,\n y: -1.0933157,\n z: -0.6216139,\n ),\n z_axis: (\n x: -0.2312857,\n y: 0.6521437,\n z: -1.0117687,\n ),\n ),\n translation: (\n x: -0.8969232,\n y: 1.1092715,\n z: -0.26012796,\n ),\n )),\n },\n ),\n 207: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0031145476,\n y: 0.10229103,\n z: 0.005881183,\n ),\n rotation: (\n x: 0.119379446,\n y: 0.712318,\n z: -0.122891776,\n w: 0.6806242,\n ),\n scale: (\n x: 0.9999993,\n y: 0.9999999,\n z: 1.0000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14078320093932418572,\n name: \"DEF-f_middle.01.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 208,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0031145476,\n y: 0.10229103,\n z: 0.005881183,\n ),\n rotation: (\n x: 0.119379446,\n y: 0.712318,\n z: -0.122891776,\n w: 0.6806242,\n ),\n scale: (\n x: 0.9999993,\n y: 0.9999999,\n z: 1.0000001,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7872564,\n y: -0.055897474,\n z: -0.14697328,\n ),\n y_axis: (\n x: 0.10321035,\n y: -0.22091703,\n z: 0.7621371,\n ),\n z_axis: (\n x: -0.10786153,\n y: -0.7632045,\n z: -0.25531867,\n ),\n ),\n translation: (\n x: 0.6074834,\n y: 0.6467686,\n z: -0.8031171,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2258176,\n y: 0.18807684,\n z: -0.14422017,\n ),\n y_axis: (\n x: -0.107302375,\n y: -0.41660503,\n z: -1.1818155,\n ),\n z_axis: (\n x: -0.19710626,\n y: 1.1658709,\n z: -0.3230366,\n ),\n ),\n translation: (\n x: -0.8335633,\n y: 1.0915244,\n z: 0.59253633,\n ),\n )),\n },\n ),\n 208: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 2,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000078231096,\n y: 0.04081299,\n z: 0.00000011175871,\n ),\n rotation: (\n x: 0.3924052,\n y: -0.0037930228,\n z: -0.0075232885,\n w: 0.91975385,\n ),\n scale: (\n x: 0.9999997,\n y: 0.99999744,\n z: 0.9999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12223042379147751874,\n name: \"DEF-f_middle.02.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 75,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000078231096,\n y: 0.04081299,\n z: 0.00000011175871,\n ),\n rotation: (\n x: 0.3924052,\n y: -0.0037930228,\n z: -0.0075232885,\n w: 0.91975385,\n ),\n scale: (\n x: 0.9999997,\n y: 0.99999744,\n z: 0.9999994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.78529304,\n y: -0.052993443,\n z: -0.16004235,\n ),\n y_axis: (\n x: 0.0021010346,\n y: -0.7044123,\n z: 0.34143105,\n ),\n z_axis: (\n x: -0.15927672,\n y: -0.36797062,\n z: -0.72488046,\n ),\n ),\n translation: (\n x: 0.6116956,\n y: 0.63775223,\n z: -0.772012,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2223265,\n y: 0.03933908,\n z: -0.2513413,\n ),\n y_axis: (\n x: -0.10154948,\n y: -1.1425672,\n z: -0.5157481,\n ),\n z_axis: (\n x: -0.2170302,\n y: 0.57135683,\n z: -1.0625021,\n ),\n ),\n translation: (\n x: -0.85047823,\n y: 1.1457056,\n z: -0.33760053,\n ),\n )),\n },\n ),\n 209: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 4,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.0054815486,\n y: 0.101212144,\n z: -0.02157735,\n ),\n rotation: (\n x: 0.18912475,\n y: 0.68433076,\n z: -0.13977852,\n w: 0.6902067,\n ),\n scale: (\n x: 0.99999976,\n y: 1.0000012,\n z: 0.9999998,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18092258693623441567,\n name: \"DEF-f_ring.01.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 210,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.0054815486,\n y: 0.101212144,\n z: -0.02157735,\n ),\n rotation: (\n x: 0.18912475,\n y: 0.68433076,\n z: -0.13977852,\n w: 0.6902067,\n ),\n scale: (\n x: 0.99999976,\n y: 1.0000012,\n z: 0.9999998,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7876155,\n y: -0.107365124,\n z: -0.0944307,\n ),\n y_axis: (\n x: 0.02001494,\n y: -0.30631128,\n z: 0.7353657,\n ),\n z_axis: (\n x: -0.14601657,\n y: -0.7273624,\n z: -0.3434577,\n ),\n ),\n translation: (\n x: 0.6290808,\n y: 0.6460674,\n z: -0.8081116,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2296805,\n y: 0.061111026,\n z: -0.20724715,\n ),\n y_axis: (\n x: -0.19307591,\n y: -0.5461789,\n z: -1.1163206,\n ),\n z_axis: (\n x: -0.11389341,\n y: 1.1306975,\n z: -0.45935452,\n ),\n ),\n translation: (\n x: -0.7408669,\n y: 1.2281544,\n z: 0.48038384,\n ),\n )),\n },\n ),\n 210: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 4,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000067055225,\n y: 0.04093422,\n z: 0.0,\n ),\n rotation: (\n x: 0.37381095,\n y: -0.0077559073,\n z: -0.010859124,\n w: 0.9274089,\n ),\n scale: (\n x: 0.99999994,\n y: 0.9999996,\n z: 0.9999993,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12851436067301410092,\n name: \"DEF-f_ring.02.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 77,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000067055225,\n y: 0.04093422,\n z: 0.0,\n ),\n rotation: (\n x: 0.37381095,\n y: -0.0077559073,\n z: -0.010859124,\n w: 0.9274089,\n ),\n scale: (\n x: 0.99999994,\n y: 0.9999996,\n z: 0.9999993,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7859008,\n y: -0.1039397,\n z: -0.115625195,\n ),\n y_axis: (\n x: -0.0755517,\n y: -0.72661406,\n z: 0.29013082,\n ),\n z_axis: (\n x: -0.13679059,\n y: -0.30925348,\n z: -0.7550477,\n ),\n ),\n translation: (\n x: 0.6299,\n y: 0.6335287,\n z: -0.77801,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2263583,\n y: -0.082074426,\n z: -0.21933745,\n ),\n y_axis: (\n x: -0.18583542,\n y: -1.1703703,\n z: -0.42126244,\n ),\n z_axis: (\n x: -0.14606231,\n y: 0.4942312,\n z: -1.1121415,\n ),\n ),\n translation: (\n x: -0.76838887,\n y: 1.1776787,\n z: -0.46021467,\n ),\n )),\n },\n ),\n 211: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 6,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.004802931,\n y: 0.093217745,\n z: -0.04302893,\n ),\n rotation: (\n x: 0.16402298,\n y: 0.6709288,\n z: -0.10720761,\n w: 0.7151627,\n ),\n scale: (\n x: 0.9999998,\n y: 1.0000008,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15361820369743496685,\n name: \"DEF-f_pinky.01.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 212,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.004802931,\n y: 0.093217745,\n z: -0.04302893,\n ),\n rotation: (\n x: 0.16402298,\n y: 0.6709288,\n z: -0.10720761,\n w: 0.7151627,\n ),\n scale: (\n x: 0.9999998,\n y: 1.0000008,\n z: 1.0,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7802581,\n y: -0.14846388,\n z: -0.09209927,\n ),\n y_axis: (\n x: 0.016165886,\n y: -0.24083252,\n z: 0.7637867,\n ),\n z_axis: (\n x: -0.18164742,\n y: -0.74455905,\n z: -0.27530065,\n ),\n ),\n translation: (\n x: 0.6447246,\n y: 0.6431691,\n z: -0.8176977,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2198889,\n y: 0.05321746,\n z: -0.26045743,\n ),\n y_axis: (\n x: -0.25798717,\n y: -0.44480878,\n z: -1.1477582,\n ),\n z_axis: (\n x: -0.107166424,\n y: 1.1678853,\n z: -0.35639134,\n ),\n ),\n translation: (\n x: -0.70819277,\n y: 1.2067538,\n z: 0.61470556,\n ),\n )),\n },\n ),\n 212: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 68,\n 0,\n 0,\n 0,\n 0,\n 6,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000008195639,\n y: 0.037450995,\n z: 0.0,\n ),\n rotation: (\n x: 0.42144144,\n y: -0.018712418,\n z: -0.008962603,\n w: 0.9066182,\n ),\n scale: (\n x: 0.9999997,\n y: 1.0000027,\n z: 0.99999905,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8042087796962122077,\n name: \"DEF-f_pinky.02.L\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 79,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000008195639,\n y: 0.037450995,\n z: 0.0,\n ),\n rotation: (\n x: 0.42144144,\n y: -0.018712418,\n z: -0.008962603,\n w: 0.9066182,\n ),\n scale: (\n x: 0.9999997,\n y: 1.0000027,\n z: 0.99999905,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.7742773,\n y: -0.16026181,\n z: -0.12374045,\n ),\n y_axis: (\n x: -0.12807685,\n y: -0.7245386,\n z: 0.28183427,\n ),\n z_axis: (\n x: -0.16171086,\n y: -0.28943506,\n z: -0.7569015,\n ),\n ),\n translation: (\n x: 0.6453301,\n y: 0.63414973,\n z: -0.78909314,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 1.2102653,\n y: -0.16423239,\n z: -0.25901005,\n ),\n y_axis: (\n x: -0.27379352,\n y: -1.1643211,\n z: -0.38877746,\n ),\n z_axis: (\n x: -0.15387416,\n y: 0.4803181,\n z: -1.1171724,\n ),\n ),\n translation: (\n x: -0.72881556,\n y: 1.2233537,\n z: -0.46786296,\n ),\n )),\n },\n ),\n 213: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 69,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.28533477,\n y: 0.7922376,\n z: 0.16886854,\n ),\n rotation: (\n x: 0.67329556,\n y: 0.2638069,\n z: -0.30552667,\n w: 0.6194615,\n ),\n scale: (\n x: 0.9999999,\n y: 1.0000025,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11690182129226110435,\n name: \"DEF-thumb.01.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 214,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.28533477,\n y: 0.7922376,\n z: 0.16886854,\n ),\n rotation: (\n x: 0.67329556,\n y: 0.2638069,\n z: -0.30552667,\n w: 0.6194615,\n ),\n scale: (\n x: 0.9999999,\n y: 1.0000025,\n z: 0.99999994,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.5420848,\n y: -0.018723525,\n z: -0.59366,\n ),\n y_axis: (\n x: 0.5900494,\n y: -0.07506406,\n z: 0.54115534,\n ),\n z_axis: (\n x: -0.0680165,\n y: -0.8004084,\n z: -0.03686326,\n ),\n ),\n translation: (\n x: 0.120664015,\n y: 0.63706875,\n z: -0.85996175,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.83831173,\n y: 0.9124823,\n z: -0.10518478,\n ),\n y_axis: (\n x: -0.028955163,\n y: -0.116082765,\n z: -1.2377983,\n ),\n z_axis: (\n x: -0.9180706,\n y: 0.8368701,\n z: -0.057007585,\n ),\n ),\n translation: (\n x: -0.87221324,\n y: 0.6835252,\n z: 0.75223035,\n ),\n )),\n },\n ),\n 214: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 69,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.00000010617077,\n y: 0.03222546,\n z: -0.00000005122274,\n ),\n rotation: (\n x: 0.22023605,\n y: -0.4039867,\n z: 0.30171227,\n w: 0.8350214,\n ),\n scale: (\n x: 1.0,\n y: 0.99999696,\n z: 0.9999993,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14303883096636211701,\n name: \"DEF-thumb.02.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 81,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.00000010617077,\n y: 0.03222546,\n z: -0.00000005122274,\n ),\n rotation: (\n x: 0.22023605,\n y: -0.4039867,\n z: 0.30171227,\n w: 0.8350214,\n ),\n scale: (\n x: 1.0,\n y: 0.99999696,\n z: 0.9999993,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: 0.40383554,\n y: -0.6800551,\n z: -0.14519328,\n ),\n y_axis: (\n x: 0.04734634,\n y: -0.14062274,\n z: 0.7903291,\n ),\n z_axis: (\n x: -0.6937687,\n y: -0.4054489,\n z: -0.030581344,\n ),\n ),\n translation: (\n x: 0.13967869,\n y: 0.63464975,\n z: -0.8425228,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: 0.6245134,\n y: 0.073216245,\n z: -1.0728831,\n ),\n y_axis: (\n x: -1.0516766,\n y: -0.21746792,\n z: -0.6270112,\n ),\n z_axis: (\n x: -0.22453693,\n y: 1.2222155,\n z: -0.047290333,\n ),\n ),\n translation: (\n x: 0.3910376,\n y: 1.1575336,\n z: 0.5079482,\n ),\n )),\n },\n ),\n 215: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.11189774,\n y: 1.183586,\n z: -0.14422476,\n ),\n rotation: (\n x: 0.013988443,\n y: 0.088826545,\n z: 0.9793839,\n w: 0.18089041,\n ),\n scale: (\n x: 1.0121914,\n y: 0.9760558,\n z: 1.0121914,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17158523888283496352,\n name: \"DEF-upper_arm.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 216,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.11189774,\n y: 1.183586,\n z: -0.14422476,\n ),\n rotation: (\n x: 0.013988443,\n y: 0.088826545,\n z: 0.9793839,\n w: 0.18089041,\n ),\n scale: (\n x: 1.0121914,\n y: 0.9760558,\n z: 1.0121914,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.76035696,\n y: 0.29042056,\n z: -0.0038545285,\n ),\n y_axis: (\n x: -0.27615142,\n y: -0.7211334,\n z: 0.14053452,\n ),\n z_axis: (\n x: 0.048458733,\n y: 0.1374991,\n z: 0.8007793,\n ),\n ),\n translation: (\n x: 0.26013142,\n y: 0.951767,\n z: -1.1117321,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.1477056,\n y: -0.44826645,\n z: 0.07314506,\n ),\n y_axis: (\n x: 0.43836948,\n y: -1.1705893,\n z: 0.20754524,\n ),\n z_axis: (\n x: -0.0058181384,\n y: 0.22812453,\n z: 1.2087202,\n ),\n ),\n translation: (\n x: -0.12513956,\n y: 1.4843498,\n z: 1.1272111,\n ),\n )),\n },\n ),\n 216: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000052619725,\n y: 0.16913661,\n z: 0.000000056810677,\n ),\n rotation: (\n x: -0.00000081945234,\n y: 0.05066349,\n z: 0.000000047995712,\n w: 0.9987158,\n ),\n scale: (\n x: 1.0000006,\n y: 0.9999986,\n z: 1.0000008,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9184370608981720205,\n name: \"DEF-upper_arm.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 217,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000052619725,\n y: 0.16913661,\n z: 0.000000056810677,\n ),\n rotation: (\n x: -0.00000081945234,\n y: 0.05066349,\n z: 0.000000047995712,\n w: 0.9987158,\n ),\n scale: (\n x: 1.0000006,\n y: 0.9999986,\n z: 1.0000008,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.7613579,\n y: 0.27501535,\n z: -0.084871136,\n ),\n y_axis: (\n x: -0.27615097,\n y: -0.7211327,\n z: 0.14053303,\n ),\n z_axis: (\n x: -0.028736241,\n y: 0.16618182,\n z: 0.7962793,\n ),\n ),\n translation: (\n x: 0.21342406,\n y: 0.82979697,\n z: -1.0879625,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.1492155,\n y: -0.4482671,\n z: -0.043375336,\n ),\n y_axis: (\n x: 0.41511598,\n y: -1.1705917,\n z: 0.2508393,\n ),\n z_axis: (\n x: -0.12810688,\n y: 0.22812289,\n z: 1.2019259,\n ),\n ),\n translation: (\n x: -0.23856723,\n y: 1.3152137,\n z: 1.108762,\n ),\n )),\n },\n ),\n 217: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.000000014901161,\n y: 0.16913626,\n z: -0.0000000009313226,\n ),\n rotation: (\n x: 0.44678885,\n y: 0.05021789,\n z: -0.025022225,\n w: 0.89287823,\n ),\n scale: (\n x: 1.0038396,\n y: 0.96975994,\n z: 1.0277618,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5444827132708999604,\n name: \"DEF-forearm.R\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 218,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: 0.000000014901161,\n y: 0.16913626,\n z: -0.0000000009313226,\n ),\n rotation: (\n x: 0.44678885,\n y: 0.05021789,\n z: -0.025022225,\n w: 0.89287823,\n ),\n scale: (\n x: 1.0038396,\n y: 0.96975994,\n z: 1.0277618,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.7562902,\n y: 0.25550577,\n z: -0.17418848,\n ),\n y_axis: (\n x: -0.24883534,\n y: -0.26719126,\n z: 0.6884956,\n ),\n z_axis: (\n x: 0.15688919,\n y: 0.7139686,\n z: 0.36605227,\n ),\n ),\n translation: (\n x: 0.16671689,\n y: 0.7078273,\n z: -1.0641932,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -1.1328558,\n y: -0.41882333,\n z: 0.24867375,\n ),\n y_axis: (\n x: 0.3827075,\n y: -0.47960135,\n z: 1.0841804,\n ),\n z_axis: (\n x: -0.26091444,\n y: 1.1149477,\n z: 0.51062393,\n ),\n ),\n translation: (\n x: -0.35968804,\n y: 1.5958196,\n z: -0.26546806,\n ),\n )),\n },\n ),\n 218: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 71,\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -0.000000044703484,\n y: 0.12935513,\n z: -0.00000010430813,\n ),\n rotation: (\n x: 0.0000000940357,\n y: -0.27765396,\n z: 0.00000008821916,\n w: 0.9606812,\n ),\n scale: (\n x: 1.0000002,\n y: 0.99999803,\n z: 1.0000007,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7437606312356086908,\n name: \"DEF-forearm.R.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 132,\n ]),\n \"studio::anim::SkeletalJoint\": (Rgba(\n red: 0.0,\n green: 0.0,\n blue: 0.0,\n alpha: 1.0,\n )),\n \"studio::anim::BindPoseLocal\": ((\n translation: (\n x: -0.000000044703484,\n y: 0.12935513,\n z: -0.00000010430813,\n ),\n rotation: (\n x: 0.0000000940357,\n y: -0.27765396,\n z: 0.00000008821916,\n w: 0.9606812,\n ),\n scale: (\n x: 1.0000002,\n y: 0.99999803,\n z: 1.0000007,\n ),\n )),\n \"studio::anim::BindPoseGlobal\": ((\n matrix3: (\n x_axis: (\n x: -0.5559865,\n y: 0.5969947,\n z: 0.047947913,\n ),\n y_axis: (\n x: -0.24883464,\n y: -0.2671907,\n z: 0.68849427,\n ),\n z_axis: (\n x: 0.53616095,\n y: 0.46758115,\n z: 0.40253815,\n ),\n ),\n translation: (\n x: 0.13452879,\n y: 0.6732646,\n z: -0.9751329,\n ),\n )),\n \"studio::anim::InvBindPose\": ((\n matrix3: (\n x_axis: (\n x: -0.82552713,\n y: -0.41882393,\n z: 0.814681,\n ),\n y_axis: (\n x: 0.902082,\n y: -0.47960225,\n z: 0.71285284,\n ),\n z_axis: (\n x: 0.051718924,\n y: 1.1149502,\n z: 0.5710846,\n ),\n ),\n translation: (\n x: -0.44584993,\n y: 1.4664677,\n z: -0.032653272,\n ),\n )),\n },\n ),\n 219: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15669080189857868856,\n name: \"Room.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 220: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 0,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12129191998988526,\n name: \"Room.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 221: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 0,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14994647859182111261,\n name: \"Room.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 222: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 0,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 2305727545421748040,\n name: \"Room.3\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 223: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 1,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13233653607929491890,\n name: \"DeskChair\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 224: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 2,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13638365500142878701,\n name: \"Desk\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 225: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 3,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13429567360513571507,\n name: \"BookCase\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 226: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 4,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11575612437093019175,\n name: \"Turntable\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 227: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 5,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6234127825786918958,\n name: \"BoomBox\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 228: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 6,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10067850846471362618,\n name: \"Radio\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 229: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 7,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14847531744333314353,\n name: \"Monitor\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 230: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 8,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15248759462573312337,\n name: \"Mannequin\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 231: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 9,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6047989615790079100,\n name: \"Clock_Plain\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 232: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 10,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1705223073573951885,\n name: \"Baseboard_North\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 233: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 11,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16448957151321728339,\n name: \"Baseboard_East\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 234: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 12,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15635982943659836433,\n name: \"Notepad\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 235: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 13,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11901467750951413030,\n name: \"Vase\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 236: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 14,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16325639447001703091,\n name: \"Painting\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 237: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 15,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9874645199171359513,\n name: \"RecordPlayer\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 238: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 16,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16038708317184909401,\n name: \"Clock_Fancy\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 239: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 17,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10855439342359554842,\n name: \"Rug\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 240: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 18,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14475911846627277336,\n name: \"Couch\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 241: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 19,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9124158084727106006,\n name: \"Flowers.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 242: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 19,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17851818263951859191,\n name: \"Flowers.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 243: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 20,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16222089751857211207,\n name: \"PottedPlant.001.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 244: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 20,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14225900030123404751,\n name: \"PottedPlant.001.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 245: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 20,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 127340627444095358,\n name: \"PottedPlant.001.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 246: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 20,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5033089025780570140,\n name: \"PottedPlant.001.3\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 247: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 20,\n 4,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1136959683339504084,\n name: \"PottedPlant.001.4\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 248: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 21,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8924537217623507871,\n name: \"PottedPlant.003.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 249: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 21,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1441078585197031827,\n name: \"PottedPlant.003.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 250: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 22,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1489012337981181736,\n name: \"WindowFrame\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 251: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 23,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9645133002790414131,\n name: \"WickerBasket\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 252: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 24,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15390124259403968010,\n name: \"DeskLamp\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 253: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 25,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1561803185303684793,\n name: \"PottedPlant.002\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 254: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 26,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15443276149788489367,\n name: \"Cabinet\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 255: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 27,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5821398879068258117,\n name: \"SoundDamping\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 256: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 28,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9249022766590542002,\n name: \"WindowGlow\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 257: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 29,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10285417804828783084,\n name: \"Curtain\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 258: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 30,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9349836063829047564,\n name: \"KitsuneMask.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 259: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 30,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5102628233173599926,\n name: \"KitsuneMask.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 260: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 30,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11594468765968735609,\n name: \"KitsuneMask.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 261: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 31,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1975187030674379270,\n name: \"Outlet\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 262: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 32,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11568187364738202027,\n name: \"Outlet.001\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 263: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 33,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 2723353865056852313,\n name: \"PottedPlant.Hanging.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 264: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 33,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13619043177376799464,\n name: \"PottedPlant.Hanging.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 265: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 33,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6728519036374738377,\n name: \"PottedPlant.Hanging.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 266: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 33,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4369564035848967240,\n name: \"PottedPlant.Hanging.3\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 267: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 34,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 2073123188983842202,\n name: \"Candle.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 268: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 34,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7141189983638833440,\n name: \"Candle.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 269: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 34,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1073933321449523599,\n name: \"Candle.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 270: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 34,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11186396129909957138,\n name: \"Candle.3\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 271: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 35,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3943832149079662047,\n name: \"Books.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 272: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 35,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15752511784738708548,\n name: \"Books.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 273: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 35,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16259136821498015829,\n name: \"Books.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 274: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 36,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18417166895556635729,\n name: \"MonitorStand\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 275: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17709677314688924048,\n name: \"Keyboard.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 276: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1418113097355009680,\n name: \"Keyboard.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 277: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12187221758989948446,\n name: \"Keyboard.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 278: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11377449108289725627,\n name: \"Keyboard.3\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 279: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 4,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9460611586308757795,\n name: \"Keyboard.4\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 280: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 5,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7605030600669986838,\n name: \"Keyboard.5\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 281: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 6,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14241548436871385862,\n name: \"Keyboard.6\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 282: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 7,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5916438948237801655,\n name: \"Keyboard.7\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 283: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 8,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 2163749061282495612,\n name: \"Keyboard.8\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 284: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 9,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10117041960069135728,\n name: \"Keyboard.9\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 285: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 10,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13128638554732962394,\n name: \"Keyboard.10\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 286: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 11,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15465115911448252021,\n name: \"Keyboard.11\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 287: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 12,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10048334224685188738,\n name: \"Keyboard.12\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 288: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 13,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16049760689340360703,\n name: \"Keyboard.13\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 289: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 14,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3257260382324782944,\n name: \"Keyboard.14\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 290: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 15,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11024016938969314631,\n name: \"Keyboard.15\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 291: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 16,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4583828939832116966,\n name: \"Keyboard.16\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 292: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 17,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5548018523736449130,\n name: \"Keyboard.17\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 293: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 18,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1782740052301684414,\n name: \"Keyboard.18\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 294: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 19,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8209929518457299945,\n name: \"Keyboard.19\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 295: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 20,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7684295081661022639,\n name: \"Keyboard.20\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 296: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 21,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7521908875287560171,\n name: \"Keyboard.21\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 297: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 22,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16043859253794122000,\n name: \"Keyboard.22\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 298: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 23,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7432651663802729993,\n name: \"Keyboard.23\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 299: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 24,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7471188895436734492,\n name: \"Keyboard.24\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 300: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 25,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7480433064510727556,\n name: \"Keyboard.25\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 301: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 26,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16779128550273836206,\n name: \"Keyboard.26\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 302: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 27,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17438903268598540125,\n name: \"Keyboard.27\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 303: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 28,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15640547847357541502,\n name: \"Keyboard.28\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 304: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 29,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10047926315702729472,\n name: \"Keyboard.29\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 305: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 30,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7915787714783793614,\n name: \"Keyboard.30\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 306: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 31,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8001164766129023511,\n name: \"Keyboard.31\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 307: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 32,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4372864228059773880,\n name: \"Keyboard.32\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 308: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 33,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8943663465810351732,\n name: \"Keyboard.33\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 309: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 34,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12329839803904548985,\n name: \"Keyboard.34\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 310: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 35,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9197090962214664795,\n name: \"Keyboard.35\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 311: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 36,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1320024986807220595,\n name: \"Keyboard.36\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 312: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 37,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14153202395861489604,\n name: \"Keyboard.37\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 313: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 38,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3679724942888129556,\n name: \"Keyboard.38\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 314: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 39,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4751230661974600615,\n name: \"Keyboard.39\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 315: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 40,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10773702055308135461,\n name: \"Keyboard.40\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 316: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 41,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15046501733984424577,\n name: \"Keyboard.41\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 317: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 42,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17739634198515394079,\n name: \"Keyboard.42\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 318: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 43,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6490610633878437841,\n name: \"Keyboard.43\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 319: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 44,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16364865887860204523,\n name: \"Keyboard.44\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 320: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 45,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 331156763138875162,\n name: \"Keyboard.45\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 321: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 46,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17691479550703612153,\n name: \"Keyboard.46\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 322: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 47,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1563805812426809584,\n name: \"Keyboard.47\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 323: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 48,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4990521215321953950,\n name: \"Keyboard.48\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 324: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 49,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5571610057764575638,\n name: \"Keyboard.49\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 325: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 50,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1870102954350984771,\n name: \"Keyboard.50\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 326: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 51,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12589463949486400167,\n name: \"Keyboard.51\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 327: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 52,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17825707333473962626,\n name: \"Keyboard.52\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 328: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 53,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12144900706243249505,\n name: \"Keyboard.53\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 329: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 54,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6789361655900191938,\n name: \"Keyboard.54\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 330: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 55,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18233013041388070284,\n name: \"Keyboard.55\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 331: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 56,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4662938992908878102,\n name: \"Keyboard.56\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 332: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 57,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 4915669298158250604,\n name: \"Keyboard.57\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 333: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 58,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18270345796694315974,\n name: \"Keyboard.58\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 334: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 59,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3079448134738135004,\n name: \"Keyboard.59\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 335: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 60,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11714120120161694258,\n name: \"Keyboard.60\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 336: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 61,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10523885056233334041,\n name: \"Keyboard.61\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 337: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 62,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16277780437737276339,\n name: \"Keyboard.62\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 338: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 63,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1288238591423617971,\n name: \"Keyboard.63\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 339: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 64,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3560464588000676014,\n name: \"Keyboard.64\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 340: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 37,\n 65,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5592780355266779383,\n name: \"Keyboard.65\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 341: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 38,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13395076145067180508,\n name: \"MaskStand\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n },\n ),\n 342: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 4,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 1.8815651,\n y: 1.2217286,\n z: 0.13310231,\n ),\n rotation: (\n x: 0.0,\n y: 0.74752766,\n z: 0.0,\n w: -0.66423076,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11575612437093019175,\n name: \"Turntable\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 226,\n ]),\n },\n ),\n 343: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 9,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.25171363,\n y: 2.0128434,\n z: 3.8510816,\n ),\n rotation: (\n x: 0.5,\n y: -0.5,\n z: 0.5,\n w: 0.5,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6047989615790079100,\n name: \"Clock_Plain\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 231,\n ]),\n },\n ),\n 344: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 13,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 1.9447775,\n y: 1.623013,\n z: 0.14467725,\n ),\n rotation: (\n x: 0.0,\n y: -0.70710665,\n z: 0.0,\n w: 0.7071069,\n ),\n scale: (\n x: 0.99999994,\n y: 1.0,\n z: 0.99999994,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11901467750951413030,\n name: \"Vase\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 235,\n ]),\n },\n ),\n 345: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 14,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 2.1681519,\n y: 1.3056031,\n z: 0.91200435,\n ),\n rotation: (\n x: -0.006548479,\n y: 0.030810712,\n z: 0.2077902,\n w: 0.9776661,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16325639447001703091,\n name: \"Painting\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 236,\n ]),\n },\n ),\n 346: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 16,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -1.1451,\n y: 2.019511,\n z: -2.4,\n ),\n rotation: (\n x: 0.70710677,\n y: 0.0,\n z: 0.0,\n w: 0.7071067,\n ),\n scale: (\n x: 1.8488362,\n y: 1.8488364,\n z: 1.8488364,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16038708317184909401,\n name: \"Clock_Fancy\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 238,\n ]),\n },\n ),\n 347: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 17,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 5.0616355,\n y: -3.7466764,\n z: -8.153595,\n ),\n rotation: (\n x: 0.53014135,\n y: -0.10957064,\n z: 0.17018145,\n w: 0.8233972,\n ),\n scale: (\n x: 1.3000001,\n y: 1.3000001,\n z: 1.3000001,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 10855439342359554842,\n name: \"Rug\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 239,\n ]),\n },\n ),\n 348: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 19,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 2.5875344,\n y: -0.6504897,\n z: -1.94945,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 9507034154890999015,\n name: \"Flowers\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 241,\n 242,\n ]),\n },\n ),\n 349: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 21,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: -1.6244209,\n y: -0.34040022,\n z: -1.606607,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 17791299942127940392,\n name: \"PottedPlant.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 248,\n 249,\n ]),\n },\n ),\n 350: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.35011268,\n y: 0.0,\n z: -0.99575543,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 0.8041385,\n y: 0.8041385,\n z: 0.8041385,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 12215706144972666758,\n name: \"base human female rig\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"space_prefab::save::ChildrenPrefab\": ([\n 133,\n 134,\n 135,\n 136,\n 137,\n 138,\n 139,\n 12,\n 13,\n 145,\n 150,\n 16,\n 17,\n 155,\n 19,\n 20,\n 21,\n 156,\n 23,\n 24,\n 157,\n 26,\n 27,\n 28,\n 158,\n 161,\n 164,\n 32,\n 165,\n 168,\n 171,\n 36,\n 172,\n 38,\n 174,\n 40,\n 175,\n 177,\n 179,\n 180,\n 181,\n 182,\n 183,\n 186,\n 187,\n 190,\n 51,\n 191,\n 53,\n 54,\n 192,\n 56,\n 193,\n 194,\n 195,\n 196,\n 61,\n 62,\n 63,\n 64,\n 65,\n 66,\n 197,\n 68,\n 69,\n 70,\n 198,\n 72,\n 200,\n 213,\n 82,\n 215,\n 91,\n 92,\n ]),\n \"studio::anim::Skeleton\": (),\n },\n ),\n 351: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 3,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15117791534975515272,\n name: \"Cube.010.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 352: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 4,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13618103622474903094,\n name: \"Mesh.008.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 353: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 5,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7296826569135617056,\n name: \"Cube.004.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 354: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 5,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 7767638055472415442,\n name: \"Cube.004.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 355: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 3,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 13985900525202258737,\n name: \"Cube.010.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 356: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 0,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1455622020426310087,\n name: \"Cube.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 357: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 1,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 11389510482376162267,\n name: \"Cube.003\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 358: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 3,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 18255521253816864638,\n name: \"Cube.010.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 359: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 5,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 3508565512674969580,\n name: \"Cube.004.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 360: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 5,\n 3,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 8851541936950713692,\n name: \"Cube.004.3\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 361: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 0,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 1930078010574380345,\n name: \"Cube.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 362: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 2,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 15656008459981989270,\n name: \"Cube.009.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 363: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 4,\n 1,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 5152044184633228138,\n name: \"Mesh.008.1\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 364: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 5,\n 4,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 6667389065424992237,\n name: \"Cube.004.4\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 365: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 2,\n 2,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 14184141110628903720,\n name: \"Cube.009.2\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n 366: (\n components: {\n \"space_prefab::sub_scene::ChildPath\": ([\n 0,\n 39,\n 2,\n 0,\n ]),\n \"bevy_transform::components::transform::Transform\": (\n translation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n ),\n rotation: (\n x: 0.0,\n y: 0.0,\n z: 0.0,\n w: 1.0,\n ),\n scale: (\n x: 1.0,\n y: 1.0,\n z: 1.0,\n ),\n ),\n \"bevy_core::name::Name\": (\n hash: 16401889644376325307,\n name: \"Cube.009.0\",\n ),\n \"bevy_render::view::visibility::Visibility\": Inherited,\n \"studio::anim::ProcessedSkinnedMesh\": (),\n },\n ),\n },\n)"), + "space_prefab::sub_scene::ChildPath": ([]), + "bevy_transform::components::transform::Transform": ( + translation: ( + x: 0.0, + y: 0.0, + z: 0.0, + ), + rotation: ( + x: 0.0, + y: 0.0, + z: 0.0, + w: 1.0, + ), + scale: ( + x: 1.0, + y: 1.0, + z: 1.0, + ), + ), + "bevy_render::view::visibility::Visibility": Inherited, + "space_prefab::component::GltfPrefab": ( + path: "gltf/sample-room.gltf", + scene: "Scene0", + ), + }, + ), + }, +) \ No newline at end of file diff --git a/studio/src/lib.rs b/studio/src/lib.rs index 560a707..0ef7ff4 100644 --- a/studio/src/lib.rs +++ b/studio/src/lib.rs @@ -136,6 +136,8 @@ pub enum InitAsset { /// Initialize the application by retargeting a Mixamo animation onto the /// bundled `Mannequin.gltf` model. MixamoAnim(String), + /// Initialize the application by loading an arbitary model given an identifier + MediaAsset(String), } pub fn start(init: InitParams, mode: StudioMode, window_config: Option) -> App { @@ -231,5 +233,6 @@ fn init_from_asset(app: &mut App, asset: InitAsset, skybox_id: String) { ew.send(ImportSceneEvent(scene.clone())); }); } + InitAsset::MediaAsset(_) => todo!(), } } diff --git a/studio/src/skybox.rs b/studio/src/skybox.rs index d50edea..55aa0b6 100644 --- a/studio/src/skybox.rs +++ b/studio/src/skybox.rs @@ -39,12 +39,21 @@ struct SkyboxAssets { } fn load_skybox(mut cmd: Commands, assets: Res, id: Res) { - let paths = SkyboxPaths::new(&**id); - cmd.insert_resource(SkyboxAssets { - cubemap: assets.load(paths.cubemap), - env_diffuse: assets.load(paths.env_diffuse), - env_specular: assets.load(paths.env_specular), - }); + let id = &**id; + if let Ok(color) = Color::hex(id) { + cmd.insert_resource(ClearColor(color)); + cmd.insert_resource(AmbientLight { + color, + brightness: 1.0, + }) + } else { + let paths = SkyboxPaths::new(id); + cmd.insert_resource(SkyboxAssets { + cubemap: assets.load(paths.cubemap), + env_diffuse: assets.load(paths.env_diffuse), + env_specular: assets.load(paths.env_specular), + }); + } } fn skybox_assets_loaded( diff --git a/studio/src/wasm/init.rs b/studio/src/wasm/init.rs index 0fb6a21..c3850f1 100644 --- a/studio/src/wasm/init.rs +++ b/studio/src/wasm/init.rs @@ -6,19 +6,10 @@ use crate::{InitAsset, InitParams, StudioMode, ViewportSize}; #[wasm_bindgen(typescript_custom_section)] const WASM_ENTRY_POINTS: &str = r#" -export type SkyboxId - = "gum_trees_4k" - | "kloofenfal_28d_misty_4k" - | "meadow_4k" - | "promenade_de_vidy_4k" - | "scythian_tombs_4k" - | "test_scene" - ; - export interface InitOptions { mode: StudioMode; /** Required for all entry-points except `initFromStorytellerScene()` */ - skyboxId?: SkyboxId; + skyboxId?: string; canvasSelector: string; canvasAlt: string; viewportSize: ViewportSize; From d6c5d5d5bdebc3ac51b7f4ba4dac072dea76b99e Mon Sep 17 00:00:00 2001 From: Danny McGee Date: Wed, 28 Feb 2024 03:17:45 -0500 Subject: [PATCH 09/13] Image Generator Demo: UI/UX (#58) This PR updates the UI/UX of the Image Generator Demo. * Hierarchy moved to the left of the editor view instead of overlaying it * Hierarchy can now be resized * Bevy canvas resizes trigger a screen-capture update * Transform Toolbar now centered over the editor view instead of the entire viewport * Added Prompt and Seed text fields, with a refresh button for the Seed --- framework/src/lib/decorators/debounce.ts | 21 +++ framework/src/lib/decorators/index.ts | 1 + image-generator-demo/src/app/app.element.scss | 136 ++++++++++++--- image-generator-demo/src/app/app.element.ts | 165 +++++++++++++----- studio-web/src/lib/studio.element.ts | 10 +- 5 files changed, 268 insertions(+), 65 deletions(-) create mode 100644 framework/src/lib/decorators/debounce.ts diff --git a/framework/src/lib/decorators/debounce.ts b/framework/src/lib/decorators/debounce.ts new file mode 100644 index 0000000..79ce479 --- /dev/null +++ b/framework/src/lib/decorators/debounce.ts @@ -0,0 +1,21 @@ +import { type Fn } from "@storyteller/utility"; +import { LitElement } from "lit"; +import { debounce as _debounce, type DebounceSettings } from "lodash"; + +import { getMethodDescriptor } from "./internal"; + +export function debounce(wait: number, options?: DebounceSettings) { + return (proto: T, propName: keyof T, desc: PropertyDescriptor) => { + const method = (desc?.value as Fn) + ?? getMethodDescriptor(proto, propName)?.value + ?? (() => {}); + + const updated: PropertyDescriptor = { + value: _debounce(method, wait, options), + } + + Object.defineProperty(proto, propName, updated); + + return updated; + } +} diff --git a/framework/src/lib/decorators/index.ts b/framework/src/lib/decorators/index.ts index 66c74fd..1f90baa 100644 --- a/framework/src/lib/decorators/index.ts +++ b/framework/src/lib/decorators/index.ts @@ -1 +1,2 @@ +export * from "./debounce"; export * from "./on"; diff --git a/image-generator-demo/src/app/app.element.scss b/image-generator-demo/src/app/app.element.scss index 11870fa..749c3dd 100644 --- a/image-generator-demo/src/app/app.element.scss +++ b/image-generator-demo/src/app/app.element.scss @@ -2,6 +2,7 @@ position: fixed; inset: 0; display: flex; + background: #242433; } // Layout utilities @@ -17,46 +18,137 @@ transform: translateX(-50%); } +.hierarchy-wrapper { + display: flex; + flex: 0 0 auto; + height: 100vh; +} +.hierarchy { + display: block; + width: 100%; + height: 100%; + padding: 1rem { + inline-end: 0.5rem; + } + border: none; + background: transparent; +} +.hierarchy-resize-handle { + width: 0.5rem; + cursor: ew-resize; + background: transparent; + transition: background 66.666ms linear; + + &:hover, &.resizing { + background: #39394c; + } +} + +.split-screen { + display: flex; + flex: 1 0 0; + position: relative; +} + .studio-scene, .image-capture { flex: 0 0 50%; } +.studio-scene { + overflow: hidden; +} +.image-capture { + width: 0; + object-fit: cover; +} -.hierarchy { - width: 256px; - max-height: calc(100vh - 2rem); +.studio-scene.resizing::part(canvas) { + pointer-events: none; } .config { - display: flex; - flex-direction: column; - gap: 0.25em; - - padding: 0.5rem 1rem; + padding: 1rem; background: #0006; backdrop-filter: blur(16px); border-radius: 0.5rem; +} - .checkbox { - display: flex; - align-items: center; - gap: 0.5rem; - height: 1.5rem; +.config-prompt { + display: flex; + gap: 0.5rem; +} - color: #FFFC; - transition: color 0.1s linear; - font: { - family: "Fira Sans", sans-serif; - size: 15px; - weight: 500; - } +.config-checkbox { + display: flex; + align-items: center; + gap: 0.5rem; - &:hover { - color: #FFFF; + color: #FFFC; + transition: color 0.1s linear; + font: { + family: "Fira Sans", sans-serif; + size: 15px; + weight: 500; + } + + &:hover { + color: #FFFF; + } +} + +.config-field { + background: #0004; + border: 1px solid #FFF2; + color: #FFFC; + padding: 0.5rem 0.75rem; + border-radius: 0.25rem; + font: { + family: "Fira Sans", sans-serif; + size: 1rem; + } + + &::placeholder { + color: #FFF6; + } + + &:focus-visible { + outline: none !important; + border-color: #FFF4; + background: #0006; + color: #FFFF; + } + + &.prompt { + width: 512px; + } + + &.seed { + width: 96px; + appearance: textfield; + + &::-webkit-outer-spin-button, + &::-webkit-inner-spin-button { + appearance: none; + margin: 0; } } } +.config-field-group { + position: relative; +} + +.seed-refresh { + position: absolute; + top: 0; + right: 0.5rem; + bottom: 0; + appearance: none; + border: none; + background: transparent; + color: #FFFC; +} + .loading { position: absolute; inset: 0; diff --git a/image-generator-demo/src/app/app.element.ts b/image-generator-demo/src/app/app.element.ts index e8f2dc6..606c239 100644 --- a/image-generator-demo/src/app/app.element.ts +++ b/image-generator-demo/src/app/app.element.ts @@ -1,4 +1,4 @@ -import { on } from "@storyteller/framework"; +import { debounce, drag, on } from "@storyteller/framework"; import * as studio from "@storyteller/studio"; import { SceneState, @@ -9,7 +9,8 @@ import { import { match } from "@storyteller/utility"; import { LitElement, html, nothing } from "lit"; import { customElement, state } from "lit/decorators.js"; -import { DebounceSettings, debounce } from "lodash"; +import { styleMap } from "lit/directives/style-map.js"; +import { classMap } from "lit/directives/class-map.js"; import "@storyteller/studio-web/canvas-provider"; import "@storyteller/studio-web/scene-hierarchy"; @@ -18,30 +19,19 @@ import "@storyteller/studio-web/transform-toolbar"; import "./app.element.scss" -class Debounce { - static readonly Wait = 1000 / 24; - static readonly Realtime = { - leading: false, - trailing: true, - maxWait: 1000 / 5, - }; - - static readonly Delayed = { - leading: false, - trailing: true, - }; - - static func(config: DebounceSettings) { - return debounce(() => studio.requestScreenshot(), this.Wait, config); - } -} - @customElement("app-root") export class AppElement extends LitElement { - @state() loading = true; @state() imageCaptureUrl?: string; @state() realtimeCapture = true; + @state() hierarchyWidth = 256; + @state() resizing = false; + + @state() loading = true; + + @state() prompt = ""; + @state() seed = randomSeed(); + protected override createRenderRoot = () => this; override disconnectedCallback(): void { @@ -63,10 +53,29 @@ export class AppElement extends LitElement { @on("entity-changes") onStudioChanges(): void { - this.requestScreenshot(); + if (this.realtimeCapture) { + this.requestScreenshot_realtime(); + } else { + this.requestScreenshot_delayed(); + } } - requestScreenshot = Debounce.func(Debounce.Realtime); + @on("viewport-resized") + // This handler requires a longer debounce to avoid crashing the render piptline + @debounce(1000 / 5) + onViewportResized(): void { + studio.requestScreenshot(); + } + + @debounce(1000 / 24, { maxWait: 1000 / 5 }) + requestScreenshot_realtime() { + studio.requestScreenshot(); + } + + @debounce(1000 / 24) + requestScreenshot_delayed() { + studio.requestScreenshot(); + } @on("screenshot-ready") onScreenshotReady({ detail: screenshot }: ScreenshotReadyEvent) { @@ -74,41 +83,109 @@ export class AppElement extends LitElement { const blob = new Blob([screenshot.data.buffer], { type: "image/png" }); this.imageCaptureUrl = URL.createObjectURL(blob); - console.log(`New blob URL: ${this.imageCaptureUrl}`); if (prevUrl != null) URL.revokeObjectURL(prevUrl); } + onResizeStart(): void { + this.resizing = true; + } + + onResizeEnd(): void { + this.resizing = false; + } + + onResize(event: PointerEvent): void { + let updated = this.hierarchyWidth + event.movementX; + this.hierarchyWidth = Math.max(Math.min(updated, 512), 128); + } + toggleRealtimeCapture(event: InputEvent): void { const { checked } = event.target as HTMLInputElement; this.realtimeCapture = checked; + } - const config = checked ? Debounce.Realtime : Debounce.Delayed; - this.requestScreenshot = Debounce.func(config); + refreshSeed(): void { + this.seed = randomSeed(); } protected override render = () => html` - +
+ +
+
- ${this.imageCaptureUrl != null ? html` - Image capture - ` : nothing} +
+ + + + + ${this.imageCaptureUrl != null ? html` + Image capture + ` : html` +
+ `} + +
event.stopPropagation()} + @keyup=${(event: KeyboardEvent) => event.stopPropagation()} + > + +
+ + +
+
+
- -
-