reacthub-pixitweenjs 0.3.2-alpha.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/components/AepComposition/AepComposition.d.ts +2 -0
  2. package/dist/components/AepComposition/index.d.ts +2 -1
  3. package/dist/components/AepComposition/model3d/animation.d.ts +21 -0
  4. package/dist/components/AepComposition/model3d/index.d.ts +2 -0
  5. package/dist/components/AepComposition/model3d/threeUtils.d.ts +15 -0
  6. package/dist/components/AepComposition/model3d/toon.d.ts +26 -0
  7. package/dist/components/AepComposition/stage3d/AepStageLayoutContext.d.ts +21 -0
  8. package/dist/components/AepComposition/stage3d/Pixi3DStageLayer.d.ts +11 -0
  9. package/dist/components/AepComposition/stage3d/StageRuntime.d.ts +66 -0
  10. package/dist/components/AepComposition/stage3d/buildWorld.d.ts +52 -0
  11. package/dist/components/AepComposition/stage3d/clipBinding.d.ts +29 -0
  12. package/dist/components/AepComposition/stage3d/convert.d.ts +9 -0
  13. package/dist/components/AepComposition/stage3d/index.d.ts +14 -0
  14. package/dist/components/AepComposition/stage3d/layout.d.ts +16 -0
  15. package/dist/components/AepComposition/stage3d/members/actor3d.d.ts +10 -0
  16. package/dist/components/AepComposition/stage3d/members/normalize.d.ts +19 -0
  17. package/dist/components/AepComposition/stage3d/members/prop3d.d.ts +3 -0
  18. package/dist/components/AepComposition/stage3d/members/registry.d.ts +9 -0
  19. package/dist/components/AepComposition/stage3d/members/types.d.ts +43 -0
  20. package/dist/components/AepComposition/stage3d/reconcile.d.ts +22 -0
  21. package/dist/components/AepComposition/stage3d/sampleStage3D.d.ts +75 -0
  22. package/dist/components/AepComposition/stage3d/style.d.ts +21 -0
  23. package/dist/components/AepComposition/useAepLayerTransform.d.ts +2 -2
  24. package/dist/components/AepComposition/useResolveAsset.d.ts +1 -0
  25. package/dist/hocs/AbstractContainer.d.ts +9 -0
  26. package/dist/importers/aep/index.d.ts +1 -0
  27. package/dist/importers/aep/stageLint.d.ts +3 -0
  28. package/dist/index.es.js +10854 -9453
  29. package/dist/index.umd.js +73 -70
  30. package/dist/types/aep/composition.d.ts +2 -1
  31. package/dist/types/aep/index.d.ts +1 -0
  32. package/dist/types/aep/layer.d.ts +10557 -4046
  33. package/dist/types/aep/stage3d.d.ts +18 -0
  34. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import { StageLayoutListener } from './stage3d/AepStageLayoutContext';
1
2
  import { AepCompositionJson, AepThemeMap, AepTransitionOverrideMap } from '../../types/aep';
2
3
  import { AepTextOverrideMap } from './AepTextOverrideContext';
3
4
  import { AepAssetOverrideMap } from './AepLayerProvider';
@@ -15,5 +16,6 @@ export interface AepCompositionProps {
15
16
  transitionOverrides?: AepTransitionOverrideMap;
16
17
  onRenderReady?: () => void;
17
18
  onLayerError?: (layerId: string, error: unknown) => void;
19
+ onStageLayout?: StageLayoutListener;
18
20
  }
19
21
  export declare const AepComposition: React.FC<AepCompositionProps>;
@@ -38,7 +38,7 @@ export type { Transform3DChannels } from './composeTransform3D';
38
38
  export { useAepLayerTransform } from './useAepLayerTransform';
39
39
  export type { AepResolvedTransform } from './useAepLayerTransform';
40
40
  export { AepAssetResolverProvider, defaultAssetResolver, useAepAssetResolver, type AepAssetResolver, type AepResolvedAsset, } from './AepAssetResolver';
41
- export { useResolveAsset } from './useResolveAsset';
41
+ export { useResolveAsset, useResolveAssets } from './useResolveAsset';
42
42
  export type { AepAssetState, AepResolvedAssetState } from './useResolveAsset';
43
43
  export { AepThemeProvider, useAepTheme, mergeTheme, } from './AepThemeContext';
44
44
  export { AepTextOverrideProvider, useAepTextOverride, resolveTextSource, } from './AepTextOverrideContext';
@@ -48,3 +48,4 @@ export { shouldSplitText } from './shouldSplitText';
48
48
  export { AudioPlaybackManager } from './AudioPlaybackManager';
49
49
  export type { AudioPlaybackManagerProps, AudioPlaybackElement, } from './AudioPlaybackManager';
50
50
  export * from './model3d';
51
+ export * from './stage3d';
@@ -0,0 +1,21 @@
1
+ import { AepModel3DAnimation } from '../../../types/aep';
2
+ export interface NamedClip {
3
+ name: string;
4
+ duration: number;
5
+ }
6
+ /**
7
+ * Picks the clip an `animation.clip` selector refers to. A name or index that
8
+ * does not exist falls back to clip 0 (`fellBack` is set so callers can warn).
9
+ */
10
+ export declare function pickClip<T extends NamedClip>(clips: readonly T[], selector: AepModel3DAnimation["clip"]): {
11
+ clip: T;
12
+ fellBack: boolean;
13
+ } | null;
14
+ export declare const HOLD_EPSILON = 0.0001;
15
+ /**
16
+ * Seconds to scrub the mixer to: `offset + speed * (time since in-point)`.
17
+ * With `loop: false` the time holds just before `clipDuration`. Holding here
18
+ * instead of using THREE.LoopOnce keeps seeking stateless: a LoopOnce action
19
+ * pauses itself at the end and then ignores `mixer.setTime` on a seek back.
20
+ */
21
+ export declare function animationTimeSeconds(frame: number, inPointFrames: number, fps: number, animation?: AepModel3DAnimation, clipDuration?: number): number;
@@ -6,6 +6,8 @@ export { ThreeOffscreenRenderer, acquireOffscreenRenderer, releaseOffscreenRende
6
6
  export type { OffscreenRenderRequest, OffscreenGlRenderer, } from './ThreeOffscreenRenderer';
7
7
  export { frameCamera, clipTimeSeconds, isFrameInRange } from './framing';
8
8
  export type { CameraFraming } from './framing';
9
+ export { animationTimeSeconds, pickClip } from './animation';
10
+ export { applyToonStyle, getToonGradientMap } from './toon';
9
11
  export { LIGHTING_PRESETS, DEFAULT_LIGHTING_PRESET, resolveLightingConfig, directionFromAzimuthElevation, } from './lighting';
10
12
  export type { LightingConfig, LightingOverrides, LightingPresetName, LightingRig, } from './lighting';
11
13
  export { buildPrimitiveGeometry, buildExtrudeGeometry, buildSourceGeometry, } from './geometry';
@@ -0,0 +1,15 @@
1
+ import * as THREE from "three";
2
+ export declare function makeMaterial(color: string, map: THREE.Texture | null, clearcoat: number, centerOnFront?: boolean): THREE.MeshPhysicalMaterial;
3
+ export declare function loadTexture(url: string): Promise<THREE.Texture>;
4
+ export declare function collectMaterials(root: THREE.Object3D): THREE.MeshStandardMaterial[];
5
+ /** Textures flagged `userData.shared` (e.g. the cached toon gradient) outlive any one object. */
6
+ export declare function isSharedTexture(texture: THREE.Texture): boolean;
7
+ export interface DisposeOptions {
8
+ /**
9
+ * Dispose only resources flagged `userData.stageOwned`. A stage3d member shares
10
+ * geometries, materials and textures with its cached glTF (clones reference
11
+ * them), so it frees only what it created itself.
12
+ */
13
+ onlyOwned?: boolean;
14
+ }
15
+ export declare function disposeObject3D(root: THREE.Object3D, options?: DisposeOptions): void;
@@ -0,0 +1,26 @@
1
+ import * as THREE from "three";
2
+ /** N-band 1px-high ramp for MeshToonMaterial.gradientMap (nearest-filtered, so bands stay hard). */
3
+ export declare function getToonGradientMap(steps: number): THREE.DataTexture;
4
+ export declare function createOutlineMaterial(color: string, width: number): THREE.MeshBasicMaterial;
5
+ /**
6
+ * Hull geometry with position-welded, smoothed normals. Hard-edged meshes (boxes) carry per-face
7
+ * normals, which would pull an inflated hull apart at every edge and leave gaps in the outline.
8
+ */
9
+ export declare function createSmoothedHullGeometry(source: THREE.BufferGeometry): THREE.BufferGeometry;
10
+ export interface ToonStyleOptions {
11
+ toon: boolean;
12
+ steps: number;
13
+ outline?: {
14
+ color: string;
15
+ width: number;
16
+ };
17
+ }
18
+ /**
19
+ * Applies the cartoon look to `content` in place. Returns the replaced
20
+ * (original) materials so the caller can dispose them. Outline hulls are
21
+ * children of their mesh, so disposing `content` disposes them too.
22
+ */
23
+ export declare function applyToonStyle(content: THREE.Object3D, options: ToonStyleOptions): {
24
+ replaced: THREE.Material[];
25
+ hulls: THREE.Mesh[];
26
+ };
@@ -0,0 +1,21 @@
1
+ import { StageRect } from './layout';
2
+ import * as React from "react";
3
+ export interface StageLayoutEvent {
4
+ worldId: string;
5
+ frame: number;
6
+ /** The world layer's offscreen size; rects are in these pixels. Map to comp px with the layer's own transform. */
7
+ viewport: {
8
+ width: number;
9
+ height: number;
10
+ };
11
+ rects: Record<string, StageRect & {
12
+ role?: "prop" | "product";
13
+ }>;
14
+ }
15
+ export type StageLayoutListener = (event: StageLayoutEvent) => void;
16
+ export declare const AepStageLayoutProvider: React.FC<{
17
+ onStageLayout?: StageLayoutListener;
18
+ children: React.ReactNode;
19
+ }>;
20
+ /** Null when nobody listens, so the layer can skip the projection work. */
21
+ export declare function useAepStageLayoutListener(): StageLayoutListener | null;
@@ -0,0 +1,11 @@
1
+ import { ForwardedRefResponse, PixiBaseSpriteProps } from '../../../types/BaseProps';
2
+ import { AepStage3DLayer, AepStageMemberLayer } from '../../../types/aep';
3
+ import * as React from "react";
4
+ export interface Pixi3DStageLayerProps extends PixiBaseSpriteProps {
5
+ layer: AepStage3DLayer;
6
+ }
7
+ /** Members of this world, in composition order. In a precomp, `layersById` is the precomp's own list. */
8
+ export declare function useStageMembers(worldId: string): AepStageMemberLayer[];
9
+ export declare const Pixi3DStageLayer: React.MemoExoticComponent<({ ref, layer, ...props }: Pixi3DStageLayerProps & {
10
+ ref?: React.Ref<ForwardedRefResponse | null>;
11
+ }) => React.JSX.Element>;
@@ -0,0 +1,66 @@
1
+ import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';
2
+ import { AepStage3DLayer, AepStageMemberLayer } from '../../../types/aep';
3
+ import { StageWorld } from './buildWorld';
4
+ import { StageMemberRig } from './members/types';
5
+ import { SampledStageWorld } from './sampleStage3D';
6
+ import * as THREE from "three";
7
+ export interface ReconcileInput {
8
+ worldLayer: AepStage3DLayer;
9
+ /** Changes when the world itself must be rebuilt (viewport, camera, set, style, spots, backdrop URL). */
10
+ worldKey: string;
11
+ members: Array<{
12
+ layer: AepStageMemberLayer;
13
+ key: string;
14
+ attachTo?: string;
15
+ }>;
16
+ /** assetId -> URL */
17
+ urls: Readonly<Record<string, string>>;
18
+ }
19
+ export interface StageRuntimeOptions {
20
+ renderer?: () => THREE.WebGLRenderer | undefined;
21
+ loadGltf?: (url: string) => Promise<GLTF>;
22
+ loadTexture?: (url: string) => Promise<THREE.Texture>;
23
+ warn?: (message: string) => void;
24
+ onError?: (error: unknown) => void;
25
+ }
26
+ interface BuiltMember {
27
+ rig: StageMemberRig;
28
+ layer: AepStageMemberLayer;
29
+ }
30
+ export declare class StageRuntime {
31
+ private readonly options;
32
+ world: StageWorld | null;
33
+ /** True once the latest reconcile finished: the world and every member are built. */
34
+ ready: boolean;
35
+ readonly rigs: Map<string, BuiltMember>;
36
+ private state;
37
+ private gen;
38
+ private disposed;
39
+ /** Set whenever something was built: the next apply renders once with everything visible. */
40
+ private needsWarm;
41
+ private queue;
42
+ private readonly gltfCache;
43
+ private readonly warned;
44
+ constructor(options?: StageRuntimeOptions);
45
+ private loadGltf;
46
+ private warn;
47
+ /** Resolves true when this call's input is fully built, false if superseded, disposed or failed. */
48
+ reconcile(input: ReconcileInput): Promise<boolean>;
49
+ private stale;
50
+ private run;
51
+ /** Applies the sampled world + member poses. No-op until ready. */
52
+ apply(world: SampledStageWorld, samples: ReadonlyMap<string, unknown>): boolean;
53
+ /**
54
+ * Renders once with every member visible. Three compiles shaders and uploads
55
+ * geometry, skeleton textures and shadow maps on first use, and skips invisible
56
+ * objects, so without this a member that enters later (inPoint) or is un-hidden
57
+ * costs a one-off hitch mid-playback. The real draw follows immediately and
58
+ * overwrites the output.
59
+ */
60
+ private warm;
61
+ private disposeMember;
62
+ private disposeBuilt;
63
+ /** Frees members, world and the glTF cache. Safe to call twice. */
64
+ dispose(): Promise<void>;
65
+ }
66
+ export {};
@@ -0,0 +1,52 @@
1
+ import { AepStage3DLayer } from '../../../types/aep';
2
+ import { LightingRig } from '../model3d/lighting';
3
+ import { SampledStageWorld } from './sampleStage3D';
4
+ import * as THREE from "three";
5
+ export interface StageWorld {
6
+ scene: THREE.Scene;
7
+ camera: THREE.PerspectiveCamera;
8
+ lighting: LightingRig;
9
+ spots: Map<string, {
10
+ light: THREE.SpotLight;
11
+ target: THREE.Object3D;
12
+ }>;
13
+ ground: THREE.Mesh;
14
+ wall: THREE.Mesh | null;
15
+ /** True when the wall carries the unlit backdrop image (it must not be toon-shaded). */
16
+ hasBackdrop: boolean;
17
+ membersRoot: THREE.Group;
18
+ extents: {
19
+ halfWidth: number;
20
+ halfDepth: number;
21
+ };
22
+ dispose(): void;
23
+ }
24
+ export interface CycloramaOptions {
25
+ width: number;
26
+ distance: number;
27
+ height: number;
28
+ curve: number;
29
+ /** v = 0 across the cove and 0->1 up the vertical wall (for a painted backdrop). */
30
+ wallUv?: boolean;
31
+ }
32
+ /**
33
+ * Curved studio wall in the YZ plane, extruded along X: a quarter-circle cove of
34
+ * radius `curve` blends the floor (starting at z = -distance + curve) into a
35
+ * vertical wall at z = -distance, up to `height`. Normals face +Z / up.
36
+ */
37
+ export declare function buildCycloramaGeometry({ width, distance, height, curve, wallUv, }: CycloramaOptions): THREE.BufferGeometry;
38
+ export declare function lightingConfigFor(s: SampledStageWorld["lighting"]): {
39
+ ambientIntensity: number;
40
+ preset: import('..').LightingPresetName;
41
+ keyAzimuth: number;
42
+ keyElevation: number;
43
+ keyIntensity: number;
44
+ keyColor: string;
45
+ fillIntensity: number;
46
+ rimIntensity: number;
47
+ environmentIntensity: number;
48
+ environment: "room" | "none";
49
+ };
50
+ export declare function buildWorld(world: AepStage3DLayer, backdrop: THREE.Texture | null, renderer?: THREE.WebGLRenderer): StageWorld;
51
+ /** Per-frame world values: lights, ambient, spots, shadow strength. No allocation of GPU resources. */
52
+ export declare function applyWorld(w: StageWorld, s: SampledStageWorld, renderer?: THREE.WebGLRenderer): void;
@@ -0,0 +1,29 @@
1
+ import * as THREE from "three";
2
+ /** `mixamorig:LeftArm`, `mixamorigLeftArm`, `mixamorig1:LeftArm`, `LeftArm` -> `leftarm`. */
3
+ export declare function normalizeBoneName(name: string): string;
4
+ export interface BindResult {
5
+ /** clip track name -> rewritten track name for the actor */
6
+ trackMap: Map<string, string>;
7
+ /** normalised clip bones with no match in the actor (sorted, unique) */
8
+ missingBones: string[];
9
+ boundBones: number;
10
+ }
11
+ export declare function splitTrackName(trackName: string): {
12
+ node: string;
13
+ property: string;
14
+ } | null;
15
+ export declare function bindTrackNames(trackNames: readonly string[], actorBoneNames: readonly string[]): BindResult;
16
+ export interface BindOptions {
17
+ rootMotion: "strip" | "keep";
18
+ /** Multiplies hips position values (clip units -> actor units). */
19
+ hipsScale: number;
20
+ }
21
+ /**
22
+ * Hips scale for converting a clip authored in another unit (Mixamo cm vs a
23
+ * metre actor): actor hips rest height / clip hips first height.
24
+ */
25
+ export declare function computeHipsScale(clip: THREE.AnimationClip, actorRoot: THREE.Object3D): number;
26
+ export declare function bindClipToSkeleton(clip: THREE.AnimationClip, actorRoot: THREE.Object3D, opts: BindOptions): {
27
+ clip: THREE.AnimationClip;
28
+ missingBones: string[];
29
+ };
@@ -0,0 +1,9 @@
1
+ import { AepModel3DLayer, AepProp3DLayer } from '../../../types/aep';
2
+ /**
3
+ * Upgrade path from the standalone `model3d` fallback: turns its product into a
4
+ * `prop3d` member of the world `stageId`. Copies identity, range, source and
5
+ * textures; `view.rotation` keyframes become the prop's `rotation`. Lighting,
6
+ * shadow, viewport and camera belong to the world (build it once per shot) and
7
+ * are not copied.
8
+ */
9
+ export declare function model3dToProp3d(layer: AepModel3DLayer, stageId: string): AepProp3DLayer;
@@ -0,0 +1,14 @@
1
+ export { Pixi3DStageLayer, useStageMembers } from './Pixi3DStageLayer';
2
+ export type { Pixi3DStageLayerProps } from './Pixi3DStageLayer';
3
+ export { sampleStageWorld, sampleActor3D, sampleProp3D, memberActive, scheduleClips, clipLocalTime, stageFrameKey, } from './sampleStage3D';
4
+ export type { SampledStageWorld, SampledActor3D, SampledProp3D, SampledClipWeight, } from './sampleStage3D';
5
+ export { normalizeBoneName, bindTrackNames, bindClipToSkeleton } from './clipBinding';
6
+ export { buildCycloramaGeometry } from './buildWorld';
7
+ export { planReconcile } from './reconcile';
8
+ export { projectBoxToViewport } from './layout';
9
+ export { model3dToProp3d } from './convert';
10
+ export type { StageRect } from './layout';
11
+ export { AepStageLayoutProvider, useAepStageLayoutListener } from './AepStageLayoutContext';
12
+ export type { StageLayoutEvent, StageLayoutListener } from './AepStageLayoutContext';
13
+ export { STAGE_MEMBER_HANDLERS } from './members/registry';
14
+ export type { StageMemberHandler, StageMemberRig, StageBuildContext } from './members/types';
@@ -0,0 +1,16 @@
1
+ import * as THREE from "three";
2
+ export interface StageRect {
3
+ x: number;
4
+ y: number;
5
+ width: number;
6
+ height: number;
7
+ }
8
+ /**
9
+ * Bounding rect of `box` seen through `camera`, clamped to the viewport.
10
+ * Returns null when any corner is behind the camera (the projection is not
11
+ * meaningful) or the box falls entirely outside the viewport.
12
+ */
13
+ export declare function projectBoxToViewport(box: THREE.Box3, camera: THREE.PerspectiveCamera, viewport: {
14
+ width: number;
15
+ height: number;
16
+ }): StageRect | null;
@@ -0,0 +1,10 @@
1
+ import { AepActor3DLayer } from '../../../../types/aep';
2
+ import { StageMemberHandler, StageMemberRig } from './types';
3
+ import * as THREE from "three";
4
+ export interface ActorRig extends StageMemberRig {
5
+ model: THREE.Object3D;
6
+ mixer: THREE.AnimationMixer;
7
+ actions: (THREE.AnimationAction | null)[];
8
+ durations: number[];
9
+ }
10
+ export declare const actor3dHandler: StageMemberHandler<AepActor3DLayer>;
@@ -0,0 +1,19 @@
1
+ import * as THREE from "three";
2
+ export interface Normalized {
3
+ /** Uniform scale applied to the model. */
4
+ scale: number;
5
+ }
6
+ /**
7
+ * Scales `model` uniformly so `measure(size)` equals `target`, then puts its
8
+ * bottom on y = 0 and centres it in x/z. Uses the rest pose (call before any
9
+ * animation plays). Returns the scale applied.
10
+ */
11
+ export declare function normalizeModel(model: THREE.Object3D, target: number, measure: (size: THREE.Vector3) => number): Normalized;
12
+ /**
13
+ * Scale from the first mesh's geometry units to world metres (outline width
14
+ * basis). Measured as rendered rest-pose size / geometry size rather than read
15
+ * from `matrixWorld`: a skinned mesh bound in "attached" mode cancels its
16
+ * parent scale (a cm rig under a 0.01 armature renders at the geometry's own
17
+ * scale), so the matrix would be off by that factor.
18
+ */
19
+ export declare function meshWorldScale(root: THREE.Object3D): number;
@@ -0,0 +1,3 @@
1
+ import { AepProp3DLayer } from '../../../../types/aep';
2
+ import { StageMemberHandler } from './types';
3
+ export declare const prop3dHandler: StageMemberHandler<AepProp3DLayer>;
@@ -0,0 +1,9 @@
1
+ import { AepStageMemberLayer } from '../../../../types/aep';
2
+ import { StageMemberHandler } from './types';
3
+ export declare const STAGE_MEMBER_HANDLERS: {
4
+ [K in AepStageMemberLayer["kind"]]: StageMemberHandler<Extract<AepStageMemberLayer, {
5
+ kind: K;
6
+ }>>;
7
+ };
8
+ /** Kind-erased lookup for code that iterates mixed members. */
9
+ export declare function handlerFor(layer: AepStageMemberLayer): StageMemberHandler<AepStageMemberLayer>;
@@ -0,0 +1,43 @@
1
+ import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';
2
+ import { AepStageMemberLayer } from '../../../../types/aep';
3
+ import type * as THREE from "three";
4
+ export interface StageBuildContext {
5
+ /** assetId -> resolved URL. */
6
+ urls: Readonly<Record<string, string>>;
7
+ /** Per-world cache. Never mutate or add the result to a scene: clone it. */
8
+ loadGltf(url: string): Promise<GLTF>;
9
+ /** Uncached: every call returns a texture the caller owns. */
10
+ loadTexture(url: string): Promise<THREE.Texture>;
11
+ /** Members already built (lower `order` first). */
12
+ rigs: ReadonlyMap<string, StageMemberRig>;
13
+ /** console.warn once per message per world. */
14
+ warn(message: string): void;
15
+ }
16
+ export interface StageMemberRig {
17
+ id: string;
18
+ /** Added to `world.membersRoot` by the world unless it already has a parent. */
19
+ root: THREE.Object3D;
20
+ /** Per-frame and stateless: the same sample gives the same pose whatever came before. */
21
+ apply(sample: unknown): void;
22
+ /** World-space box, for layout rects. */
23
+ worldBox(target: THREE.Box3): THREE.Box3;
24
+ /** Scale from the member's local units to world metres, for world-metre outlines. */
25
+ worldScale: number;
26
+ dispose(): void;
27
+ }
28
+ export interface StageMemberHandler<L extends AepStageMemberLayer> {
29
+ kind: L["kind"];
30
+ /** Lower builds first: actors 0, props 1 (attach needs actor bones). */
31
+ order: number;
32
+ /** Asset ids to resolve before build. */
33
+ assetIds(layer: L): string[];
34
+ /**
35
+ * JSON-able. A change rebuilds THIS member only, so it excludes per-frame
36
+ * fields (marks, position/rotation/scale keyframes, inPoint/outPoint, hidden).
37
+ */
38
+ structureOf(layer: L): unknown;
39
+ sample(layer: L, frame: number, fps: number): {
40
+ active: boolean;
41
+ };
42
+ build(layer: L, ctx: StageBuildContext): Promise<StageMemberRig>;
43
+ }
@@ -0,0 +1,22 @@
1
+ export interface ReconcileMember {
2
+ id: string;
3
+ /** Includes resolved asset URLs (and, for an attached prop, its actor's key). */
4
+ key: string;
5
+ /** Set for a prop attached to an actor: rebuilds when that actor does. */
6
+ attachTo?: string;
7
+ order: number;
8
+ }
9
+ export interface ReconcileState {
10
+ worldKey: string | null;
11
+ members: ReconcileMember[];
12
+ }
13
+ export interface ReconcilePlan {
14
+ rebuildWorld: boolean;
15
+ /** Members to build from scratch, in build order. */
16
+ build: string[];
17
+ /** Members to dispose and build again, in build order. */
18
+ rebuild: string[];
19
+ /** Members to dispose and not rebuild. */
20
+ dispose: string[];
21
+ }
22
+ export declare function planReconcile(prev: ReconcileState, next: ReconcileState): ReconcilePlan;
@@ -0,0 +1,75 @@
1
+ import { AepActor3DLayer, AepProp3DLayer, AepStage3DLayer, AepStageClip, AepStageMemberLayer } from '../../../types/aep';
2
+ import { LightingPresetName } from '../model3d/lighting';
3
+ type Vec3 = [number, number, number];
4
+ export interface SampledClipWeight {
5
+ clipIndex: number;
6
+ /** 0..1; the weights of an actor sum to 1 (or the actor has none). */
7
+ weight: number;
8
+ /** Unclamped clip time: offset + max(0, F - startFrame) / fps * speed. */
9
+ rawSeconds: number;
10
+ loop: boolean;
11
+ }
12
+ export interface SampledSpot {
13
+ id: string;
14
+ position: Vec3;
15
+ target: Vec3;
16
+ intensity: number;
17
+ angleDeg: number;
18
+ }
19
+ export interface SampledStageLighting {
20
+ preset: LightingPresetName;
21
+ keyAzimuth: number;
22
+ keyElevation: number;
23
+ keyIntensity: number;
24
+ keyColor: string;
25
+ fillIntensity: number;
26
+ rimIntensity: number;
27
+ ambient: number;
28
+ environment: "room" | "none";
29
+ }
30
+ export declare const STAGE3D_DEFAULTS: {
31
+ readonly shadowOpacity: 0.55;
32
+ readonly shadowSoftness: 0.5;
33
+ readonly spotAngle: 25;
34
+ };
35
+ /**
36
+ * Which clips are audible at composition frame `F`, with blend weights.
37
+ * Linear weights, at most two clips at once (the schema enforces spacing).
38
+ */
39
+ export declare function scheduleClips(clips: readonly AepStageClip[], F: number, fps: number): SampledClipWeight[];
40
+ /**
41
+ * Seconds to put an action at. Looping wraps; otherwise the pose holds just
42
+ * inside the last key (at exactly `duration` a repeating action wraps to the
43
+ * first pose). Same hold rule as model3d's `animationTimeSeconds`.
44
+ */
45
+ export declare function clipLocalTime(rawSeconds: number, duration: number, loop: boolean): number;
46
+ /** A member is in the scene while !hidden and inPoint <= F < outPoint. */
47
+ export declare function memberActive(layer: AepStageMemberLayer, F: number): boolean;
48
+ export interface SampledStageWorld {
49
+ lighting: SampledStageLighting;
50
+ spots: SampledSpot[];
51
+ shadowOpacity: number;
52
+ shadowSoftness: number;
53
+ focusDistance: number | null;
54
+ }
55
+ export declare function sampleStageWorld(world: AepStage3DLayer, F: number): SampledStageWorld;
56
+ export interface SampledActor3D {
57
+ id: string;
58
+ active: boolean;
59
+ x: number;
60
+ z: number;
61
+ facingDeg: number;
62
+ clips: SampledClipWeight[];
63
+ }
64
+ export declare function sampleActor3D(actor: AepActor3DLayer, F: number, fps: number): SampledActor3D;
65
+ export interface SampledProp3D {
66
+ id: string;
67
+ active: boolean;
68
+ position: Vec3;
69
+ rotationDeg: Vec3;
70
+ scale: Vec3;
71
+ }
72
+ export declare function sampleProp3D(prop: AepProp3DLayer, F: number): SampledProp3D;
73
+ /** Dirty-check key for one render: the world plus every member, in member order. */
74
+ export declare function stageFrameKey(world: SampledStageWorld, members: readonly unknown[]): string;
75
+ export {};
@@ -0,0 +1,21 @@
1
+ import { AepStage3DLayer } from '../../../types/aep';
2
+ import { StageWorld } from './buildWorld';
3
+ import { StageMemberRig } from './members/types';
4
+ export interface ResolvedStageStyle {
5
+ toon: boolean;
6
+ steps: number;
7
+ outline: {
8
+ color: string;
9
+ width: number;
10
+ } | null;
11
+ exposure: number;
12
+ }
13
+ export declare function resolveStageStyle(style: AepStage3DLayer["style"]): ResolvedStageStyle;
14
+ /**
15
+ * Applies the style to a built member. Outline width is in world metres:
16
+ * `width / worldScale` converts it to the member's local units, so a 0.012 m
17
+ * line looks the same on a tiny prop and a big actor.
18
+ */
19
+ export declare function styleMember(rig: StageMemberRig, style: ResolvedStageStyle): void;
20
+ /** Ground and wall: toon shading, never an outline. A backdrop wall stays unlit. */
21
+ export declare function styleWorldSurfaces(world: StageWorld, style: ResolvedStageStyle): void;
@@ -1,4 +1,4 @@
1
- import { AepLayer } from '../../types/aep';
1
+ import { AepLayer, AepStageMemberLayer } from '../../types/aep';
2
2
  export interface AepResolvedTransform {
3
3
  x: number;
4
4
  y: number;
@@ -12,7 +12,7 @@ export interface AepResolvedTransform {
12
12
  y: number;
13
13
  };
14
14
  }
15
- export declare function useAepLayerTransform(layer: AepLayer, intrinsicSize: {
15
+ export declare function useAepLayerTransform(layer: Exclude<AepLayer, AepStageMemberLayer>, intrinsicSize: {
16
16
  width: number;
17
17
  height: number;
18
18
  }): AepResolvedTransform;
@@ -6,3 +6,4 @@ export interface AepResolvedAssetState {
6
6
  error?: unknown;
7
7
  }
8
8
  export declare function useResolveAsset(assetId: string | undefined): AepResolvedAssetState;
9
+ export declare function useResolveAssets(assetIds: readonly string[]): Record<string, AepResolvedAssetState>;
@@ -5,6 +5,15 @@ interface AbstractContainerProps extends PixiBaseSpriteProps {
5
5
  /** Container label/id override. Defaults to `getElementName(uniqueId)`. */
6
6
  id?: string;
7
7
  sortableChildren?: boolean;
8
+ /**
9
+ * Shifts the scale/rotation pivot away from (x, y) without moving the
10
+ * content. Used by precomps so keyframed scale/rotation act about the AE
11
+ * anchor point instead of the precomp's top-left corner.
12
+ */
13
+ pivotOffset?: {
14
+ x: number;
15
+ y: number;
16
+ };
8
17
  /** Text handed to text-unit / typewriter effects (see usePixiAnimation). */
9
18
  animationText?: string;
10
19
  ignoreTlForVideo?: boolean;
@@ -6,3 +6,4 @@ export { lottieColorToHex } from './bodymovin-color';
6
6
  export { lintBodymovinJson, LottieLintError, type LintFinding, type LintReport, type LintSeverity, type LintOptions, } from './lottieLint';
7
7
  export { readPostFxExtension, readExtrusionExtension, } from './bodymovinExtensions';
8
8
  export { lintAepTransitions } from './transitionLint';
9
+ export { lintAepStage3D } from './stageLint';
@@ -0,0 +1,3 @@
1
+ import { AepCompositionJson } from '../../types/aep';
2
+ import { LintReport } from './lottieLint';
3
+ export declare const lintAepStage3D: (comp: AepCompositionJson) => LintReport;