//===========================================================================// // File: AnimFormat.hpp // Project: MechWarrior 4 // Contents: // This is the base animation format header file. // This file defines Keyframes and Animation Player classes // PLEASE NOTE!!!! THIS FILE IS USED BY THE PLUGIN : // 3dsplugins/AnimationExport // If you change this you must also change the plugin!!!! // // THIS IS A THREAT! // All the animations that have been exported rely on this format // If you change this format, you better know what you are doing! // If you don't support multiple versions when you change this // Then you HAVE TO EXPORT ALL THE ANIMATIONS AGAIN!!!!! // The max plugin environment allows for this. //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 05/15/98 JSE Initial coding, //---------------------------------------------------------------------------// // Copyright (C) 1998, Fasa Interactive, Inc. // All Rights reserved worldwide // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //===========================================================================// #pragma once // Animation file format // The animation file format is designed to be quickly loaded and have only a // small amount of overhead. // Basicly the file format is binary compatable with the memory format. // The only section that isn't binary compatable is the header block // and that is so that it can actualy point to the blocks of memory // #define MAJOR_ANIM_VERSION_2_1 2 #define MINOR_ANIM_VERSION_2_1 1 #define MAJOR_ANIM_VERSION_2_0 2 #define MINOR_ANIM_VERSION_2_0 0 #define MAJOR_ANIM_VERSION_1_0 1 #define MINOR_ANIM_VERSION_1_0 0 #define COMPRESS_JOINT_COUNT 47 #include #include namespace MW4Animation { // Pack all this #pragma pack( push, anim_pack, 4 ) // //===========================================================================// // This is the basic keyframe data holders // This is binary compatable to the file format // so casting is all that is required to // create them from the file //===========================================================================// // Class BaseKeyframe // Only holds the time // all iteration uses this base class class BaseKeyframeTime { public: Stuff::Scalar timeOfFrame; }; //===========================================================================// class BaseKeyframe { public: }; //===========================================================================// class Point3DLinearKey : public BaseKeyframe { public: Stuff::Point3D valueOfKey; }; //===========================================================================// class QuaternionLinearKey : public BaseKeyframe { public: Stuff::UnitQuaternion valueOfKey; }; //===========================================================================// class TriggerLinearKey : public BaseKeyframe { public: int valueOfKey; }; //===========================================================================// class VelocityLinearKey : public BaseKeyframe { public: Stuff::Point3D valueOfKey; Stuff::Point3D velocityOfKey; }; //===========================================================================// class AngularVelocityLinearKey : public BaseKeyframe { public: Stuff::UnitQuaternion valueOfKey; Stuff::Vector3D velocityOfKey; }; //===========================================================================// class JointAnimData { public: enum { Point3DLinearKeyType, QuaternionLinearKeyType, TriggerLinearKeyType, VelocityLinearKeyType, AngularVelocityLinearKeyType, KeyTypeCount }; JointAnimData(){}; ~JointAnimData(){}; size_t offsetToName; int firstChannel; BYTE channelsUsed; const char *GetName(const char *name_block) { return name_block + offsetToName; } }; //===========================================================================// class ChannelAnimData { public: enum { VelocityChannelType, PositionChannelType, RotationChannelType, TriggerChannelType, AngularVelocityChannelType }; size_t sizeOfOneKey; size_t offsetToKeyData; size_t offsetToKeyTimeData; BYTE keyframeCount; BYTE channelType; BYTE keyType; BYTE jointNumber; }; //===========================================================================// class AnimHeader { public: AnimHeader(){}; ~AnimHeader(){}; int majorVersion; int minorVersion; Stuff::Scalar startTime; Stuff::Scalar endTime; size_t totalSizeOfAnimation; size_t offsetToHeaderBlock; size_t offsetToJointBlock; size_t offsetToNameBlock; size_t offsetToKeyBlock; size_t offsetToKeyTimeBlock; size_t offsetToChannelBlock; // these are last for packing reasons. char animationName[56]; }; //===========================================================================// // This is the only thing that has to be dynamicly allocated once the binary // of the animation has been transfered to memory. The rest is pointer math! class AnimData { public: AnimData(); ~AnimData(); // if we made a copy of the memory BYTE *startOfBlocks; AnimHeader *animHeaderBlock; size_t animHeaderBlockSize; JointAnimData *animJointBlock; size_t animJointBlockSize; char *animNameBlock; size_t animNameBlockSize; void *animKeyBlock; size_t animKeyBlockSize; void *animKeyTimeBlock; size_t animKeyTimeBlockSize; ChannelAnimData *animChannelBlock; size_t animChannelBlockSize; BYTE GetJointCount(); int GetChannelCount(); size_t GetSize(); bool Save(const char *file_name); bool Save(Stuff::FileStream *stream); bool Save(Stuff::MemoryStream *stream); bool Load(const char *file_name); // this makes a local copy of the data bool Load(Stuff::FileStream *stream); // this makes a local copy of the data bool Load_1_0(Stuff::MemoryStream *stream); // this just refrences the data bool Load_2_0(Stuff::MemoryStream *stream); bool Load_2_1(Stuff::MemoryStream *stream); bool Load(Adept::Resource *res); bool CopyAndLoad(Stuff::MemoryStream *stream); // this will make a copy of the data }; #pragma pack( pop, anim_pack) inline BYTE AnimData::GetJointCount(void) { return (BYTE)(animJointBlockSize / sizeof(JointAnimData)); } inline int AnimData::GetChannelCount(void) { return animChannelBlockSize / sizeof(ChannelAnimData); } inline size_t AnimData::GetSize(void) { return animHeaderBlockSize + animJointBlockSize + animNameBlockSize + animKeyBlockSize + animKeyTimeBlockSize + animChannelBlockSize + 1; // one is the null byte } int CompressName(const char *source, Stuff::MString &dest); int UncompressName(const char *source, Stuff::MString &dest); }