Skip to content

Keyframer Classes

widberg edited this page Jul 4, 2023 · 46 revisions

These Keyframer classes are used extensively in objects like Animation_Z, MaterialAnim_Z, Particles_Z, and Rtc_Z. They are not themselves found as objects in BigFiles.

Interpolation Techniques

Keyframer classes with Linear in the class name use Linear interpolation to interpolate values between keyframes. Classes without Linear in the name use Cubic Bézier interpolation to interpolate values between keyframes. See the Interpolation Functions section below for more information.

Compressed

Classes with Comp (Compressed) in the name use std::int16_t values in place of float values to minimize the size of keyframes. To decompress the compressed Keyframer values, for quaternions divide the signed 16-bit integers by 2000, and for vectors divide by 4096. This yields normalized quaternions in the case of KeyframerRot_Z.

Extended

Classes with Ext (Extended) in the name seem to refer to extended functionality in the class at runtime rather than storing extra data. The only class that fits this description is KeyframerExtVec3f_Z from the WALL-E Mac debug symbols.

Classes

The class names on this page were taken from the WALL-E Mac debug symbols.

Float Keyframers

struct KeyframerFloat_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        float value;
        float tangentIn;
        float tangentOut;
     }> keyframes;
};

struct KeyframerFloatComp_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        std::int16_t value;
        std::int16_t tangentIn;
        std::int16_t tangentOut;
        std::uint16_t padding;
    }> keyframes;
};

struct KeyframerFloatLinearComp_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        std::int16_t value;
        std::uint16_t padding;
    }> keyframes;
};

Vec2f Keyframers

struct KeyframerVec2fLinear_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        Vec2f data;
    }> keyframes;
};

struct KeyframerVec2fLinearComp_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        Vec2i16 value;
    }> keyframes;
};

Vec3f Keyframers

struct KeyframerVec3f_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        Vec3f value;
        Vec3f tangentIn;
        Vec3f tangentOut;
    }> keyframes;
};

struct KeyframerVec3fComp_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        Vec3i16 value;
        Vec3i16 tangentIn;
        Vec3i16 tangentOut;
        std::uint16_t padding;
            // Always 0xFF
    }> keyframes;
};

struct KeyframerVec3fLinear_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        Vec3f value;
    }> keyframes;
};

Vec4f Keyframers

struct KeyframerVec4fLinear_Z {
    std::uint16_t flags;
    PascalArray<struct {
        float time;
        Vec4f value;
    }> keyframes;
};

Rotation Keyframer

struct KeyframerRot_Z {
    PascalArray<struct {
        float time;
        Quati16 rotation;
    }> keyframes;
};
    // Linear and Compressed despite the name

Beszier Rotation Keyframer

struct KeyframerBezierRot_Z {
    PascalArray<struct {
        float time;
        Vec3f a;
        Vec3f b;
        Vec3f c;
    }> keyframes;
};

Handle Keyframer

struct KeyframerHdl_Z {
    PascalArray<struct {
        float time;
        crc32_t crc32;
    }> keyframes;
};
    // Not interpolated

Flag Keyframer

struct KeyframerFlag_Z {
    PascalArray<struct {
        float time;
        std::uint32_t flag;
    }> keyframes;
};
    // Not interpolated

Message Keyframer

Sends Message_Zs

struct KeyframerMessage_Z {
    PascalArray<struct {
        float time;
        PascalArray<struct {
            std::uint32_t messageClass;
                // Observed values:
                //   * 12
                //   * 13
                //   * 32
                //   * 36 - Sound_Z related
            crc32_t recieverCRC32;
                // 0
                // Sound_Z crc32s
            std::uint32_t c;
                // Observed values:
                //   * 0
                //   * 15
                //   * 792146210
                //   * 1162695237
                //   * 10295924
            float parameter;
            crc32_t messageID;
        }> messages;
    }> keyframes;
};
    // Not interpolated

Interpolation Functions

The interpolation functions were revealed to me in a dream.

Linear Interpolation

The type TKey::KeyType is the "backing type" of the keyframe, for example Vec2f in the case of KeyframerVec2fLinear_Z . The argument Value is an out parameter where the keyframed value at the time fTime is stored. Key0 is the keyframe whos time is largest while still being less than fTime; likewise, Key1 is the keyframe whos time is smallest while still being greater than fTime. If there is a keyframe with a time that is equal to fTime then that keyframe's value is used without interpolation.

template <class TKey>
void LinInterp(typename TKey::KeyType& Value, const TKey& Key0,
    const TKey& Key1, Float fTime) {
    // 1 - Get the parameter of the Linear curve
    Float Time0 = Key0.GetTime();
    Float Time1 = Key1.GetTime();

    Float RangeTime = Time1 - Time0;
    Float DeltaTime = fTime - Time0;
    Float t = DeltaTime / RangeTime;

    // 2 - Get the 2 points of the Linear curve
    typename TKey::KeyType PrecValue = Key0.Get();
    typename TKey::KeyType DeltaValue = Key1.Get() - PrecValue;

    // 3 - Compute Value
    Value = PrecValue + DeltaValue * t;
}

Cubic Bezier Interpolation

The parameters of the BezierInterp function are the same as LinInterp with an additional Tgt out parameter for the tangent at time fTime to be stored. There is also an equivalent version of this function without the Tgt out parameter to save processing when the tangent is not needed.

template <class TKey>
void BezierInterp(typename TKey::KeyType& Value, typename TKey::KeyType& Tgt,
    const TKey& Key0, const TKey& Key1, Float fTime) {
    // 1 - Get the parameter of the Bezier curve
    Float fTime0 = Key0.GetTime();
    Float fTime1 = Key1.GetTime();

    Float fRangeTime = fTime1 - fTime0;
    Float fDeltaTime = fTime - fTime0;
    Float t = fDeltaTime / fRangeTime;

    // 2 - Get the 4 points of the degree3 Bezier curve
    typename TKey::KeyType Pt0, Pt1, dPt0, dPt1;
    Key0.GetValue(Pt0);
    Key0.GetTgtOut(dPt0);

    Key1.GetValue(Pt1);
    Key1.GetTgtIn(dPt1);

    // 3 - Compute a, b, c, d final Bezier curve coefficients
    typename TKey::KeyType a, b, c, d;
    a =  Pt0 * 2 - Pt1 * 2 + dPt0 + dPt1;
    b = -Pt0 * 3 + Pt1 * 3 - dPt0 * 2 - dPt1;
    c =  dPt0;
    d =  Pt0;

    // with the tangent (f'(t))
    Value = d + t * (c + t * (b + t * a));
    Tgt = c + t * (2 * b + t * 3 * a);
}

Home
FAQ

For FMTK Users and Mod Developers

Read the Docs

For FMTK Developers

Asobo BigFile Format Specification
Asobo Classes
      Animation_Z
      Binary_Z
      Bitmap_Z
      Camera_Z
      CollisionVol_Z
      Fonts_Z
      GameObj_Z
      GenWorld_Z
      GwRoad_Z
      Keyframer*_Z
      Light_Z
      LightData_Z
      Lod_Z
      LodData_Z
      Material_Z
      MaterialAnim_Z
      MaterialObj_Z
      Mesh_Z
      MeshData_Z
      Node_Z
      Omni_Z
      Particles_Z
      ParticlesData_Z
      RotShape_Z
      RotShapeData_Z
      Rtc_Z
      Skel_Z
      Skin_Z
      Sound_Z
      Spline_Z
      SplineGraph_Z
      Surface_Z
      SurfaceDatas_Z
      UserDefine_Z
      Warp_Z
      World_Z
      WorldRef_Z
Asobo File Format Idioms
Asobo CRC32
Asobo LZ Compression
Asobo Arithmetic Coding Compression
Asobo Save Game File Format Specification
Asobo Audio Formats
TotemTech/ToonTech/Zouna/ACE/BSSTech/Opal Timeline
Zouna Modding Resources
Miscellaneous

Clone this wiki locally