Last active
June 13, 2017 08:00
-
-
Save williewillus/2f02eb0fe2849657623111706bedebb6 to your computer and use it in GitHub Desktop.
animation api grokking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
- Properties.StaticProperty (PropertyBool) | |
- when true, show the static parts of the model (the non animated ones) | |
- when false, show the animated parts | |
- Properties.AnimationProperty (IUnlistedProperty<IModelState>) | |
- The model is animated by rebaking it using the value of this property | |
What is a joint? | |
- basically, part of a model that you'd like to treat as 1 single unit for animation purposes | |
What is a clip? | |
- in short, (joint -> (float -> model transform)). the float -> model transform is the important part | |
What is an ITimeValue | |
- function (float -> float) | |
- can be specified from json (where they are called parameters), or bound to code objects | |
- not necessarily time! though the very first input to the system is the world time, with partial ticks | |
*/ | |
animation state machine json (IAnimationStateMachine): | |
{ | |
"parameters": { "name": <time_value>, ... }, // specify any ITimeValue's to be used by clips. any unbound time values used in this json must be provided by code loading the ASM | |
"clips": { "<clip_name>": <clip>, ... }, | |
"states": [ "<clip_name>", ... ], | |
"transitions": { "<clip_name>": "<clip_name>", ... }, | |
"start_state": "<clip_name>" | |
} | |
<time_value> ::= | |
<number> // result = number; Constant value. | |
"#identity" // result = input; Value that returns its input. | |
"#name" // result = name(input); Reference to another value defined in "parameters" block. | |
[ "compose" <time_value> <time_value> ] // result = value1(value2(input)); Value composition. | |
[ regex("[+\\-*/mMrRfF]+"), <time_value>* ] // Simple arithmetic operation, see below. | |
// example: [ "+*-", <foo>, <bar>, <baz> ]: (((input + foo) * bar) - baz) | |
<clip> ::= | |
"#identity" // Identity clip, does nothing to the model. | |
"#name" // Reference to another clip defined in "clips" block. | |
"domain:model#variant@clip" // reference to a clip loaded by the model loader. Variant is optional. | |
[ "apply", <clip>, <time_value> ] // call clip, but instead of passing the input directly in, run it through time_value first. clip(time_value(input)) | |
[ "slerp", <clip_from>, <clip_to>, <time_value_input>, <time_value_progress> ] // spherical linear blend between 2 clips; result = (1 - progress) * clip_from(input) + progress * clip_to(input). | |
// calls the clips foo and bar, but slerping the TRSRTransformation returned by the two using the ITimeValue tv_progress. Input is run through the ITimeValue tv_input before calling. | |
[ "trigger_positive", <clip>, <time_value>, "name" ] // clip that fires an additional event when specified time_value switches from negative to positive. | |
Simple arithmetic operation time value expects 1 time value for each character in the operand string, | |
and applies operands in order to the input value. | |
Arithmetic operations: | |
"+": output = input + arg; | |
"-": output = input - arg; | |
"*": output = input * arg; | |
"/": output = input / arg; | |
"m": output = min(input, arg); | |
"M": output = max(input, arg); | |
"r": output = floor(input / arg) * arg; | |
"R": output = ceil(input / arg) * arg; | |
"f": output = input - floor(input / arg) * arg; // <- this one's modulus!! | |
"F": output = ceil(input / arg) * arg - input; | |
how are clips defined on json models? (armature file): | |
{ | |
// break this model down into joints | |
"joints": { | |
"<joint_name>": { | |
// key: index into elements array in model json | |
// value: floats? meaning unknown | |
"0": [ 1.0 ], | |
"1": [ 1.0 ], | |
... | |
} | |
}, | |
// clips of this model overall. this is the outer layer of (joint -> (float -> model transform)) described in "what is a clip?" above | |
"clips": { | |
"<clip_name>": { | |
"loop": <bool>, // should the clip automatically restart from the beginning when it reaches the end (?) | |
// clips for individual joints within this model clip | |
"joint_clips": { | |
"<joint_name>": [ | |
// each element in this array defines a (float -> model transform) | |
// the transforms are interpolated independently, then added together to form one TRSR to put in AnimationProperty | |
{ | |
"variable": "offset_[xyz]"|"axis_[xyz]"|"angle"|"scale"|"scale_[xyz]", // the thing to transform. this maps to the respective part of TRSR | |
"type": "uniform", // only option at the moment | |
"interpolation": "linear"|"nearest", // interpolation style | |
"samples": [ <float>... ] | |
// array of samples. we will scale the input time to this clip to the array length then use it as an index | |
// this implies the input time should be a value between 0 and 1, set that up in your asm json appropriately | |
// if the scaled value is "in between" two of the samples then we interpolate between the two using the style above | |
// these samples are the direct input to "variable". as in offset_x with sample 0.5 means "offset this joint 0.5 east" | |
}, | |
... | |
] | |
}, | |
"events": { | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment