@vvfx/ge-ir 0.0.1-beta.7 → 0.0.1-beta.8

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 (66) hide show
  1. package/README.md +65 -27
  2. package/dist/common/coordinate-mapping.d.ts +14 -0
  3. package/dist/common/data-path.d.ts +15 -0
  4. package/dist/common/json-normalization.d.ts +3 -0
  5. package/dist/common/math.d.ts +4 -0
  6. package/dist/{passthrough.d.ts → effects-passthrough.d.ts} +3 -2
  7. package/dist/ge2ir/assemble.d.ts +4 -0
  8. package/dist/ge2ir/index.d.ts +4 -2
  9. package/dist/ge2ir/mapping.d.ts +6 -0
  10. package/dist/ge2ir/{parsers/component-parser.d.ts → parser/component.d.ts} +5 -4
  11. package/dist/ge2ir/parser/layer.d.ts +4 -0
  12. package/dist/ge2ir/{scene-reader.d.ts → parser/scene.d.ts} +2 -2
  13. package/dist/ge2ir/{parsers/timeline-parser.d.ts → parser/timeline.d.ts} +5 -3
  14. package/dist/ge2ir/{merge/merge.d.ts → post-process.d.ts} +1 -1
  15. package/dist/ge2ir/types.d.ts +4 -3
  16. package/dist/index.d.ts +7 -19
  17. package/dist/index.js +4268 -4531
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +4270 -4515
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/ir2ge/assemble.d.ts +8 -0
  22. package/dist/ir2ge/converter/animation.d.ts +5 -0
  23. package/dist/ir2ge/converter/bezier.d.ts +35 -0
  24. package/dist/ir2ge/converter/layer-strategy.d.ts +18 -0
  25. package/dist/ir2ge/converter/normalized-animation.d.ts +15 -0
  26. package/dist/ir2ge/converter/timing.d.ts +14 -0
  27. package/dist/ir2ge/{ir/layer-utils.d.ts → converter/transform.d.ts} +5 -4
  28. package/dist/ir2ge/generator/component.d.ts +9 -0
  29. package/dist/ir2ge/generator/layer.d.ts +6 -0
  30. package/dist/ir2ge/generator/timeline.d.ts +7 -0
  31. package/dist/ir2ge/index.d.ts +10 -14
  32. package/dist/ir2ge/mapping.d.ts +5 -0
  33. package/dist/ir2ge/post-process/ge-mask-remap.d.ts +2 -14
  34. package/dist/ir2ge/post-process/index.d.ts +8 -18
  35. package/dist/ir2ge/post-process/mask.d.ts +5 -18
  36. package/dist/ir2ge/post-process/merge-preserved-resources.d.ts +3 -0
  37. package/dist/ir2ge/post-process/parenting.d.ts +2 -2
  38. package/dist/ir2ge/post-process/visibility.d.ts +11 -15
  39. package/dist/ir2ge/types.d.ts +27 -18
  40. package/package.json +3 -3
  41. package/dist/ge2ir/converter.d.ts +0 -3
  42. package/dist/ge2ir/pool/pool.d.ts +0 -4
  43. package/dist/ge2ir/reverse/blend-mode.d.ts +0 -2
  44. package/dist/ge2ir/reverse/coordinate.d.ts +0 -1
  45. package/dist/ge2ir/reverse/end-behavior.d.ts +0 -3
  46. package/dist/ge2ir/reverse/timing.d.ts +0 -2
  47. package/dist/ir2ge/assembly/generator.d.ts +0 -21
  48. package/dist/ir2ge/assembly/scene-assembly.d.ts +0 -11
  49. package/dist/ir2ge/builders/animation.d.ts +0 -12
  50. package/dist/ir2ge/builders/bezier.d.ts +0 -44
  51. package/dist/ir2ge/builders/component.d.ts +0 -13
  52. package/dist/ir2ge/builders/effects.d.ts +0 -9
  53. package/dist/ir2ge/builders/layer.d.ts +0 -6
  54. package/dist/ir2ge/builders/timeline.d.ts +0 -9
  55. package/dist/ir2ge/builders/timing.d.ts +0 -17
  56. package/dist/ir2ge/ir/anchor-strategy.d.ts +0 -24
  57. package/dist/ir2ge/ir/layer-dimensions.d.ts +0 -7
  58. package/dist/ir2ge/ir/parent-link.d.ts +0 -6
  59. package/dist/ir2ge/ir/specific.d.ts +0 -12
  60. package/dist/ir2ge/utils.d.ts +0 -14
  61. package/dist/shared/coordinate.d.ts +0 -11
  62. package/dist/shared/json-value.d.ts +0 -2
  63. package/dist/shared/types.d.ts +0 -60
  64. /package/dist/ge2ir/{parsers/animation-parser.d.ts → parser/animation.d.ts} +0 -0
  65. /package/dist/ge2ir/{parsers/keyframe-parser.d.ts → parser/keyframe.d.ts} +0 -0
  66. /package/dist/ge2ir/{parsers/transform-parser.d.ts → parser/transform.d.ts} +0 -0
@@ -0,0 +1,8 @@
1
+ import { type IRComposition } from '@vvfx/animation-ir';
2
+ import type { JSONScene } from '@galacean/effects-specification';
3
+ import type { ECSCollector, GeneratedItemBinding } from './types';
4
+ /**
5
+ * Assemble a GE JSONScene from generated pools and preserved source resources.
6
+ * `duration` overrides the value derived from the IR frame bounds.
7
+ */
8
+ export declare function assembleGEScene(ir: IRComposition, collector: ECSCollector, itemBindings: GeneratedItemBinding[], duration?: number): JSONScene;
@@ -0,0 +1,5 @@
1
+ import type { IRComposition, IRLayerNode } from '@vvfx/animation-ir';
2
+ import type { ColorOverLifetime } from '@galacean/effects-specification';
3
+ import type { GEAnimationPayload, LayerGenerationContext, TransformAnimation } from '../types';
4
+ export declare function buildTransformAnimation(layer: IRLayerNode, ctx: LayerGenerationContext): TransformAnimation;
5
+ export declare function buildColorAnimation(layer: IRLayerNode, ir: IRComposition): GEAnimationPayload<ColorOverLifetime> | undefined;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Encode IR keyframes as GE BezierKeyframeValue payloads.
3
+ *
4
+ * Wire format:
5
+ * - First: [EASE_OUT(3), [t, v, out_cp_x, out_cp_y]]
6
+ * - Middle: [EASE(1), [in_cp_x, in_cp_y, t, v, out_cp_x, out_cp_y]]
7
+ * - Last: [EASE_IN(2), [in_cp_x, in_cp_y, t, v]]
8
+ *
9
+ * Time is normalized to the layer's visible frame range.
10
+ */
11
+ import type { IRAnimatedProperty, IRVec3 } from '@vvfx/animation-ir';
12
+ import { type BezierKeyframeValue } from '@galacean/effects-specification';
13
+ export interface IRToGETimeContext {
14
+ /** Layer visible start frame. */
15
+ startFrame: number;
16
+ /** Layer visible end frame. */
17
+ endFrame: number;
18
+ }
19
+ interface GEPositionAnimationData {
20
+ /** One-dimensional timing curves in BezierKeyframeValue format. */
21
+ curves: BezierKeyframeValue[][];
22
+ /** Segment endpoints as `[[startX, startY], [endX, endY]]`. */
23
+ pathPoints: [[number, number], [number, number]][];
24
+ /** Segment control offsets as `[[outX, outY], [inX, inY]]`. */
25
+ controlPoints: [[number, number], [number, number]][];
26
+ }
27
+ /** Convert a scalar property to a single GE Bezier curve. */
28
+ export declare function convertIRScalarKeyframesToGE(property: IRAnimatedProperty<number>, timeContext: IRToGETimeContext): BezierKeyframeValue[][] | undefined;
29
+ /** Convert a vector property to one GE Bezier curve per dimension. */
30
+ export declare function convertIRVectorKeyframesToGE(property: IRAnimatedProperty<IRVec3>, timeContext: IRToGETimeContext): BezierKeyframeValue[][] | undefined;
31
+ /** Convert position keyframes to GE path, control-point, and timing payloads. */
32
+ export declare function convertIRPositionKeyframesToGE(property: IRAnimatedProperty<IRVec3>, timeContext: IRToGETimeContext): GEPositionAnimationData | undefined;
33
+ /** Return whether GE's compact keyframe fields are required for this property. */
34
+ export declare function shouldUseKeyframeMode(property: IRAnimatedProperty): boolean;
35
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { IRComposition, IRLayerNode } from '@vvfx/animation-ir';
2
+ /**
3
+ * Anchor encoding strategy.
4
+ *
5
+ * - `inline-anchor` encodes the renderer anchor and compensates item position.
6
+ * - `split-null-sprite` places transforms on a null parent and visual content
7
+ * on an anchor-offset child.
8
+ * Effects passthrough data may request the source hierarchy.
9
+ */
10
+ type LayerGenerationStrategy = {
11
+ kind: 'inline-anchor';
12
+ anchorScale: [number, number];
13
+ anchorOffset: [number, number];
14
+ } | {
15
+ kind: 'split-null-sprite';
16
+ };
17
+ export declare function resolveLayerGenerationStrategy(ir: IRComposition, layer: IRLayerNode): LayerGenerationStrategy;
18
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { IRLayerNode } from '@vvfx/animation-ir';
2
+ import type { ColorOverLifetime, TransformPlayableAssetData } from '@galacean/effects-specification';
3
+ interface NormalizedAnimationContext {
4
+ width: number;
5
+ height: number;
6
+ }
7
+ type NormalizedTransformAnimation = Pick<TransformPlayableAssetData, 'positionOverLifetime' | 'rotationOverLifetime' | 'sizeOverLifetime'>;
8
+ /**
9
+ * Encode normalized IR transform channels as GE timeline payloads without
10
+ * consulting composition-specific passthrough data.
11
+ */
12
+ export declare function buildNormalizedTransformAnimation(layer: IRLayerNode, ctx: NormalizedAnimationContext): NormalizedTransformAnimation;
13
+ /** Encode normalized IR opacity as a GE color-over-lifetime payload. */
14
+ export declare function buildNormalizedColorAnimation(layer: IRLayerNode): ColorOverLifetime | undefined;
15
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { IRLayerNode } from '@vvfx/animation-ir';
2
+ /**
3
+ * Convert an IR frame range to GE delay and duration, including stretch and
4
+ * offset semantics. Degenerate durations use a minimal activation interval.
5
+ */
6
+ export declare function computeLayerTiming(layer: IRLayerNode, frameRate: number, compositionInPoint?: number): {
7
+ delay: number;
8
+ layerDuration: number;
9
+ };
10
+ /**
11
+ * Extend transform-parent lifetimes to cover independent children. GE requires
12
+ * the parent item to remain active for transform inheritance.
13
+ */
14
+ export declare function extendParentEndFrames(layers: IRLayerNode[], parentIndexSet: Set<number>): IRLayerNode[];
@@ -1,8 +1,9 @@
1
1
  import type { IRLayerNode, IRLocalBounds } from '@vvfx/animation-ir';
2
- import type { IRToGETimeContext } from '../builders/bezier';
3
- import type { LayerProcessingContext } from '../types';
4
- export { computeLayerTiming } from '../builders/timing';
5
- export declare function computeStaticPosition(layer: IRLayerNode, ctx: LayerProcessingContext, anchorOffsetX?: number, anchorOffsetY?: number): [number, number, number];
2
+ import type { IRToGETimeContext } from './bezier';
3
+ import type { LayerGenerationContext } from '../types';
4
+ export declare function getLayerLocalBounds(layer: IRLayerNode, fallback?: IRLocalBounds): IRLocalBounds;
5
+ export declare function hasIndependentParentLifetime(layer: IRLayerNode): boolean;
6
+ export declare function computeStaticPosition(layer: IRLayerNode, ctx: LayerGenerationContext, anchorOffsetX?: number, anchorOffsetY?: number): [number, number, number];
6
7
  export declare function getStaticAnchor(layer: IRLayerNode): [number, number];
7
8
  export declare function applyScalePositionAdjust(position: [number, number, number], layer: IRLayerNode, bounds: IRLocalBounds, ratio: number): [number, number, number];
8
9
  export declare function computeAnchorInfo(layer: IRLayerNode, bounds: IRLocalBounds): {
@@ -0,0 +1,9 @@
1
+ import type { IRComposition, IRLayerNode, IRShapeData } from '@vvfx/animation-ir';
2
+ import type { GeneratedComponentData, LayerGenerationContext } from '../types';
3
+ export declare function buildComponent(layer: IRLayerNode, itemId: string, anchorScaleX: number, anchorScaleY: number, ctx: LayerGenerationContext): string | undefined;
4
+ /**
5
+ * Copy a preserved GE mask to the generated component. Target references still
6
+ * use source component IDs and are remapped after generation.
7
+ */
8
+ export declare function copyPassthroughMaskToComponent(ir: IRComposition, layer: IRLayerNode, component: GeneratedComponentData): void;
9
+ export declare function buildShapeOptions(shapeData: IRShapeData, ratio: number, ctx?: LayerGenerationContext): Record<string, unknown>;
@@ -0,0 +1,6 @@
1
+ import type { IRLayerNode } from '@vvfx/animation-ir';
2
+ import type { LayerGenerationContext } from '../types';
3
+ export declare function appendNullLayer(layer: IRLayerNode, ctx: LayerGenerationContext): void;
4
+ export declare function appendPrecompLayer(layer: IRLayerNode, ctx: LayerGenerationContext): void;
5
+ export declare function appendParentLayer(layer: IRLayerNode, ctx: LayerGenerationContext): void;
6
+ export declare function appendVisualLayer(layer: IRLayerNode, ctx: LayerGenerationContext): void;
@@ -0,0 +1,7 @@
1
+ import { type EndBehavior, ItemType } from '@galacean/effects-specification';
2
+ import type { ECSCollector, TransformAnimation } from '../types';
3
+ /**
4
+ * Build binding, activation, transform, and optional color tracks for one item.
5
+ * Null and precomposition items omit the color track.
6
+ */
7
+ export declare function buildTimelineTracks(collector: ECSCollector, delay: number, duration: number, endBehavior: EndBehavior, animation: TransformAnimation, itemType: ItemType): string;
@@ -1,14 +1,10 @@
1
- export { convertIRToGE } from './assembly/generator';
2
- export type { DataPath, JSONScene } from '@galacean/effects-specification';
3
- export { readLottieSpecific } from './ir/specific';
4
- export type { LottieLayerSpecific } from './ir/specific';
5
- export { hasIndependentParentLifetime } from './ir/parent-link';
6
- export type { ECSCollector, GEDataPath, GEItem, GEPoolIndex, GERecord, GETransform } from '../shared/types';
7
- export type { ProcessedItem, TransformAnimation } from './types';
8
- export { assembleScene } from './assembly/scene-assembly';
9
- export { estimateTextWidth, roundNumber, lerp, createId, toDataPath } from './utils';
10
- export { DEFAULT_CLIP_MODE, DEFAULT_CAMERA_FOV, DEFAULT_CAMERA_Z, get2dTo3dRatio, convert2dTo3dPoint, } from '../shared/coordinate';
11
- export { irScalarKeyframesToGE, irVectorKeyframesToGE, irPositionKeyframesToGE, shouldUseKeyframeMode, } from './builders/bezier';
12
- export type { IRToGETimeContext, IRPositionGEResult } from './builders/bezier';
13
- export { buildTimelineTracks } from './builders/timeline';
14
- export { normalizeChildVisibilityByParentDelays } from './post-process/visibility';
1
+ import { type IRComposition } from '@vvfx/animation-ir';
2
+ import type { JSONScene } from '@galacean/effects-specification';
3
+ /**
4
+ * Convert an IR composition to a GE JSONScene.
5
+ *
6
+ * Effects passthrough data is used only to preserve source hierarchy, masks,
7
+ * precompositions, and animation encodings that normalized IR cannot represent.
8
+ * `duration` overrides the range derived from the IR frame bounds.
9
+ */
10
+ export declare function convertIRToGE(ir: IRComposition, duration?: number): JSONScene;
@@ -0,0 +1,5 @@
1
+ import { IRBlendMode } from '@vvfx/animation-ir';
2
+ import { ItemType } from '@galacean/effects-specification';
3
+ export declare function mapBlendModeToGE(blendMode: IRBlendMode | undefined): number | undefined;
4
+ export declare function mapLayerTypeToGETimelineType(type: string): ItemType;
5
+ export declare function mapLayerTypeToGEItemType(type: string): ItemType;
@@ -1,18 +1,6 @@
1
1
  import type { ECSCollector } from '../types';
2
2
  /**
3
- * Remap GE mask references after ge2ir round-trip.
4
- *
5
- * ge2ir carries each masked component's raw `mask` object verbatim (via
6
- * `IRLayerNode.specific.effects.mask`), but `mask.reference.id` still points at the
7
- * ORIGINAL (GE1) mask-source component id, which ir2ge has regenerated. This
8
- * pass rewrites every target's `reference.id` from the stale GE1 id to the
9
- * freshly-minted GE2 component id, using the `GEComponentId → newId` map built
10
- * during the layer walk.
11
- *
12
- * Mirrors `applyParenting`: an IR-side reference (here the stale id stored in
13
- * data) → map → regenerated id → written in place. Mask SOURCE components have
14
- * no `reference` and are skipped. Dangling references (source not regenerated —
15
- * e.g. dropped by the null+sprite merger) have their `mask` removed so the GE
16
- * runtime doesn't choke on an id that resolves to nothing.
3
+ * Remap preserved mask targets from source component IDs to regenerated IDs.
4
+ * Source masks have no reference; unresolved target masks are removed.
17
5
  */
18
6
  export declare function applyGEMaskRemap(collector: ECSCollector, GEComponentIdToNewId: Record<string, string>): void;
@@ -1,18 +1,11 @@
1
1
  import type { IRComposition } from '@vvfx/animation-ir';
2
- import type { ECSCollector, ProcessedItem } from '../types';
2
+ import type { ECSCollector, GeneratedItemBinding } from '../types';
3
3
  import { type MaskLayerLookup } from './mask';
4
- export type { MaskLayerLookup } from './mask';
5
- /**
6
- * Post-emit state populated by the unified pipeline's per-layer walk.
7
- * All fields beyond `collector` + `processedItems` are optional — each
8
- * post-process step is gated on the presence of the data it needs, not
9
- * on `ir.source`. Steps that only apply to certain sources naturally
10
- * no-op when the relevant data is absent (e.g. dsl IR has no masks).
11
- */
12
- export interface PostProcessState {
4
+ /** Generation state consumed by optional post-processing steps. */
5
+ interface PostProcessState {
13
6
  collector: ECSCollector;
14
- processedItems: ProcessedItem[];
15
- /** Per-layer lookups consumed by the shared mask post-process. */
7
+ itemBindings: GeneratedItemBinding[];
8
+ /** Per-layer lookups used during mask generation. */
16
9
  maskLookup?: MaskLayerLookup;
17
10
  layerToItemId?: Record<number, string>;
18
11
  parentIndexSet?: Set<number>;
@@ -20,12 +13,9 @@ export interface PostProcessState {
20
13
  width?: number;
21
14
  height?: number;
22
15
  frameRate?: number;
23
- /** GE1→GE2 component-id map for remapping ge2ir mask passthrough references. */
16
+ /** Source-to-generated component ID map for preserved mask references. */
24
17
  GEComponentIdToNewId?: Record<string, string>;
25
18
  }
26
- /**
27
- * Run post-emit mutations on the collector before `assembleScene`.
28
- * Order: parenting → mask → visibility. Each step is gated on whether
29
- * the pipeline supplied the required tracking state.
30
- */
19
+ /** Run ordered post-generation passes before scene assembly. */
31
20
  export declare function applyPostProcess(ir: IRComposition, state: PostProcessState): void;
21
+ export {};
@@ -1,26 +1,13 @@
1
1
  /**
2
- * Mask post-process: emits a mask shape item + component for each layer that
3
- * carries `IRMaskData`, propagating the mask reference to the layer's renderer
4
- * component or — for parent layers — to descendant renderers.
5
- *
6
- * The decision to emit (per-layer) is gated solely on `layer.mask != null`,
7
- * so any IR producer can opt in by writing the field. Currently only lottie
8
- * IR has masks; dsl IR leaves `mask` undefined and this module no-ops for it.
9
- *
10
- * The lookup callbacks let each pipeline plug in its own layer-to-emitted-id
11
- * mapping — lottie keeps `layerToItemId`/`layerToComponentId`/`parentIndexSet`
12
- * during emission, dsl tracks differently. Mask handling stays generic.
2
+ * Generate GE mask items for masked IR layers and attach references to direct
3
+ * or descendant renderer components.
13
4
  */
14
5
  import type { IRComposition } from '@vvfx/animation-ir';
15
- import type { ECSCollector, ProcessedItem } from '../types';
16
- /**
17
- * Pipeline-specific lookups consumed during mask emission. A pipeline that
18
- * never produces masks can pass stub callbacks (the iterator skips layers
19
- * without `mask`, so the callbacks are never invoked in that case).
20
- */
6
+ import type { ECSCollector, GeneratedItemBinding } from '../types';
7
+ /** Resolve IR layer indices to generated items and components. */
21
8
  export interface MaskLayerLookup {
22
9
  getItemId(layerIndex: number): string | undefined;
23
10
  getComponentId(layerIndex: number): string | undefined;
24
11
  isParentLayer(layerIndex: number): boolean;
25
12
  }
26
- export declare function applyMasks(ir: IRComposition, collector: ECSCollector, processedItems: ProcessedItem[], ratio: number, width: number, height: number, frameRate: number, lookup: MaskLayerLookup): void;
13
+ export declare function applyMasks(ir: IRComposition, collector: ECSCollector, itemBindings: GeneratedItemBinding[], ratio: number, width: number, height: number, frameRate: number, lookup: MaskLayerLookup): void;
@@ -0,0 +1,3 @@
1
+ import type { IRComposition } from '@vvfx/animation-ir';
2
+ /** Merge non-root pools retained from a source GE scene into the generated scene. */
3
+ export declare function mergePreservedResources(generated: Record<string, unknown>, ir: IRComposition): Record<string, unknown>;
@@ -1,3 +1,3 @@
1
1
  import type { IRLayerNode } from '@vvfx/animation-ir';
2
- import type { GEItem } from '../types';
3
- export declare function applyParenting(layers: IRLayerNode[], items: GEItem[], layerToItemId: Record<number, string>, ratio: number, width: number, height: number): void;
2
+ import type { GeneratedVFXItemData } from '../types';
3
+ export declare function applyParenting(layers: IRLayerNode[], items: GeneratedVFXItemData[], layerToItemId: Record<number, string>, ratio: number, width: number, height: number): void;
@@ -1,26 +1,22 @@
1
- interface ProcessedItemRef {
1
+ import type { VFXItemData } from '@galacean/effects-specification';
2
+ import type { GeneratedMiscData } from '../types';
3
+ type VisibilityItem = Pick<VFXItemData, 'id' | 'delay' | 'duration' | 'parentId'>;
4
+ interface GeneratedItemBindingRef {
2
5
  itemId: string;
3
6
  objectBindingTrackId: string;
4
7
  }
5
8
  interface NormalizeVisibilityParams {
6
- items: Record<string, unknown>[];
7
- miscs: Record<string, unknown>[];
8
- processedItems: ProcessedItemRef[];
9
+ items: VisibilityItem[];
10
+ miscs: GeneratedMiscData[];
11
+ itemBindings: GeneratedItemBindingRef[];
9
12
  /** Child item IDs whose lifetime is independent of the transform parent's window. */
10
13
  independentLifetimeChildItemIds?: Set<string>;
11
14
  roundNumber: (value: number, precision: number) => number;
12
15
  }
13
16
  /**
14
- * Normalize child visibility delays so children never appear before their parent.
15
- *
16
- * Topologically sorts items (parent-first) so by the time we process any child
17
- * its parent's delay/duration are already finalized. For children with an
18
- * independent lifetime, we instead advance the parent's delay/duration so the
19
- * child can render from its own start time (GE requires the parent to be active
20
- * for transform inheritance, but the parent-link relationship does not propagate
21
- * visibility). Only the ActivationTrack clip is updated; TransformTrack
22
- * keyframes are normalized to the original time range and would hold their
23
- * first frame value if the track started earlier.
17
+ * Normalize item lifetimes in parent-first order. Contained children are clamped
18
+ * to their parent; independent children extend the transform parent's activation
19
+ * interval. Transform keyframes retain their original time domain.
24
20
  */
25
- export declare function normalizeChildVisibilityByParentDelays({ items, miscs, processedItems, independentLifetimeChildItemIds, roundNumber, }: NormalizeVisibilityParams): void;
21
+ export declare function normalizeChildVisibilityByParentDelays({ items, miscs, itemBindings, independentLifetimeChildItemIds, roundNumber, }: NormalizeVisibilityParams): void;
26
22
  export {};
@@ -1,31 +1,40 @@
1
1
  import type { IRComposition } from '@vvfx/animation-ir';
2
- import type { DataPath } from '@galacean/effects-specification';
3
- import type { ECSCollector } from '../shared/types';
4
- export type { ECSCollector, GEDataPath, GEItem, GEPoolIndex, GERecord, GETransform } from '../shared/types';
5
- /**
6
- * Bookkeeping for a fully emitted item: its VFXItemData id and the
7
- * ObjectBindingTrack that owns its child Activation/Transform/SpriteColor
8
- * tracks. The optional `layerIndex` lets source-specific post-processing
9
- * (e.g. lottie visibility normalization) trace items back to the IR layer.
10
- */
11
- export interface ProcessedItem {
2
+ import type { ColorOverLifetime, ComponentData, DataPath, EffectsObjectData, JSONScene, PositionOverLifetime, RotationOverLifetime, SizeOverLifetime, VFXItemData } from '@galacean/effects-specification';
3
+ /** Generated item with a required transform and optional deprecated content. */
4
+ export type GeneratedVFXItemData = Omit<VFXItemData, 'content' | 'transform'> & Partial<Pick<VFXItemData, 'content'>> & Required<Pick<VFXItemData, 'transform'>>;
5
+ /** Generated component with specification fields and preserved extension data. */
6
+ export type GeneratedComponentData = ComponentData & Record<string, unknown>;
7
+ /** Generated misc object with specification fields and timeline payloads. */
8
+ export type GeneratedMiscData = EffectsObjectData & Record<string, unknown>;
9
+ /** Pools collected while building a GE JSONScene. */
10
+ export interface ECSCollector {
11
+ images: JSONScene['images'];
12
+ components: GeneratedComponentData[];
13
+ items: GeneratedVFXItemData[];
14
+ textures: NonNullable<JSONScene['textures']>;
15
+ miscs: GeneratedMiscData[];
16
+ }
17
+ /** Links a generated item and its binding track to the originating IR layer. */
18
+ export interface GeneratedItemBinding {
12
19
  itemId: string;
13
20
  objectBindingTrackId: string;
14
21
  layerIndex?: number;
15
22
  }
23
+ /** Specification-defined GE animation data or an opaque preserved payload. */
24
+ export type GEAnimationPayload<T> = T | Record<string, unknown>;
16
25
  /** Per-channel animation payload consumed by the timeline tracks. */
17
26
  export interface TransformAnimation {
18
- positionOverLifetime?: Record<string, unknown> | null;
19
- rotationOverLifetime?: Record<string, unknown> | null;
20
- sizeOverLifetime?: Record<string, unknown> | null;
21
- colorOverLifetime?: Record<string, unknown> | null;
27
+ positionOverLifetime?: GEAnimationPayload<PositionOverLifetime>;
28
+ rotationOverLifetime?: GEAnimationPayload<RotationOverLifetime>;
29
+ sizeOverLifetime?: GEAnimationPayload<SizeOverLifetime>;
30
+ colorOverLifetime?: GEAnimationPayload<ColorOverLifetime>;
22
31
  }
23
- /** Per-layer context threaded through the unified layer processors. */
24
- export interface LayerProcessingContext {
25
- /** Full IR composition; needed for normalized semantics and guarded fidelity payloads. */
32
+ /** Shared context for layer generation. */
33
+ export interface LayerGenerationContext {
34
+ /** IR composition used for normalized semantics and source-fidelity data. */
26
35
  ir: IRComposition;
27
36
  collector: ECSCollector;
28
- processedItems: ProcessedItem[];
37
+ itemBindings: GeneratedItemBinding[];
29
38
  layerToItemId: Record<number, string>;
30
39
  layerToComponentId: Record<number, string>;
31
40
  textureCache: Map<string, DataPath>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vvfx/ge-ir",
3
- "version": "0.0.1-beta.7",
3
+ "version": "0.0.1-beta.8",
4
4
  "description": "Galacean Effects and animation IR bidirectional conversion package",
5
5
  "module": "./dist/index.mjs",
6
6
  "main": "./dist/index.js",
@@ -16,9 +16,9 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@galacean/effects-specification": "^2.8.0",
19
+ "@galacean/effects-specification": "2.7.2",
20
20
  "uuid": "^13.0.0",
21
- "@vvfx/animation-ir": "0.0.1-beta.7"
21
+ "@vvfx/animation-ir": "0.0.1-beta.8"
22
22
  },
23
23
  "contributors": [
24
24
  {
@@ -1,3 +0,0 @@
1
- import type { IRComposition } from '@vvfx/animation-ir';
2
- import type { GE2IROptions } from './types';
3
- export declare function convertGEToIR(scene: Record<string, unknown>, options: GE2IROptions): IRComposition;
@@ -1,4 +0,0 @@
1
- import type { GEPoolIndex, GERecord } from '../../shared/types';
2
- export declare function buildPoolIndex(pool: GERecord[] | undefined): GEPoolIndex;
3
- export declare function resolveDataPath(pool: GEPoolIndex, ref: unknown): GERecord | undefined;
4
- export declare function resolveDataPathId(ref: unknown): string | undefined;
@@ -1,2 +0,0 @@
1
- import type { IRBlendMode as IRBlendModeType } from '@vvfx/animation-ir';
2
- export declare function reverseBlendMode(GECode: number | undefined): IRBlendModeType | undefined;
@@ -1 +0,0 @@
1
- export declare function convert3dTo2dPoint(x: number, y: number, z: number, width: number, height: number): [number, number, number];
@@ -1,3 +0,0 @@
1
- import type { IREndBehavior as IREndBehaviorType } from '@vvfx/animation-ir';
2
- export declare function reverseEndBehavior(GEBehavior: number | undefined): IREndBehaviorType | undefined;
3
- export declare function reverseCompositionEndBehavior(GEBehavior: number | undefined): IREndBehaviorType | undefined;
@@ -1,2 +0,0 @@
1
- import type { IRTimeContext } from '@vvfx/animation-ir';
2
- export declare function reverseLayerTiming(delay: number, duration: number, frameRate: number): IRTimeContext;
@@ -1,21 +0,0 @@
1
- /**
2
- * Unified IR → GE scene generation pipeline. All IR sources (lottie, dsl,
3
- * future) are processed here. Normalized animation semantics select the GE
4
- * lowering plan; source-specific payloads are consulted only for fidelity
5
- * restoration such as GE hierarchy, mask and precomp graphs.
6
- */
7
- import { type IRComposition } from '@vvfx/animation-ir';
8
- import type { JSONScene } from '@galacean/effects-specification';
9
- /**
10
- * Convert an IR composition to a GE JSONScene.
11
- *
12
- * All IR sources (lottie, dsl, future) go through this single unified
13
- * pipeline. Normalized animation semantics select the GE lowering plan;
14
- * source-specific payloads may preserve authored GE hierarchy or restore
15
- * mask and precomp graphs.
16
- *
17
- * The optional `duration` arg is a caller override; lottie2ge currently passes
18
- * the duration computed from the raw json upstream. When omitted, the
19
- * canonical assembler derives it from `(outPoint - inPoint) / frameRate`.
20
- */
21
- export declare function convertIRToGE(ir: IRComposition, duration?: number): JSONScene;
@@ -1,11 +0,0 @@
1
- import { type IRComposition } from '@vvfx/animation-ir';
2
- import { type JSONScene } from '@galacean/effects-specification';
3
- import type { ECSCollector, ProcessedItem } from '../types';
4
- /**
5
- * Assemble the top-level GE JSONScene wrapper from a populated collector.
6
- *
7
- * Reads composition-level properties (`name`, `width`/`height`, `endBehavior`,
8
- * `backgroundColor`) directly from the IR. The optional `duration` arg is a
9
- * caller override — when omitted, derived from `(outPoint - inPoint) / frameRate`.
10
- */
11
- export declare function assembleScene(ir: IRComposition, collector: ECSCollector, processedItems: ProcessedItem[], duration?: number): JSONScene;
@@ -1,12 +0,0 @@
1
- import type { IRComposition, IRLayerNode } from '@vvfx/animation-ir';
2
- import type { LayerProcessingContext, TransformAnimation } from '../types';
3
- export declare function buildTransformAnimation(layer: IRLayerNode, ctx: LayerProcessingContext): TransformAnimation;
4
- /**
5
- * Encode normalized IR transform channels as GE timeline payloads without
6
- * consulting composition-specific passthrough data. Sibling converters use
7
- * this when they need the canonical curve encoding for a preserved sub-scene.
8
- */
9
- export declare function buildNormalizedTransformAnimation(layer: IRLayerNode, ctx: Pick<LayerProcessingContext, 'width' | 'height'>): TransformAnimation;
10
- export declare function buildColorAnimation(layer: IRLayerNode, ir: IRComposition): Record<string, unknown> | undefined;
11
- /** Encode normalized IR opacity as a GE color-over-lifetime payload. */
12
- export declare function buildNormalizedColorAnimation(layer: IRLayerNode): Record<string, unknown> | undefined;
@@ -1,44 +0,0 @@
1
- /**
2
- * Converts IR keyframe-based animation data to GE BezierKeyframeValue format.
3
- *
4
- * GE BezierKeyframeValue format per keyframe:
5
- * - First: [EASE_OUT(3), [t, v, out_cp_x, out_cp_y]]
6
- * - Middle: [EASE(1), [in_cp_x, in_cp_y, t, v, out_cp_x, out_cp_y]]
7
- * - Last: [EASE_IN(2), [in_cp_x, in_cp_y, t, v]]
8
- *
9
- * Time is normalized to [0, 1] based on the layer's visible frame range (ip → op).
10
- */
11
- import type { IRAnimatedProperty, IRVec3 } from '@vvfx/animation-ir';
12
- import { type BezierKeyframeValue } from '@galacean/effects-specification';
13
- export interface IRToGETimeContext {
14
- /** Layer visible start frame. */
15
- startFrame: number;
16
- /** Layer visible end frame. */
17
- endFrame: number;
18
- }
19
- export interface IRPositionGEResult {
20
- /** Timing curves in BezierKeyframeValue format (1D, time-domain only). */
21
- curves: BezierKeyframeValue[][];
22
- /** Path points per segment: [[start_x, start_y], [end_x, end_y]]. */
23
- pathPoints: [[number, number], [number, number]][];
24
- /** Spatial control points per segment: [[to_x, to_y], [ti_x, ti_y]]. */
25
- controlPoints: [[number, number], [number, number]][];
26
- }
27
- /**
28
- * Convert a 1D animated property (opacity / rotation) to GE BezierKeyframeValue[][].
29
- * Returns a single-element outer array with the full curve.
30
- */
31
- export declare function irScalarKeyframesToGE(property: IRAnimatedProperty<number>, timeContext: IRToGETimeContext): BezierKeyframeValue[][] | undefined;
32
- /**
33
- * Convert a multi-dimensional animated property (scale / anchor) to GE BezierKeyframeValue[][].
34
- * Returns one curve per dimension in the outer array.
35
- */
36
- export declare function irVectorKeyframesToGE(property: IRAnimatedProperty<IRVec3>, timeContext: IRToGETimeContext): BezierKeyframeValue[][] | undefined;
37
- /**
38
- * Convert position keyframes to GE path animation format (pp/cp + timing curves).
39
- */
40
- export declare function irPositionKeyframesToGE(property: IRAnimatedProperty<IRVec3>, timeContext: IRToGETimeContext): IRPositionGEResult | undefined;
41
- /**
42
- * Determine if a property has enough keyframes to warrant keyframe mode (pkf/skf/rkf/okf).
43
- */
44
- export declare function shouldUseKeyframeMode(property: IRAnimatedProperty): boolean;
@@ -1,13 +0,0 @@
1
- import type { IRComposition, IRLayerNode, IRShapeData } from '@vvfx/animation-ir';
2
- import type { LayerProcessingContext } from '../types';
3
- export declare function buildComponent(layer: IRLayerNode, itemId: string, anchorScaleX: number, anchorScaleY: number, ctx: LayerProcessingContext): string | undefined;
4
- /**
5
- * Copy the raw GE mask object (from specific.effects passthrough) onto a freshly
6
- * built component, as a top-level `mask` field matching GE's structure. For a
7
- * mask SOURCE this carries `{isMask:true, alphaMaskEnabled}`; for a TARGET it
8
- * carries `{isMask:false, reference, inverted}` where `reference.id` is still
9
- * the stale GE1 component id — `applyGEMaskRemap` rewrites it in post-process.
10
- * No-op for non-GE sources (Lottie masks go through the IRLayerNode.mask path).
11
- */
12
- export declare function applyGEMask(ir: IRComposition, layer: IRLayerNode, component: Record<string, unknown>): void;
13
- export declare function buildShapeOptions(shapeData: IRShapeData, ratio: number, ctx?: LayerProcessingContext): Record<string, unknown>;
@@ -1,9 +0,0 @@
1
- import { type IRBlendMode } from '@vvfx/animation-ir';
2
- import type { DataPath } from '@galacean/effects-specification';
3
- import type { ECSCollector, GETransform } from '../types';
4
- export { estimateTextWidth } from '../utils';
5
- export declare function buildGETransform(position: [number, number, number], eulerHint: [number, number, number], scale: [number, number, number]): GETransform;
6
- export declare function getGEItemType(type: string): string;
7
- export declare function getGEItemTypeCode(type: string): string;
8
- export declare function registerTexture(collector: ECSCollector, imageUrl: string, cache: Map<string, DataPath>): DataPath;
9
- export declare function mapBlendingMode(blendMode: IRBlendMode | undefined): number | undefined;
@@ -1,6 +0,0 @@
1
- import type { IRLayerNode } from '@vvfx/animation-ir';
2
- import type { LayerProcessingContext } from '../types';
3
- export declare function processNullLayer(layer: IRLayerNode, ctx: LayerProcessingContext): void;
4
- export declare function processPrecompLayer(layer: IRLayerNode, ctx: LayerProcessingContext): void;
5
- export declare function processParentLayer(layer: IRLayerNode, ctx: LayerProcessingContext): void;
6
- export declare function processVisualLayer(layer: IRLayerNode, ctx: LayerProcessingContext): void;
@@ -1,9 +0,0 @@
1
- import type { ECSCollector, TransformAnimation } from '../types';
2
- /**
3
- * Build the ObjectBindingTrack + Activation/Transform/SpriteColor child tracks
4
- * for one VFX item. Shared by lottie2ge and dsl2ge generators.
5
- *
6
- * The SpriteColor track is omitted for null layers (itemType `'null'` or
7
- * the GE numeric code `'3'`).
8
- */
9
- export declare function buildTimelineTracks(collector: ECSCollector, delay: number, duration: number, endBehavior: number, animation: TransformAnimation, itemType: string): string;
@@ -1,17 +0,0 @@
1
- import type { IRLayerNode } from '@vvfx/animation-ir';
2
- /**
3
- * Map an IR layer's time range to GE delay/duration in seconds, applying
4
- * the time-stretch and offset semantics from `IRTimeContext`.
5
- *
6
- * dsl-source IRs leave `stretch` and `offsetFrame` undefined, in which case
7
- * this collapses to `delay = (startFrame - compositionInPoint) / fr` and
8
- * `duration = (endFrame - startFrame) / fr` — exactly what dsl2ge used to
9
- * compute inline.
10
- *
11
- * Zero/negative durations are clamped to a 0.0001 epsilon so GE keeps the
12
- * activation track alive for the (degenerate) layer.
13
- */
14
- export declare function computeLayerTiming(layer: IRLayerNode, frameRate: number, compositionInPoint?: number): {
15
- delay: number;
16
- layerDuration: number;
17
- };