123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- /*
- Open Asset Import Library (assimp)
- ----------------------------------------------------------------------
- Copyright (c) 2006-2025, assimp team
- All rights reserved.
- Redistribution and use of this software in source and binary forms,
- with or without modification, are permitted provided that the
- following conditions are met:
- * Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
- * Neither the name of the assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ----------------------------------------------------------------------
- */
- #pragma once
- /** @file MD5Parser.h
- * @brief Definition of the .MD5 parser class.
- * http://www.modwiki.net/wiki/MD5_(file_format)
- */
- #ifndef AI_MD5PARSER_H_INCLUDED
- #define AI_MD5PARSER_H_INCLUDED
- #include <assimp/types.h>
- #include <assimp/ParsingUtils.h>
- #include <vector>
- #include <cstdint>
- struct aiFace;
- namespace Assimp {
- namespace MD5 {
- // ---------------------------------------------------------------------------
- /** Represents a single element in a MD5 file
- *
- * Elements are always contained in sections.
- */
- struct Element {
- //! Points to the starting point of the element
- //! Whitespace at the beginning and at the end have been removed,
- //! Elements are terminated with \0
- char* szStart;
- const char *end;
- //! Original line number (can be used in error messages
- //! if a parsing error occurs)
- unsigned int iLineNumber;
- };
- using ElementArray = std::vector<Element>;
- // ---------------------------------------------------------------------------
- /** Represents a section of a MD5 file (such as the mesh or the joints section)
- *
- * A section is always enclosed in { and } brackets.
- */
- struct Section {
- //! Original line number (can be used in error messages
- //! if a parsing error occurs)
- unsigned int iLineNumber;
- //! List of all elements which have been parsed in this section.
- ElementArray mElements;
- //! Name of the section
- std::string mName;
- //! For global elements: the value of the element as string
- //! if !length() the section is not a global element
- std::string mGlobalValue;
- };
- using SectionArray = std::vector<Section>;
- // ---------------------------------------------------------------------------
- /** Basic information about a joint
- */
- struct BaseJointDescription {
- //! Name of the bone
- aiString mName;
- //! Parent index of the bone
- int mParentIndex;
- };
- // ---------------------------------------------------------------------------
- /** Represents a bone (joint) descriptor in a MD5Mesh file
- */
- struct BoneDesc : BaseJointDescription {
- //! Absolute position of the bone
- aiVector3D mPositionXYZ;
- //! Absolute rotation of the bone
- aiVector3D mRotationQuat;
- aiQuaternion mRotationQuatConverted;
- //! Absolute transformation of the bone
- //! (temporary)
- aiMatrix4x4 mTransform;
- //! Inverse transformation of the bone
- //! (temporary)
- aiMatrix4x4 mInvTransform;
- //! Internal
- unsigned int mMap;
- };
- using BoneArray = std::vector<BoneDesc>;
- // ---------------------------------------------------------------------------
- /** Represents a bone (joint) descriptor in a MD5Anim file
- */
- struct AnimBoneDesc : BaseJointDescription {
- //! Flags (AI_MD5_ANIMATION_FLAG_xxx)
- unsigned int iFlags;
- //! Index of the first key that corresponds to this anim bone
- unsigned int iFirstKeyIndex;
- };
- using AnimBoneArray = std::vector< AnimBoneDesc >;
- // ---------------------------------------------------------------------------
- /** Represents a base frame descriptor in a MD5Anim file
- */
- struct BaseFrameDesc {
- aiVector3D vPositionXYZ;
- aiVector3D vRotationQuat;
- };
- using BaseFrameArray = std::vector<BaseFrameDesc>;
- // ---------------------------------------------------------------------------
- /** Represents a camera animation frame in a MDCamera file
- */
- struct CameraAnimFrameDesc : BaseFrameDesc {
- float fFOV;
- };
- using CameraFrameArray = std::vector<CameraAnimFrameDesc>;
- // ---------------------------------------------------------------------------
- /** Represents a frame descriptor in a MD5Anim file
- */
- struct FrameDesc {
- //! Index of the frame
- unsigned int iIndex;
- //! Animation keyframes - a large blob of data at first
- std::vector< float > mValues;
- };
- using FrameArray = std::vector<FrameDesc>;
- // ---------------------------------------------------------------------------
- /** Represents a vertex descriptor in a MD5 file
- */
- struct VertexDesc {
- VertexDesc() AI_NO_EXCEPT
- : mFirstWeight(0), mNumWeights(0) {
- // empty
- }
- //! UV coordinate of the vertex
- aiVector2D mUV;
- //! Index of the first weight of the vertex in
- //! the vertex weight list
- unsigned int mFirstWeight;
- //! Number of weights assigned to this vertex
- unsigned int mNumWeights;
- };
- using VertexArray = std::vector<VertexDesc>;
- // ---------------------------------------------------------------------------
- /** Represents a vertex weight descriptor in a MD5 file
- */
- struct WeightDesc {
- //! Index of the bone to which this weight refers
- unsigned int mBone;
- //! The weight value
- float mWeight;
- //! The offset position of this weight
- // ! (in the coordinate system defined by the parent bone)
- aiVector3D vOffsetPosition;
- };
- using WeightArray = std::vector<WeightDesc>;
- using FaceArray = std::vector<aiFace>;
- // ---------------------------------------------------------------------------
- /** Represents a mesh in a MD5 file
- */
- struct MeshDesc {
- //! Weights of the mesh
- WeightArray mWeights;
- //! Vertices of the mesh
- VertexArray mVertices;
- //! Faces of the mesh
- FaceArray mFaces;
- //! Name of the shader (=texture) to be assigned to the mesh
- aiString mShader;
- };
- using MeshArray = std::vector<MeshDesc>;
- // ---------------------------------------------------------------------------
- // Convert a quaternion to its usual representation
- inline void ConvertQuaternion (const aiVector3D& in, aiQuaternion& out) {
- out.x = in.x;
- out.y = in.y;
- out.z = in.z;
- const float t = 1.0f - (in.x*in.x) - (in.y*in.y) - (in.z*in.z);
- if (t < 0.0f) {
- out.w = 0.0f;
- } else {
- out.w = std::sqrt (t);
- }
- // Assimp convention.
- out.w *= -1.f;
- }
- // ---------------------------------------------------------------------------
- /** Parses the data sections of a MD5 mesh file
- */
- class MD5MeshParser {
- public:
- // -------------------------------------------------------------------
- /** Constructs a new MD5MeshParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- explicit MD5MeshParser(SectionArray& mSections);
- //! List of all meshes
- MeshArray mMeshes;
- //! List of all joints
- BoneArray mJoints;
- };
- // remove this flag if you need to the bounding box data
- #define AI_MD5_PARSE_NO_BOUNDS
- // ---------------------------------------------------------------------------
- /** Parses the data sections of a MD5 animation file
- */
- class MD5AnimParser {
- public:
- // -------------------------------------------------------------------
- /** Constructs a new MD5AnimParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- explicit MD5AnimParser(SectionArray& mSections);
- //! Output frame rate
- float fFrameRate;
- //! List of animation bones
- AnimBoneArray mAnimatedBones;
- //! List of base frames
- BaseFrameArray mBaseFrames;
- //! List of animation frames
- FrameArray mFrames;
- //! Number of animated components
- unsigned int mNumAnimatedComponents;
- };
- // ---------------------------------------------------------------------------
- /** Parses the data sections of a MD5 camera animation file
- */
- class MD5CameraParser {
- public:
- // -------------------------------------------------------------------
- /** Constructs a new MD5CameraParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- explicit MD5CameraParser(SectionArray& mSections);
- //! Output frame rate
- float fFrameRate;
- //! List of cuts
- std::vector<unsigned int> cuts;
- //! Frames
- CameraFrameArray frames;
- };
- // ---------------------------------------------------------------------------
- /** Parses the block structure of MD5MESH and MD5ANIM files (but does no
- * further processing)
- */
- class MD5Parser {
- public:
- // -------------------------------------------------------------------
- /** Constructs a new MD5Parser instance from an existing buffer.
- *
- * @param buffer File buffer
- * @param fileSize Length of the file in bytes (excluding a terminal 0)
- */
- MD5Parser(char* buffer, unsigned int fileSize);
- // -------------------------------------------------------------------
- /** Report a specific error message and throw an exception
- * @param error Error message to be reported
- * @param line Index of the line where the error occurred
- */
- AI_WONT_RETURN static void ReportError(const char* error, unsigned int line) AI_WONT_RETURN_SUFFIX;
- // -------------------------------------------------------------------
- /** Report a specific warning
- * @param warn Warn message to be reported
- * @param line Index of the line where the error occurred
- */
- static void ReportWarning(const char* warn, unsigned int line);
- // -------------------------------------------------------------------
- /** Report a specific error
- * @param error Error message to be reported
- */
- AI_WONT_RETURN void ReportError (const char* error) AI_WONT_RETURN_SUFFIX;
- // -------------------------------------------------------------------
- /** Report a specific warning
- * @param error Warn message to be reported
- */
- void ReportWarning (const char* warn);
- //! List of all sections which have been read
- SectionArray mSections;
- private:
- bool ParseSection(Section& out);
- void ParseHeader();
- bool SkipLine(const char* in, const char** out);
- bool SkipLine( );
- bool SkipSpacesAndLineEnd( const char* in, const char** out);
- bool SkipSpacesAndLineEnd();
- bool SkipSpaces();
- private:
- char* buffer;
- const char* bufferEnd;
- unsigned int fileSize;
- unsigned int lineNumber;
- };
- // -------------------------------------------------------------------
- inline void MD5Parser::ReportWarning (const char* warn) {
- return ReportWarning(warn, lineNumber);
- }
- // -------------------------------------------------------------------
- inline void MD5Parser::ReportError(const char* error) {
- ReportError(error, lineNumber);
- }
- // -------------------------------------------------------------------
- inline bool MD5Parser::SkipLine(const char* in, const char** out) {
- ++lineNumber;
- return Assimp::SkipLine(in, out, bufferEnd);
- }
- // -------------------------------------------------------------------
- inline bool MD5Parser::SkipLine( ) {
- return SkipLine(buffer,(const char**)&buffer);
- }
- // -------------------------------------------------------------------
- inline bool MD5Parser::SkipSpacesAndLineEnd( const char* in, const char** out) {
- if (in == bufferEnd) {
- *out = in;
- return false;
- }
- bool bHad = false, running = true;
- while (running) {
- if( *in == '\r' || *in == '\n') {
- // we open files in binary mode, so there could be \r\n sequences ...
- if (!bHad) {
- bHad = true;
- ++lineNumber;
- }
- } else if (*in == '\t' || *in == ' ') {
- bHad = false;
- } else {
- break;
- }
- ++in;
- if (in == bufferEnd) {
- break;
- }
- }
- *out = in;
- return *in != '\0';
- }
- // -------------------------------------------------------------------
- inline bool MD5Parser::SkipSpacesAndLineEnd() {
- return SkipSpacesAndLineEnd(buffer,(const char**)&buffer);
- }
- // -------------------------------------------------------------------
- inline bool MD5Parser::SkipSpaces() {
- return Assimp::SkipSpaces((const char**)&buffer, bufferEnd);
- }
- } // namespace Assimp
- } // namespace MD5
- #endif // AI_MD5PARSER_H_INCLUDED
|