Skip to content

Commit 644bebf

Browse files
committed
Add matrix and decomposed transforms to baked plugin export frames
1 parent feeb236 commit 644bebf

2 files changed

Lines changed: 190 additions & 97 deletions

File tree

schemas/plugin-blueprint.schema.json

Lines changed: 160 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,26 @@
680680
"type": "object",
681681
"default": {},
682682
"properties": {
683+
"matrix": {
684+
"type": "object",
685+
"default": {},
686+
"description": "A collection of baked transformation matrix keyframes, identified by a floating-point timestamp.",
687+
"patternProperties": {
688+
"^\\d+\\.\\d+$": {
689+
"$ref": "#/definitions/matrix_keyframe"
690+
}
691+
}
692+
},
693+
"decomposed": {
694+
"type": "object",
695+
"default": {},
696+
"description": "A collection of baked decomposed transformation keyframes, identified by a floating-point timestamp.",
697+
"patternProperties": {
698+
"^\\d+\\.\\d+$": {
699+
"$ref": "#/definitions/decomposed_keyframe"
700+
}
701+
}
702+
},
683703
"position": {
684704
"type": "object",
685705
"default": {},
@@ -762,110 +782,153 @@
762782
"$ref": "#/definitions/molang_vector3"
763783
},
764784
"interpolation": {
785+
"$ref": "#/definitions/keyframe_interpolation"
786+
}
787+
}
788+
},
789+
"matrix_keyframe": {
790+
"type": "object",
791+
"required": ["value", "interpolation"],
792+
"description": "A baked transformation matrix keyframe, identified by a floating-point timestamp.",
793+
"properties": {
794+
"value": {
795+
"$ref": "#/definitions/matrix"
796+
},
797+
"interpolation": {
798+
"$ref": "#/definitions/keyframe_interpolation"
799+
}
800+
}
801+
},
802+
"decomposed_keyframe": {
803+
"type": "object",
804+
"required": ["value", "interpolation"],
805+
"description": "A baked decomposed transformation keyframe, identified by a floating-point timestamp.",
806+
"properties": {
807+
"value": {
765808
"type": "object",
766-
"oneOf": [
767-
{
768-
"type": "object",
769-
"required": ["type", "easing"],
770-
"properties": {
771-
"type": {
772-
"const": "linear"
773-
},
774-
"easing": {
775-
"type": "string",
776-
"enum": [
777-
"linear",
778-
"step",
779-
"ease_in_quad",
780-
"ease_out_quad",
781-
"ease_in_out_quad",
782-
"ease_in_cubic",
783-
"ease_out_cubic",
784-
"ease_in_out_cubic",
785-
"ease_in_quart",
786-
"ease_out_quart",
787-
"ease_in_out_quart",
788-
"ease_in_quint",
789-
"ease_out_quint",
790-
"ease_in_out_quint",
791-
"ease_in_sine",
792-
"ease_out_sine",
793-
"ease_in_out_sine",
794-
"ease_in_expo",
795-
"ease_out_expo",
796-
"ease_in_out_expo",
797-
"ease_in_circ",
798-
"ease_out_circ",
799-
"ease_in_out_circ",
800-
"ease_in_back",
801-
"ease_out_back",
802-
"ease_in_out_back",
803-
"ease_in_elastic",
804-
"ease_out_elastic",
805-
"ease_in_out_elastic",
806-
"ease_in_bounce",
807-
"ease_out_bounce",
808-
"ease_in_out_bounce"
809-
]
810-
},
811-
"easing_arguments": {
812-
"type": "array",
813-
"items": {
814-
"type": "number"
815-
},
816-
"default": []
817-
}
818-
}
819-
},
820-
{
821-
"type": "object",
822-
"required": [
823-
"type",
824-
"left_handle_time",
825-
"left_handle_value",
826-
"right_handle_time",
827-
"right_handle_value"
828-
],
829-
"properties": {
830-
"type": {
831-
"const": "bezier"
832-
},
833-
"left_handle_time": {
834-
"$ref": "#/definitions/vector3"
835-
},
836-
"left_handle_value": {
837-
"$ref": "#/definitions/vector3"
838-
},
839-
"right_handle_time": {
840-
"$ref": "#/definitions/vector3"
841-
},
842-
"right_handle_value": {
843-
"$ref": "#/definitions/vector3"
844-
}
845-
}
809+
"properties": {
810+
"translation": {
811+
"$ref": "#/definitions/vector3",
812+
"default": [0.0, 0.0, 0.0]
846813
},
847-
{
848-
"type": "object",
849-
"required": ["type"],
850-
"properties": {
851-
"type": {
852-
"const": "catmullrom"
853-
}
854-
}
814+
"left_rotation": {
815+
"$ref": "#/definitions/vector4",
816+
"default": [0.0, 0.0, 0.0, 1.0]
855817
},
856-
{
857-
"type": "object",
858-
"required": ["type"],
859-
"properties": {
860-
"type": {
861-
"const": "step"
862-
}
863-
}
818+
"scale": {
819+
"$ref": "#/definitions/vector3",
820+
"default": [1.0, 1.0, 1.0]
864821
}
865-
]
822+
}
823+
},
824+
"interpolation": {
825+
"$ref": "#/definitions/keyframe_interpolation"
866826
}
867827
}
868828
},
829+
"keyframe_interpolation": {
830+
"type": "object",
831+
"oneOf": [
832+
{
833+
"type": "object",
834+
"required": ["type", "easing"],
835+
"properties": {
836+
"type": {
837+
"const": "linear"
838+
},
839+
"easing": {
840+
"type": "string",
841+
"enum": [
842+
"linear",
843+
"step",
844+
"ease_in_quad",
845+
"ease_out_quad",
846+
"ease_in_out_quad",
847+
"ease_in_cubic",
848+
"ease_out_cubic",
849+
"ease_in_out_cubic",
850+
"ease_in_quart",
851+
"ease_out_quart",
852+
"ease_in_out_quart",
853+
"ease_in_quint",
854+
"ease_out_quint",
855+
"ease_in_out_quint",
856+
"ease_in_sine",
857+
"ease_out_sine",
858+
"ease_in_out_sine",
859+
"ease_in_expo",
860+
"ease_out_expo",
861+
"ease_in_out_expo",
862+
"ease_in_circ",
863+
"ease_out_circ",
864+
"ease_in_out_circ",
865+
"ease_in_back",
866+
"ease_out_back",
867+
"ease_in_out_back",
868+
"ease_in_elastic",
869+
"ease_out_elastic",
870+
"ease_in_out_elastic",
871+
"ease_in_bounce",
872+
"ease_out_bounce",
873+
"ease_in_out_bounce"
874+
]
875+
},
876+
"easing_arguments": {
877+
"type": "array",
878+
"items": {
879+
"type": "number"
880+
},
881+
"default": []
882+
}
883+
}
884+
},
885+
{
886+
"type": "object",
887+
"required": [
888+
"type",
889+
"left_handle_time",
890+
"left_handle_value",
891+
"right_handle_time",
892+
"right_handle_value"
893+
],
894+
"properties": {
895+
"type": {
896+
"const": "bezier"
897+
},
898+
"left_handle_time": {
899+
"$ref": "#/definitions/vector3"
900+
},
901+
"left_handle_value": {
902+
"$ref": "#/definitions/vector3"
903+
},
904+
"right_handle_time": {
905+
"$ref": "#/definitions/vector3"
906+
},
907+
"right_handle_value": {
908+
"$ref": "#/definitions/vector3"
909+
}
910+
}
911+
},
912+
{
913+
"type": "object",
914+
"required": ["type"],
915+
"properties": {
916+
"type": {
917+
"const": "catmullrom"
918+
}
919+
}
920+
},
921+
{
922+
"type": "object",
923+
"required": ["type"],
924+
"properties": {
925+
"type": {
926+
"const": "step"
927+
}
928+
}
929+
}
930+
]
931+
},
869932
"resource_location": {
870933
"type": "string",
871934
"pattern": "^[a-z0-9_\\-]+:[a-z0-9_\\-./]+$",

src/systems/pluginCompiler.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,20 @@ interface TransformationKeyframe {
150150
interpolation: TransformationKeyframeInterpolation
151151
}
152152

153+
interface MatrixKeyframe {
154+
value: number[]
155+
interpolation: TransformationKeyframeInterpolation
156+
}
157+
158+
interface DecomposedKeyframe {
159+
value: {
160+
translation: ArrayVector3
161+
left_rotation: ArrayVector4
162+
scale: ArrayVector3
163+
}
164+
interpolation: TransformationKeyframeInterpolation
165+
}
166+
153167
interface PluginAnimation {
154168
loop_mode: LoopMode
155169
length: number
@@ -162,6 +176,8 @@ interface PluginAnimation {
162176
node_keyframes?: Record<
163177
string,
164178
{
179+
matrix?: Record<string, MatrixKeyframe>
180+
decomposed?: Record<string, DecomposedKeyframe>
165181
position?: Record<string, TransformationKeyframe>
166182
rotation?: Record<string, TransformationKeyframe>
167183
scale?: Record<string, TransformationKeyframe>
@@ -637,10 +653,24 @@ function serializeBakedAnimation(options: {
637653
: { type: 'linear', easing: 'linear' }
638654

639655
const channels = (node_keyframes[nodeId] ??= {})
656+
const matrix = (channels.matrix ??= {})
657+
const decomposed = (channels.decomposed ??= {})
640658
const position = (channels.position ??= {})
641659
const rotation = (channels.rotation ??= {})
642660
const scale = (channels.scale ??= {})
643661

662+
matrix[timeKey] = {
663+
value: transform.matrix.elements.slice(),
664+
interpolation,
665+
}
666+
decomposed[timeKey] = {
667+
value: {
668+
translation: transform.decomposed.translation.toArray() as ArrayVector3,
669+
left_rotation: transform.decomposed.left_rotation.toArray() as ArrayVector4,
670+
scale: transform.decomposed.scale.toArray() as ArrayVector3,
671+
},
672+
interpolation,
673+
}
644674
position[timeKey] = {
645675
value: transform.pos.map(toMolangNumber) as StringVector3,
646676
interpolation,

0 commit comments

Comments
 (0)