75 if (m_unk0x04 !=
NULL) {
80 if (m_unk0x0c !=
NULL) {
85 if (m_unk0x14 !=
NULL) {
98 if ((result = p_storage->
Write(&m_unk0x00,
sizeof(m_unk0x00))) !=
SUCCESS) {
101 if (m_unk0x00 != 0) {
102 for (i = 0; i < m_unk0x00; i++) {
103 if ((result = m_unk0x04[i].
Write(p_storage)) !=
SUCCESS) {
109 if ((result = p_storage->
Write(&m_unk0x08,
sizeof(m_unk0x08))) !=
SUCCESS) {
112 if (m_unk0x08 != 0) {
113 for (i = 0; i < m_unk0x08; i++) {
114 if ((result = m_unk0x0c[i].
Write(p_storage)) !=
SUCCESS) {
120 if ((result = p_storage->
Write(&m_unk0x10,
sizeof(m_unk0x10))) !=
SUCCESS) {
123 if (m_unk0x10 != 0) {
124 for (i = 0; i < m_unk0x10; i++) {
125 if ((result = m_unk0x14[i].
Write(p_storage)) !=
SUCCESS) {
140 if ((result = p_storage->
Read(&m_unk0x00,
sizeof(m_unk0x00))) !=
SUCCESS) {
143 if (m_unk0x00 != 0) {
145 for (i = 0; i < m_unk0x00; i++) {
146 if ((result = m_unk0x04[i].
Read(p_storage)) !=
SUCCESS) {
152 if ((result = p_storage->
Read(&m_unk0x08,
sizeof(m_unk0x08))) !=
SUCCESS) {
155 if (m_unk0x08 != 0) {
157 for (i = 0; i < m_unk0x08; i++) {
158 if ((result = m_unk0x0c[i].
Read(p_storage)) !=
SUCCESS) {
164 if ((result = p_storage->
Read(&m_unk0x10,
sizeof(m_unk0x10))) !=
SUCCESS) {
167 if (m_unk0x10 != 0) {
169 for (i = 0; i < m_unk0x10; i++) {
170 if ((result = m_unk0x14[i].
Read(p_storage)) !=
SUCCESS) {
179 if (m_unk0x04 !=
NULL) {
185 if (m_unk0x0c !=
NULL) {
191 if (m_unk0x14 !=
NULL) {
217 if (m_unk0x08 != 0) {
225 if (m_unk0x00 != 0) {
240 localcc = p_matrix[3];
241 localcc += localb0[3];
243 p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = localb0[3][0] = localb0[3][1] = localb0[3][2] = 0;
245 if (m_unk0x10 != 0) {
257 p_matrix.
RotateZ(m_unk0x14[locald8].GetZ());
264 m_unk0x14[locald8].GetZ(),
265 m_unk0x14[locald8 + 1],
266 m_unk0x14[locald8 + 1].GetZ()
268 p_matrix.
RotateZ(m_unk0x14[locald8].GetZ());
275 p_matrix[3][0] = localcc[0];
276 p_matrix[3][1] = localcc[1];
277 p_matrix[3][2] = localcc[2];
298 if ((result = p_storage->
Read(&timeAndFlags,
sizeof(timeAndFlags))) !=
SUCCESS) {
303 m_time = timeAndFlags & 0xffffff;
314 if ((result = p_storage->
Write(&timeAndFlags,
sizeof(timeAndFlags))) !=
SUCCESS) {
350 if (
m_x > 1e-05F || m_x < -1e-05F || m_y > 1e-05F || m_y < -1e-05F || m_z > 1e-05F ||
m_z < -1e-05F) {
482 if (
m_x > 1.00001 || m_x < 0.99999 || m_y > 1.00001 || m_y < 0.99999 || m_z > 1.00001 ||
m_z < 0.99999) {
563 if ((result = p_storage->
Read(&length,
sizeof(length))) !=
SUCCESS) {
660 if ((result = p_storage->
Write(&length,
sizeof(length))) !=
SUCCESS) {
777 p_numTranslationKeys & USHRT_MAX,
779 sizeof(*p_translationKeys),
788 if (!p_translationKeys[i].TestBit1()) {
792 x = p_translationKeys[i].
GetX();
793 y = p_translationKeys[i].
GetY();
794 z = p_translationKeys[i].
GetZ();
797 if (!p_translationKeys[i].TestBit1() && !p_translationKeys[i + 1].TestBit1()) {
803 p_translationKeys[i],
804 p_translationKeys[i].GetX(),
805 p_translationKeys[i + 1],
806 p_translationKeys[i + 1].GetX()
810 p_translationKeys[i],
811 p_translationKeys[i].GetY(),
812 p_translationKeys[i + 1],
813 p_translationKeys[i + 1].GetY()
817 p_translationKeys[i],
818 p_translationKeys[i].GetZ(),
819 p_translationKeys[i + 1],
820 p_translationKeys[i + 1].GetZ()
838 n =
FindKeys(p_time, p_numRotationKeys & USHRT_MAX, p_rotationKeys,
sizeof(*p_rotationKeys), i, p_old_index);
844 if (p_rotationKeys[i].TestBit1()) {
846 p_rotationKeys[i].GetX(),
847 p_rotationKeys[i].GetY(),
848 p_rotationKeys[i].GetZ(),
849 p_rotationKeys[i].GetAngle()
857 if (p_rotationKeys[i].TestBit1() || p_rotationKeys[i + 1].TestBit1()) {
858 a[0] = p_rotationKeys[i].
GetX();
859 a[1] = p_rotationKeys[i].
GetY();
860 a[2] = p_rotationKeys[i].
GetZ();
861 a[3] = p_rotationKeys[i].
GetAngle();
863 if (p_rotationKeys[i + 1].TestBit3()) {
869 if (p_rotationKeys[i + 1].TestBit2()) {
870 c[0] = -p_rotationKeys[i + 1].
GetX();
871 c[1] = -p_rotationKeys[i + 1].
GetY();
872 c[2] = -p_rotationKeys[i + 1].
GetZ();
873 c[3] = -p_rotationKeys[i + 1].
GetAngle();
876 c[0] = p_rotationKeys[i + 1].
GetX();
877 c[1] = p_rotationKeys[i + 1].
GetY();
878 c[2] = p_rotationKeys[i + 1].
GetZ();
879 c[3] = p_rotationKeys[i + 1].
GetAngle();
886 (p_time - p_rotationKeys[i].GetTime()) / (p_rotationKeys[i + 1].GetTime() - p_rotationKeys[i].GetTime())
902 n =
FindKeys(p_time, p_numScaleKeys & USHRT_MAX, p_scaleKeys,
sizeof(*p_scaleKeys), i, p_old_index);
908 x = p_scaleKeys[i].
GetX();
909 y = p_scaleKeys[i].
GetY();
910 z = p_scaleKeys[i].
GetZ();
913 x =
Interpolate(p_time, p_scaleKeys[i], p_scaleKeys[i].GetX(), p_scaleKeys[i + 1], p_scaleKeys[i + 1].GetX());
914 y =
Interpolate(p_time, p_scaleKeys[i], p_scaleKeys[i].GetY(), p_scaleKeys[i + 1], p_scaleKeys[i + 1].GetY());
915 z =
Interpolate(p_time, p_scaleKeys[i], p_scaleKeys[i].GetZ(), p_scaleKeys[i + 1], p_scaleKeys[i + 1].GetZ());
919 p_matrix.
Scale(x, y, z);
956 if (p_numKeys == 0) {
959 else if (p_time <
GetKey(0, p_keys, p_size).GetTime()) {
962 else if (p_time >
GetKey(p_numKeys - 1, p_keys, p_size).GetTime()) {
963 p_new_index = p_numKeys - 1;
967 if (
GetKey(p_old_index, p_keys, p_size).GetTime() <= p_time) {
968 for (p_new_index = p_old_index;
969 p_new_index < p_numKeys - 1 && p_time >=
GetKey(p_new_index + 1, p_keys, p_size).
GetTime();
974 for (p_new_index = 0;
975 p_new_index < p_numKeys - 1 && p_time >=
GetKey(p_new_index + 1, p_keys, p_size).
GetTime();
980 p_old_index = p_new_index;
981 if (p_time ==
GetKey(p_new_index, p_keys, p_size).
GetTime()) {
984 else if (p_new_index < p_numKeys - 1) {
1004 return p_value1 + (p_value2 - p_value1) * (p_time - p_key1.
GetTime()) / (p_key2.
GetTime() - p_key1.
GetTime());
1043 if (p_storage->
Read(&length,
sizeof(length)) !=
SUCCESS) {
1050 for (i = 0; i < length; i++) {
1052 if (p_storage->
Read(&length,
sizeof(length)) !=
SUCCESS) {
1117 if (p_storage->
Write(&length,
sizeof(length)) !=
SUCCESS) {
[AI] Represents a single generic animation keyframe, containing timing and per-keyframe flags.
LegoFloat GetTime()
[AI] Retrieves the time (frame/tick) of this key.
@ c_bit1
[AI] Indicates if the key affects the output (meaning depends on derived type).
LegoAnimKey()
[AI] Constructs an animation key with zero time and cleared flags.
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the animation key to storage.
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the animation key from storage.
LegoFloat m_time
[AI] Time/sample/frame when this key occurs.
LegoU8 m_flags
[AI] Flags controlling key behavior or interpolation (see Flags enum).
[AI] Holds per-node animation data for a model's animation tree.
LegoU32 GetRotationIndex()
[AI] Gets last used/optimized rotation index for interpolation.
LegoRotationKey * m_rotationKeys
[AI] Array of rotation keyframes.
static LegoAnimKey & GetKey(LegoU32 p_i, LegoAnimKey *p_keys, LegoU32 p_size)
[AI] Retrieves a reference to the p_i-th LegoAnimKey of given size.
LegoU32 m_rotationIndex
[AI] Index cache for optimized rotation lookup/interpolation.
LegoU16 m_numTranslationKeys
[AI] Number of translation keyframes.
LegoChar * m_name
[AI] Animation node name.
void SetScaleIndex(LegoU32 p_scaleIndex)
[AI] Sets last used scale index.
LegoU32 m_morphIndex
[AI] Index cache for optimized morph lookup/interpolation.
LegoU16 m_numScaleKeys
[AI] Number of scale keyframes.
~LegoAnimNodeData() override
[AI] Cleans up all allocated animation key arrays and the node name. [AI]
LegoU16 m_numRotationKeys
[AI] Number of rotation keyframes.
static LegoFloat Interpolate(LegoFloat p_time, LegoAnimKey &p_key1, LegoFloat p_value1, LegoAnimKey &p_key2, LegoFloat p_value2)
[AI] Performs linear interpolation between two key values for the given time.
void SetTranslationIndex(LegoU32 p_translationIndex)
[AI] Sets last used translation index.
LegoAnimNodeData()
[AI] Default-initializes all animation key counts to zero and pointers to NULL. [AI]
static void GetTranslation(LegoU16 p_numTranslationKeys, LegoTranslationKey *p_translationKeys, LegoFloat p_time, Matrix4 &p_matrix, LegoU32 &p_old_index)
[AI] Computes interpolated translation for a node at specified time, filling p_matrix.
LegoResult CreateLocalTransform(LegoFloat p_time, Matrix4 &p_matrix)
[AI] Computes the interpolated local transformation matrix for this node at the given animation time.
LegoU32 GetScaleIndex()
[AI] Gets last used/optimized scale index for interpolation.
void SetMorphIndex(LegoU32 p_morphIndex)
[AI] Sets last used morph index.
LegoScaleKey * m_scaleKeys
[AI] Array of scale keyframes.
LegoResult Read(LegoStorage *p_storage) override
[AI] Reads all node keyframe arrays, name, and meta from storage.
LegoBool FUN_100a0990(LegoFloat p_time)
[AI] Evaluates morph keys at the given animation time and returns result (typically affects mesh shap...
void SetName(LegoChar *p_name)
[AI] Sets the node's name (deep-copies string).
LegoMorphKey * m_morphKeys
[AI] Array of morph keyframes.
LegoU32 GetTranslationIndex()
[AI] Gets last used/optimized translation index for interpolation.
static void GetScale(LegoU16 p_numScaleKeys, LegoScaleKey *p_scaleKeys, LegoFloat p_time, Matrix4 &p_matrix, LegoU32 &p_old_index)
[AI] Computes interpolated scaling on a node at given time, updating p_matrix.
LegoTranslationKey * m_translationKeys
[AI] Array of translation keyframes.
void SetRotationIndex(LegoU32 p_rotationIndex)
[AI] Sets last used rotation index.
LegoU32 m_scaleIndex
[AI] Index cache for optimized scale lookup/interpolation.
static LegoU32 FindKeys(LegoFloat p_time, LegoU32 p_numKeys, LegoAnimKey *p_keys, LegoU32 p_size, LegoU32 &p_new_index, LegoU32 &p_old_index)
[AI] Finds surrounding key(s) for interpolation at p_time.
LegoResult Write(LegoStorage *p_storage) override
[AI] Writes all node keyframe arrays, name, and meta to storage.
static void GetRotation(LegoU16 p_numRotationKeys, LegoRotationKey *p_rotationKeys, LegoFloat p_time, Matrix4 &p_matrix, LegoU32 &p_old_index)
[AI] Computes interpolated rotation at a given time, filling p_matrix.
LegoU16 m_unk0x22
[AI] Unknown, used in camera/scene morph/rotation (purpose unclear).
LegoU32 m_translationIndex
[AI] Index cache for optimized translation lookup/interpolation.
LegoU32 GetMorphIndex()
[AI] Gets last used/optimized morph index for interpolation.
LegoU16 m_unk0x20
[AI] Unknown, used in camera/scene morph/rotation (purpose unclear).
LegoU16 m_numMorphKeys
[AI] Number of morph keyframes.
[AI] Represents an animation scene; possibly used for camera motion or global transforms.
LegoU32 GetUnknown0x1c()
[AI] Cached index for translation key interpolation (for second translation key array).
LegoResult FUN_1009f490(LegoFloat p_time, Matrix4 &p_matrix)
[AI] Evaluates this scene's animation at the given time, updating the passed matrix.
LegoAnimScene()
[AI] Default construction, zeroes all data pointers and counters.
~LegoAnimScene()
[AI] Destroys the scene, frees all allocated key arrays.
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the entire scene data to storage, including all translation/unknown key arrays.
LegoResult Read(LegoStorage *p_storage)
[AI] Reads the entire scene data from storage, including all translation/unknown key arrays.
void SetUnknown0x18(LegoU32 p_unk0x18)
[AI] Sets cached translation index (first stream).
void SetUnknown0x1c(LegoU32 p_unk0x1c)
[AI] Sets cached translation index (second stream).
void SetUnknown0x20(LegoU32 p_unk0x20)
[AI] Sets cached key interpolation index (unknown key type).
LegoU32 GetUnknown0x20()
[AI] Cached index for unknown key interpolation.
LegoU32 GetUnknown0x18()
[AI] Cached index for translation key interpolation (for first translation key array).
[AI] Root class for all node-based animation blending/structure.
LegoAnimActorEntry * m_modelList
[AI] Array of actor/model entries animated by this object.
virtual LegoResult Read(LegoStorage *p_storage, LegoS32 p_parseScene)
[AI] Loads model and animation data from storage, optionally including scene/camera animation.
LegoAnimScene * m_camAnim
[AI] Pointer to camera/scene animation (may be nullptr).
LegoU32 m_numActors
[AI] Number of actors/models.
~LegoAnim() override
[AI] Destructor, deallocates actors and camera animation.
undefined4 GetActorUnknown0x04(LegoU32 p_index)
[AI] Gets the actor's "unk0x04" property at a given index.
LegoTime m_duration
[AI] Animation duration in time units.
LegoAnim()
[AI] Constructs an empty animation object, with no actors or tracks.
const LegoChar * GetActorName(LegoU32 p_index)
[AI] Gets the name of the actor at a given index.
LegoResult Write(LegoStorage *p_storage) override
[AI] Serializes all model and animation data to storage.
[AI] Animation key for morphing states or mesh morphing.
LegoBool GetUnknown0x08()
[AI] Gets the morph Boolean value (meaning unknown).
LegoMorphKey()
[AI] Constructs a morph key with an unset ("off") state.
LegoBool m_unk0x08
[AI][AI_SUGGESTED_NAME: m_morphState] Morphing state or flag at this key (meaning unknown).
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the morph key to storage.
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the morph key from storage.
[AI] Animation key class for rotations (axis-angle format).
LegoFloat GetY()
[AI] Gets the Y-axis of the rotation.
LegoFloat m_z
[AI] Axis-angle rotation: Z component.
LegoRotationKey()
[AI] Constructs a rotation key with default (identity) rotation.
LegoFloat m_x
[AI] Axis-angle rotation: X component.
LegoFloat GetZ()
[AI] Gets the Z-axis of the rotation.
LegoFloat m_y
[AI] Axis-angle rotation: Y component.
LegoFloat GetX()
[AI] Gets the X-axis of the rotation.
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the rotation key from storage.
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the rotation key to storage.
LegoFloat GetAngle()
[AI] Gets the rotation angle (around the axis).
LegoFloat m_angle
[AI] Axis-angle rotation: the angle value.
[AI] Animation key class for scaling transformations.
LegoFloat GetX()
[AI] Gets the scaling X factor.
LegoFloat m_x
[AI] Scale along the X-axis.
LegoFloat m_z
[AI] Scale along the Z-axis.
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the scale key to storage.
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the scale key from storage.
LegoFloat GetZ()
[AI] Gets the scaling Z factor.
LegoFloat m_y
[AI] Scale along the Y-axis.
LegoFloat GetY()
[AI] Gets the scaling Y factor.
LegoScaleKey()
[AI] Constructs a scale key (default: scale factor 1,1,1).
Abstract base class providing an interface for file-like storage with binary and text read/write oper...
virtual LegoResult Write(const void *p_buffer, LegoU32 p_size)=0
Write bytes from buffer into storage.
virtual LegoResult Read(void *p_buffer, LegoU32 p_size)=0
Read bytes from storage into buffer.
[AI] Animation key class for translations (vector 3D positions).
LegoFloat m_y
[AI] Translation along Y-axis.
LegoTranslationKey()
[AI] Constructs a translation key with all translation components set to zero.
LegoFloat m_z
[AI] Translation along Z-axis.
LegoFloat m_x
[AI] Translation along X-axis.
LegoFloat GetZ()
[AI] Gets the translation Z component.
LegoFloat GetX()
[AI] Gets the translation X component.
LegoFloat GetY()
[AI] Gets the translation Y component.
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes this translation key from storage.
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes this translation key to storage.
virtual LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the tree structure recursively to the given storage.
virtual LegoResult Read(LegoStorage *p_storage)
[AI] Loads the tree structure recursively from the given storage.
[AI] Animation key of unknown type, used internally by camera/track animation.
LegoResult Read(LegoStorage *p_storage)
[AI] Deserializes the unknown key from storage.
LegoFloat m_z
[AI][AI_SUGGESTED_NAME: m_angleOrZ] Tracks either a Z translation or angle for camera movement.
LegoResult Write(LegoStorage *p_storage)
[AI] Serializes the unknown key to storage.
4x4 Matrix class with virtual interface for manipulation and transformation.
virtual float(* GetData())[4]
Gets modifiable access to the 4x4 float matrix.
virtual void TranslateBy(const float &p_x, const float &p_y, const float &p_z)
Applies translation by amounts along X, Y, Z axes.
void Scale(const float &p_x, const float &p_y, const float &p_z)
Applies scaling factors along X, Y, and Z axes.
void RotateZ(const float &p_angle)
Applies a rotation (in radians or degrees) about the Z axis.
virtual void Product(float(*p_a)[4], float(*p_b)[4])
Multiplies two 4x4 float matrices, storing result in this.
virtual void SetIdentity()
Sets this matrix to identity (diagonal 1, others 0).
virtual int FromQuaternion(const Vector4 &p_vec)
Initializes the matrix from a quaternion (Vector4).
[AI] Represents a 3D point with floating-point precision, inheriting from Vector3.
[AI] 4D point class for floating point values.
[AI] Represents a 4x4 transformation matrix, specialized for the LEGO Island engine and derived from ...
virtual int Unitize()
[AI] Scales the vector so its norm is 1 (unit vector).
[AI] 3D vector class, providing vector and cross-product operations in 3D space.
void Clear() override
[AI] Sets every coordinate (x, y, z) to zero.
virtual void EqualsCross(const Vector3 &p_a, const Vector3 &p_b)
[AI] Sets this vector to be the cross product of p_a and p_b.
#define DECOMP_SIZE_ASSERT(T, S)
#define NULL
[AI] Null pointer value (C/C++ semantics).
unsigned long LegoU32
[AI] Unsigned 32-bit integer type for cross-platform compatibility.
char LegoChar
[AI] Alias for char, for use in character/byte data and string handling.
#define FAILURE
[AI] Used to indicate a failed operation in result codes.
unsigned char LegoU8
[AI] Unsigned 8-bit integer type used throughout LEGO Island.
LegoS32 LegoResult
[AI] Function result type (return code): typically SUCCESS (0) or FAILURE (-1).
long LegoS32
[AI] Signed 32-bit integer type for cross-platform compatibility.
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
unsigned short LegoU16
[AI] Unsigned 16-bit integer type for cross-platform compatibility.
float LegoFloat
[AI] Floating point type used throughout LEGO Island.
LegoU8 LegoBool
[AI] Boolean value used throughout the codebase.
[AI] Describes a single actor or model referenced by an animation.
LegoChar * m_name
[AI] Name of the actor/model.
undefined4 m_unk0x04
[AI] Unknown. May refer to a flag, index, or property (purpose unclear). [AI_SUGGESTED_NAME: m_actorP...