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