From 42ef23e745061d6a58635f50230647a230ccd5b7 Mon Sep 17 00:00:00 2001 From: aramis_acg Date: Thu, 7 Aug 2008 22:27:17 +0000 Subject: [PATCH] WIP version of a LWO file loader. Not working yet. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@82 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/ByteSwap.h | 65 +++-- code/IFF.h | 57 ++++ code/Importer.cpp | 6 + code/LWOFileData.h | 300 +++++++++++++++++++++ code/LWOLoader.cpp | 487 +++++++++++++++++++++++++++++++++++ code/LWOLoader.h | 158 ++++++++++++ code/STLLoader.cpp | 1 + workspaces/vc8/assimp.vcproj | 24 ++ 8 files changed, 1080 insertions(+), 18 deletions(-) create mode 100644 code/IFF.h create mode 100644 code/LWOFileData.h create mode 100644 code/LWOLoader.cpp create mode 100644 code/LWOLoader.h diff --git a/code/ByteSwap.h b/code/ByteSwap.h index 30cfd924e..34ad0a45b 100644 --- a/code/ByteSwap.h +++ b/code/ByteSwap.h @@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_BYTESWAP_H_INC #include "../include/aiAssert.h" +#include "../include/aiTypes.h" namespace Assimp { @@ -61,26 +62,39 @@ class ByteSwap public: //! Swap the byte oder of 2 byte of data //! \param szOut Buffer to be swapped - static inline void Swap2(char* szOut) + static inline void Swap2(void* _szOut) { - ai_assert(NULL != szOut); + ai_assert(NULL != _szOut); + int8_t* szOut = (int8_t*)_szOut; std::swap(szOut[0],szOut[1]); } //! Swap the byte oder of 4 byte of data //! \param szOut Buffer to be swapped - static inline void Swap4(char* szOut) + static inline void Swap4(void* _szOut) { - ai_assert(NULL != szOut); +#if _MSC_VER >= 1400 && (defined _M_X86) + __asm + { + mov edi, _szOut + mov eax, dword_ptr[edi] + bswap eax + mov dword_ptr[edi], eax + }; +#else + ai_assert(NULL != _szOut); + int8_t* szOut = (int8_t*)_szOut; std::swap(szOut[0],szOut[3]); std::swap(szOut[1],szOut[2]); +#endif } //! Swap the byte oder of 8 byte of data //! \param szOut Buffer to be swapped - static inline void Swap8(char* szOut) + static inline void Swap8(void* _szOut) { - ai_assert(NULL != szOut); + ai_assert(NULL != _szOut); + int8_t* szOut = (int8_t*)_szOut; std::swap(szOut[0],szOut[7]); std::swap(szOut[1],szOut[6]); std::swap(szOut[2],szOut[5]); @@ -91,47 +105,54 @@ public: //! \param fOut Float value to be swapped static inline void Swap(float* fOut) { - Swap4((char*)fOut); + Swap4(fOut); } //! Swap a double precision float //! \param fOut Double value to be swapped static inline void Swap(double* fOut) { - Swap8((char*)fOut); + Swap8(fOut); } //! Swap a 16 bit integer //! \param fOut Integer to be swapped static inline void Swap(int16_t* fOut) { - Swap2((char*)fOut); + Swap2(fOut); } //! Swap a 32 bit integer //! \param fOut Integer to be swapped static inline void Swap(int32_t* fOut) { - Swap4((char*)fOut); + Swap4(fOut); } //! Swap a 64 bit integer //! \param fOut Integer to be swapped static inline void Swap(int64_t* fOut) { - Swap8((char*)fOut); + Swap8(fOut); } }; }; -// byteswap macros for BigEndian support +// byteswap macros for BigEndian/LittleEndian support #if (defined AI_BUILD_BIG_ENDIAN) -# define AI_SWAP2(p) ByteSwap::Swap2((char*)&(p)) -# define AI_SWAP4(p) ByteSwap::Swap4((char*)&(p)) -# define AI_SWAP8(p) ByteSwap::Swap8((char*)&(p)) -# define AI_SWAP2P(p) ByteSwap::Swap2((char*)(p)) -# define AI_SWAP4P(p) ByteSwap::Swap4((char*)(p)) -# define AI_SWAP8P(p) ByteSwap::Swap8((char*)(p)) +# define AI_LSWAP2(p) +# define AI_LSWAP4(p) +# define AI_LSWAP8(p) +# define AI_LSWAP2P(p) +# define AI_LSWAP4P(p) +# define AI_LSWAP8P(p) +# define LE_NCONST const +# define AI_SWAP2(p) ByteSwap::Swap2(&(p)) +# define AI_SWAP4(p) ByteSwap::Swap4(&(p)) +# define AI_SWAP8(p) ByteSwap::Swap8(&(p)) +# define AI_SWAP2P(p) ByteSwap::Swap2((p)) +# define AI_SWAP4P(p) ByteSwap::Swap4((p)) +# define AI_SWAP8P(p) ByteSwap::Swap8((p)) # define BE_NCONST #else # define AI_SWAP2(p) @@ -141,7 +162,15 @@ public: # define AI_SWAP4P(p) # define AI_SWAP8P(p) # define BE_NCONST const +# define AI_LSWAP2(p) ByteSwap::Swap2(&(p)) +# define AI_LSWAP4(p) ByteSwap::Swap4(&(p)) +# define AI_LSWAP8(p) ByteSwap::Swap8(&(p)) +# define AI_LSWAP2P(p) ByteSwap::Swap2((p)) +# define AI_LSWAP4P(p) ByteSwap::Swap4((p)) +# define AI_LSWAP8P(p) ByteSwap::Swap8((p)) +# define LE_NCONST #endif + #endif //!! AI_BYTESWAP_H_INC diff --git a/code/IFF.h b/code/IFF.h new file mode 100644 index 000000000..fc3e4002b --- /dev/null +++ b/code/IFF.h @@ -0,0 +1,57 @@ + + +// Definitions for the Interchange File Format (IFF) +// Alexander Gessler, 2006 +// Adapted for Assimp August 2008 + +#ifndef AI_IFF_H_INCLUDED +#define AI_IFF_H_INCLUDED + +#include "ByteSwap.h" + +namespace Assimp { +namespace IFF { + +//! Describes an IFF chunk header +struct ChunkHeader +{ + //! Type of the chunk header - FourCC + uint32_t type; + + //! Length of the chunk data, in bytes + uint32_t length; +}; + + +#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \ + ((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d))) + + +#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M') + + +///////////////////////////////////////////////////////////////////////////////// +//! Read the file header and return the type of the file and its size +//! @param outFile Pointer to the file data. The buffer must at +//! least be 12 bytes large. +//! @param fileType Receives the type of the file +//! @return 0 if everything was OK, otherwise an error message +///////////////////////////////////////////////////////////////////////////////// +inline const char* ReadHeader(const uint8_t* outFile,uint32_t& fileType) +{ + LE_NCONST ChunkHeader* head = (LE_NCONST ChunkHeader*) outFile; + AI_LSWAP4(head->length); + AI_LSWAP4(head->type); + if(AI_IFF_FOURCC_FORM != head->type) + { + return "The file is not an IFF file: FORM chunk is missing"; + } + fileType = *((uint32_t*)(head+1)); + AI_LSWAP4(fileType); + return 0; +} + + +}} + +#endif // !! AI_IFF_H_INCLUDED \ No newline at end of file diff --git a/code/Importer.cpp b/code/Importer.cpp index 2132bb891..3354b2771 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -98,6 +98,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #if (!defined AI_BUILD_NO_STL_IMPORTER) # include "STLLoader.h" #endif +#if (!defined AI_BUILD_NO_LWO_IMPORTER) +# include "LWOLoader.h" +#endif // PostProcess-Steps #if (!defined AI_BUILD_NO_CALCTANGENTS_PROCESS) @@ -195,6 +198,9 @@ Importer::Importer() : #if (!defined AI_BUILD_NO_STL_IMPORTER) mImporter.push_back( new STLImporter()); #endif +#if (!defined AI_BUILD_NO_LWO_IMPORTER) + mImporter.push_back( new LWOImporter()); +#endif // add an instance of each post processing step here in the order // of sequence it is executed diff --git a/code/LWOFileData.h b/code/LWOFileData.h new file mode 100644 index 000000000..b7dca8157 --- /dev/null +++ b/code/LWOFileData.h @@ -0,0 +1,300 @@ +/* +Open Asset Import Library (ASSIMP) +---------------------------------------------------------------------- + +Copyright (c) 2006-2008, ASSIMP Development 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 Development 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. + +---------------------------------------------------------------------- +*/ + +/** @file Defines chunk constants used by the LWO file format + +The chunks are taken from LWO2.h, found in the sourcecode of +a project called Nxabega (http://www.sourceforge.net/projects/nxabega). +I assume they are from the official LightWave SDK headers. +Original copyright notice: "Ernie Wright 17 Sep 00" + +*/ +#ifndef AI_LWO_FILEDATA_INCLUDED +#define AI_LWO_FILEDATA_INCLUDED + + +#include "IFF.h" +#include "../include/aiMesh.h" + +namespace Assimp { +namespace LWO { + +#define AI_LWO_FOURCC_LWOB AI_IFF_FOURCC('L','W','O','B') +#define AI_LWO_FOURCC_LWO2 AI_IFF_FOURCC('L','W','O','2') + +// chunks specific to the LWOB format +#define AI_LWO_SRFS AI_IFF_FOURCC('S','R','F','S') +#define AI_LWO_FLAG AI_IFF_FOURCC('F','L','A','G') +#define AI_LWO_VLUM AI_IFF_FOURCC('V','L','U','M') +#define AI_LWO_VDIF AI_IFF_FOURCC('V','D','I','F') +#define AI_LWO_VSPC AI_IFF_FOURCC('V','S','P','C') +#define AI_LWO_RFLT AI_IFF_FOURCC('R','F','L','T') +#define AI_LWO_BTEX AI_IFF_FOURCC('B','T','E','X') +#define AI_LWO_CTEX AI_IFF_FOURCC('C','T','E','X') +#define AI_LWO_DTEX AI_IFF_FOURCC('D','T','E','X') +#define AI_LWO_LTEX AI_IFF_FOURCC('L','T','E','X') +#define AI_LWO_RTEX AI_IFF_FOURCC('R','T','E','X') +#define AI_LWO_STEX AI_IFF_FOURCC('S','T','E','X') +#define AI_LWO_TTEX AI_IFF_FOURCC('T','T','E','X') +#define AI_LWO_TFLG AI_IFF_FOURCC('T','F','L','G') +#define AI_LWO_TSIZ AI_IFF_FOURCC('T','S','I','Z') +#define AI_LWO_TCTR AI_IFF_FOURCC('T','C','T','R') +#define AI_LWO_TFAL AI_IFF_FOURCC('T','F','A','L') +#define AI_LWO_TVEL AI_IFF_FOURCC('T','V','E','L') +#define AI_LWO_TCLR AI_IFF_FOURCC('T','C','L','R') +#define AI_LWO_TVAL AI_IFF_FOURCC('T','V','A','L') +#define AI_LWO_TAMP AI_IFF_FOURCC('T','A','M','P') +#define AI_LWO_TIMG AI_IFF_FOURCC('T','I','M','G') +#define AI_LWO_TAAS AI_IFF_FOURCC('T','A','A','S') +#define AI_LWO_TREF AI_IFF_FOURCC('T','R','E','F') +#define AI_LWO_TOPC AI_IFF_FOURCC('T','O','P','C') +#define AI_LWO_SDAT AI_IFF_FOURCC('S','D','A','T') +#define AI_LWO_TFP0 AI_IFF_FOURCC('T','F','P','0') +#define AI_LWO_TFP1 AI_IFF_FOURCC('T','F','P','1') + + +/* top-level chunks */ +#define AI_LWO_LAYR AI_IFF_FOURCC('L','A','Y','R') +#define AI_LWO_TAGS AI_IFF_FOURCC('T','A','G','S') +#define AI_LWO_PNTS AI_IFF_FOURCC('P','N','T','S') +#define AI_LWO_BBOX AI_IFF_FOURCC('B','B','O','X') +#define AI_LWO_VMAP AI_IFF_FOURCC('V','M','A','P') +#define AI_LWO_VMAD AI_IFF_FOURCC('V','M','A','D') +#define AI_LWO_POLS AI_IFF_FOURCC('P','O','L','S') +#define AI_LWO_PTAG AI_IFF_FOURCC('P','T','A','G') +#define AI_LWO_ENVL AI_IFF_FOURCC('E','N','V','L') +#define AI_LWO_CLIP AI_IFF_FOURCC('C','L','I','P') +#define AI_LWO_SURF AI_IFF_FOURCC('S','U','R','F') +#define AI_LWO_DESC AI_IFF_FOURCC('D','E','S','C') +#define AI_LWO_TEXT AI_IFF_FOURCC('T','E','X','T') +#define AI_LWO_ICON AI_IFF_FOURCC('I','C','O','N') + +/* polygon types */ +#define AI_LWO_FACE AI_IFF_FOURCC('F','A','C','E') +#define AI_LWO_CURV AI_IFF_FOURCC('C','U','R','V') +#define AI_LWO_PTCH AI_IFF_FOURCC('P','T','C','H') +#define AI_LWO_MBAL AI_IFF_FOURCC('M','B','A','L') +#define AI_LWO_BONE AI_IFF_FOURCC('B','O','N','E') + +/* polygon tags */ +#define AI_LWO_SURF AI_IFF_FOURCC('S','U','R','F') +#define AI_LWO_PART AI_IFF_FOURCC('P','A','R','T') +#define AI_LWO_SMGP AI_IFF_FOURCC('S','M','G','P') + +/* envelopes */ +#define AI_LWO_PRE AI_IFF_FOURCC('P','R','E',' ') +#define AI_LWO_POST AI_IFF_FOURCC('P','O','S','T') +#define AI_LWO_KEY AI_IFF_FOURCC('K','E','Y',' ') +#define AI_LWO_SPAN AI_IFF_FOURCC('S','P','A','N') +#define AI_LWO_TCB AI_IFF_FOURCC('T','C','B',' ') +#define AI_LWO_HERM AI_IFF_FOURCC('H','E','R','M') +#define AI_LWO_BEZI AI_IFF_FOURCC('B','E','Z','I') +#define AI_LWO_BEZ2 AI_IFF_FOURCC('B','E','Z','2') +#define AI_LWO_LINE AI_IFF_FOURCC('L','I','N','E') +#define AI_LWO_STEP AI_IFF_FOURCC('S','T','E','P') + +/* clips */ +#define AI_LWO_STIL AI_IFF_FOURCC('S','T','I','L') +#define AI_LWO_ISEQ AI_IFF_FOURCC('I','S','E','Q') +#define AI_LWO_ANIM AI_IFF_FOURCC('A','N','I','M') +#define AI_LWO_XREF AI_IFF_FOURCC('X','R','E','F') +#define AI_LWO_STCC AI_IFF_FOURCC('S','T','C','C') +#define AI_LWO_TIME AI_IFF_FOURCC('T','I','M','E') +#define AI_LWO_CONT AI_IFF_FOURCC('C','O','N','T') +#define AI_LWO_BRIT AI_IFF_FOURCC('B','R','I','T') +#define AI_LWO_SATR AI_IFF_FOURCC('S','A','T','R') +#define AI_LWO_HUE AI_IFF_FOURCC('H','U','E',' ') +#define AI_LWO_GAMM AI_IFF_FOURCC('G','A','M','M') +#define AI_LWO_NEGA AI_IFF_FOURCC('N','E','G','A') +#define AI_LWO_IFLT AI_IFF_FOURCC('I','F','L','T') +#define AI_LWO_PFLT AI_IFF_FOURCC('P','F','L','T') + +/* surfaces */ +#define AI_LWO_COLR AI_IFF_FOURCC('C','O','L','R') +#define AI_LWO_LUMI AI_IFF_FOURCC('L','U','M','I') +#define AI_LWO_DIFF AI_IFF_FOURCC('D','I','F','F') +#define AI_LWO_SPEC AI_IFF_FOURCC('S','P','E','C') +#define AI_LWO_GLOS AI_IFF_FOURCC('G','L','O','S') +#define AI_LWO_REFL AI_IFF_FOURCC('R','E','F','L') +#define AI_LWO_RFOP AI_IFF_FOURCC('R','F','O','P') +#define AI_LWO_RIMG AI_IFF_FOURCC('R','I','M','G') +#define AI_LWO_RSAN AI_IFF_FOURCC('R','S','A','N') +#define AI_LWO_TRAN AI_IFF_FOURCC('T','R','A','N') +#define AI_LWO_TROP AI_IFF_FOURCC('T','R','O','P') +#define AI_LWO_TIMG AI_IFF_FOURCC('T','I','M','G') +#define AI_LWO_RIND AI_IFF_FOURCC('R','I','N','D') +#define AI_LWO_TRNL AI_IFF_FOURCC('T','R','N','L') +#define AI_LWO_BUMP AI_IFF_FOURCC('B','U','M','P') +#define AI_LWO_SMAN AI_IFF_FOURCC('S','M','A','N') +#define AI_LWO_SIDE AI_IFF_FOURCC('S','I','D','E') +#define AI_LWO_CLRH AI_IFF_FOURCC('C','L','R','H') +#define AI_LWO_CLRF AI_IFF_FOURCC('C','L','R','F') +#define AI_LWO_ADTR AI_IFF_FOURCC('A','D','T','R') +#define AI_LWO_SHRP AI_IFF_FOURCC('S','H','R','P') +#define AI_LWO_LINE AI_IFF_FOURCC('L','I','N','E') +#define AI_LWO_LSIZ AI_IFF_FOURCC('L','S','I','Z') +#define AI_LWO_ALPH AI_IFF_FOURCC('A','L','P','H') +#define AI_LWO_AVAL AI_IFF_FOURCC('A','V','A','L') +#define AI_LWO_GVAL AI_IFF_FOURCC('G','V','A','L') +#define AI_LWO_BLOK AI_IFF_FOURCC('B','L','O','K') + +/* texture layer */ +#define AI_LWO_TYPE AI_IFF_FOURCC('T','Y','P','E') +#define AI_LWO_CHAN AI_IFF_FOURCC('C','H','A','N') +#define AI_LWO_NAME AI_IFF_FOURCC('N','A','M','E') +#define AI_LWO_ENAB AI_IFF_FOURCC('E','N','A','B') +#define AI_LWO_OPAC AI_IFF_FOURCC('O','P','A','C') +#define AI_LWO_FLAG AI_IFF_FOURCC('F','L','A','G') +#define AI_LWO_PROJ AI_IFF_FOURCC('P','R','O','J') +#define AI_LWO_STCK AI_IFF_FOURCC('S','T','C','K') +#define AI_LWO_TAMP AI_IFF_FOURCC('T','A','M','P') + +/* texture coordinates */ +#define AI_LWO_TMAP AI_IFF_FOURCC('T','M','A','P') +#define AI_LWO_AXIS AI_IFF_FOURCC('A','X','I','S') +#define AI_LWO_CNTR AI_IFF_FOURCC('C','N','T','R') +#define AI_LWO_SIZE AI_IFF_FOURCC('S','I','Z','E') +#define AI_LWO_ROTA AI_IFF_FOURCC('R','O','T','A') +#define AI_LWO_OREF AI_IFF_FOURCC('O','R','E','F') +#define AI_LWO_FALL AI_IFF_FOURCC('F','A','L','L') +#define AI_LWO_CSYS AI_IFF_FOURCC('C','S','Y','S') + +/* image map */ +#define AI_LWO_IMAP AI_IFF_FOURCC('I','M','A','P') +#define AI_LWO_IMAG AI_IFF_FOURCC('I','M','A','G') +#define AI_LWO_WRAP AI_IFF_FOURCC('W','R','A','P') +#define AI_LWO_WRPW AI_IFF_FOURCC('W','R','P','W') +#define AI_LWO_WRPH AI_IFF_FOURCC('W','R','P','H') +#define AI_LWO_VMAP AI_IFF_FOURCC('V','M','A','P') +#define AI_LWO_AAST AI_IFF_FOURCC('A','A','S','T') +#define AI_LWO_PIXB AI_IFF_FOURCC('P','I','X','B') + +/* procedural */ +#define AI_LWO_PROC AI_IFF_FOURCC('P','R','O','C') +#define AI_LWO_COLR AI_IFF_FOURCC('C','O','L','R') +#define AI_LWO_VALU AI_IFF_FOURCC('V','A','L','U') +#define AI_LWO_FUNC AI_IFF_FOURCC('F','U','N','C') +#define AI_LWO_FTPS AI_IFF_FOURCC('F','T','P','S') +#define AI_LWO_ITPS AI_IFF_FOURCC('I','T','P','S') +#define AI_LWO_ETPS AI_IFF_FOURCC('E','T','P','S') + +/* gradient */ +#define AI_LWO_GRAD AI_IFF_FOURCC('G','R','A','D') +#define AI_LWO_GRST AI_IFF_FOURCC('G','R','S','T') +#define AI_LWO_GREN AI_IFF_FOURCC('G','R','E','N') +#define AI_LWO_PNAM AI_IFF_FOURCC('P','N','A','M') +#define AI_LWO_INAM AI_IFF_FOURCC('I','N','A','M') +#define AI_LWO_GRPT AI_IFF_FOURCC('G','R','P','T') +#define AI_LWO_FKEY AI_IFF_FOURCC('F','K','E','Y') +#define AI_LWO_IKEY AI_IFF_FOURCC('I','K','E','Y') + +/* shader */ +#define AI_LWO_SHDR AI_IFF_FOURCC('S','H','D','R') +#define AI_LWO_DATA AI_IFF_FOURCC('D','A','T','A') + + +// --------------------------------------------------------------------------- +/** \brief Data structure for a face in a LWO file + */ +struct Face : public aiFace +{ + Face() : surfaceIndex(0) {} + unsigned int surfaceIndex; +}; + + + +// --------------------------------------------------------------------------- +/** \brief Data structure for a LWO file texture + */ +struct Texture +{ + Texture() + : mStrength(1.0f) + {} + + //! File name of the texture + std::string mFileName; + + //! Strength of the texture + float mStrength; +}; + + +// --------------------------------------------------------------------------- +/** \brief Data structure for a LWO file surface (= material) + */ +struct Surface +{ + Surface() + : bDoubleSided (false) + , mDiffuseValue (1.0f) + , mSpecularValue (1.0f) + , mTransparency (0.0f) + , mGlossiness (0.0f) + , mMaximumSmoothAngle (90.0f) + {} + + //! Name of the surface + std::string mName; + + //! Color of the surface + aiColor3D mColor; + + //! true for two-sided materials + bool bDoubleSided; + + //! Various material parameters + float mDiffuseValue,mSpecularValue,mTransparency,mGlossiness; + + //! Maximum angle between two adjacent triangles + //! that they can be smoothed + float mMaximumSmoothAngle; + + //! Textures + Texture mColorTexture,mDiffuseTexture,mSpecularTexture, + mBumpTexture,mTransparencyTexture; +}; + +}} + + +#endif // !! AI_LWO_FILEDATA_INCLUDED + diff --git a/code/LWOLoader.cpp b/code/LWOLoader.cpp new file mode 100644 index 000000000..a9f56bb69 --- /dev/null +++ b/code/LWOLoader.cpp @@ -0,0 +1,487 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (ASSIMP) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2008, ASSIMP Development 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 Development 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. +--------------------------------------------------------------------------- +*/ + +/** @file Implementation of the LWO importer class */ + +// internal headers +#include "LWOLoader.h" +#include "MaterialSystem.h" +#include "ByteSwap.h" + +// public assimp headers +#include "../include/IOStream.h" +#include "../include/IOSystem.h" +#include "../include/aiMesh.h" +#include "../include/aiScene.h" +#include "../include/aiAssert.h" +#include "../include/DefaultLogger.h" + +// boost headers +#include + +using namespace Assimp; + + +// ------------------------------------------------------------------------------------------------ +// Constructor to be privately used by Importer +LWOImporter::LWOImporter() +{ +} + +// ------------------------------------------------------------------------------------------------ +// Destructor, private as well +LWOImporter::~LWOImporter() +{ + mFaces.clear(); + mTempPoints.clear(); + mSurfaces.clear(); +} + +// ------------------------------------------------------------------------------------------------ +// Returns whether the class can handle the format of the given file. +bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const +{ + // simple check of file extension is enough for the moment + std::string::size_type pos = pFile.find_last_of('.'); + // no file extension - can't read + if( pos == std::string::npos)return false; + std::string extension = pFile.substr( pos); + + if (extension.length() < 4)return false; + if (extension[0] != '.')return false; + + if (extension[1] != 'l' && extension[1] != 'L')return false; + if (extension[2] != 'w' && extension[2] != 'W')return false; + if (extension[3] != 'o' && extension[3] != 'O')return false; + + return true; +} +// ------------------------------------------------------------------------------------------------ +// Imports the given file into the given scene structure. +void LWOImporter::InternReadFile( const std::string& pFile, + aiScene* pScene, + IOSystem* pIOHandler) +{ + boost::scoped_ptr file( pIOHandler->Open( pFile, "rb")); + + // Check whether we can read from the file + if( file.get() == NULL) + throw new ImportErrorException( "Failed to open LWO file " + pFile + "."); + + if((this->fileSize = (unsigned int)file->FileSize()) < 12) + throw new ImportErrorException("LWO: The file is too small to contain the IFF header"); + + // allocate storage and copy the contents of the file to a memory buffer + std::vector< uint8_t > mBuffer(fileSize); + file->Read( &mBuffer[0], 1, fileSize); + this->pScene = pScene; + + // determine the type of the file + uint32_t fileType; + const char* sz = IFF::ReadHeader(&mBuffer[0],fileType); + if (sz)throw new ImportErrorException(sz); + + mFileBuffer = &mBuffer[0] + 12; + fileSize -= 12; + + try + { + // old lightwave file format (prior to v6) + if (AI_LWO_FOURCC_LWOB == fileType) + this->LoadLWOBFile(); + // new lightwave format + else if (AI_LWO_FOURCC_LWO2 == fileType) + this->LoadLWO2File(); + // we don't know this format + else + { + char szBuff[5]; + szBuff[0] = (char)(fileType >> 24u); + szBuff[1] = (char)(fileType >> 16u); + szBuff[2] = (char)(fileType >> 8u); + szBuff[3] = (char)(fileType); + throw new ImportErrorException(std::string("Unknown LWO sub format: ") + szBuff); + } + + // generate a default surface if necessary + if (mSurfaces.empty()) + mSurfaces.push_back(LWO::Surface()); + + // now sort all faces by the surfaces assigned to them + typedef std::vector SortedRep; + std::vector pSorted(mSurfaces.size()); + + unsigned int i = 0; + for (FaceList::iterator it = mFaces.begin(), end = mFaces.end(); + it != end;++it,++i) + { + if ((*it).surfaceIndex >= mSurfaces.size()) + { + DefaultLogger::get()->warn("LWO: Invalid face surface index"); + (*it).surfaceIndex = mSurfaces.size()-1; + } + pSorted[(*it).surfaceIndex].push_back(i); + } + + // now generate output meshes + for (unsigned int p = 0; p < mSurfaces.size();++p) + if (!pSorted[p].empty())pScene->mNumMeshes++; + + if (!(pScene->mNumMaterials = pScene->mNumMeshes)) + throw new ImportErrorException("LWO: There are no meshes"); + + pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; + pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; + for (unsigned int p = 0,i = 0;i < mSurfaces.size();++i) + { + SortedRep& sorted = pSorted[i]; + if (sorted.empty())continue; + + // generate the mesh + aiMesh* mesh = pScene->mMeshes[p] = new aiMesh(); + mesh->mNumFaces = sorted.size(); + + for (SortedRep::const_iterator it = sorted.begin(), end = sorted.end(); + it != end;++it) + { + mesh->mNumVertices += mFaces[*it].mNumIndices; + } + + mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + mesh->mFaces = new aiFace[mesh->mNumFaces]; + mesh->mMaterialIndex = p; + + // now convert all faces + unsigned int vert = 0; + for (SortedRep::const_iterator it = sorted.begin(), end = sorted.end(); + it != end;++it) + { + LWO::Face& face = mFaces[*it]; + + // copy all vertices + for (unsigned int q = 0; q < face.mNumIndices;++q) + { + *mesh->mVertices++ = mTempPoints[face.mIndices[q]]; + face.mIndices[q] = vert++; + } + + mesh->mFaces->mIndices = face.mIndices; + mesh->mFaces->mNumIndices = face.mNumIndices; + face.mIndices = NULL; // make sure it won't be deleted + + mesh->mFaces++; + } + mesh->mFaces -= mesh->mNumFaces; + mesh->mVertices -= mesh->mNumVertices; + + // generate the corresponding material + MaterialHelper* pcMat = new MaterialHelper(); + pScene->mMaterials[p] = pcMat; + + // todo + + ++p; + } + } + // make sure the arrays are cleaned up ... + catch (ImportErrorException* ex) + { + this->~LWOImporter(); + throw ex; + } + this->~LWOImporter(); +} +// ------------------------------------------------------------------------------------------------ +void LWOImporter::CountVertsAndFaces(unsigned int& verts, unsigned int& faces, + LE_NCONST uint8_t*& cursor, const uint8_t* const end, unsigned int max) +{ + while (cursor < end && max--) + { + uint16_t numIndices = *((uint16_t*)cursor);cursor+=2; + verts += numIndices;faces++; + cursor += numIndices*2; + int16_t surface = *((uint16_t*)cursor);cursor+=2; + if (surface < 0) + { + // there are detail polygons + numIndices = *((uint16_t*)cursor);cursor+=2; + CountVertsAndFaces(verts,faces,cursor,end,numIndices); + } + } +} +// ------------------------------------------------------------------------------------------------ +void LWOImporter::CopyFaceIndices(LWOImporter::FaceList::iterator& it,LE_NCONST uint8_t*& cursor, + const uint8_t* const end, unsigned int max) +{ + while (cursor < end && max--) + { + LWO::Face& face = *it;++it; + face.mNumIndices = *((uint16_t*)cursor); + if (cursor + face.mNumIndices*2 + 4 >= end)break; + face.mIndices = new unsigned int[face.mNumIndices]; + for (unsigned int i = 0; i < face.mNumIndices;++i) + { + face.mIndices[i] = *((uint16_t*)(cursor+=2)); + if (face.mIndices[i] >= mTempPoints.size()) + { + face.mIndices[i] = mTempPoints.size()-1; + DefaultLogger::get()->warn("LWO: Face index is out of range"); + } + } + cursor+=2; + int16_t surface = *((uint16_t*)cursor);cursor+=2; + if (surface < 0) + { + surface *= -1; + + // there are detail polygons + uint16_t numPolygons = *((uint16_t*)cursor);cursor+=2; + if (cursor < end)CopyFaceIndices(it,cursor,end,numPolygons); + } + face.surfaceIndex = surface-1; + } +} +// ------------------------------------------------------------------------------------------------ +void LWOImporter::LoadLWOBSurface(unsigned int size) +{ + uint32_t iCursor = 0; + mSurfaces.push_back( LWO::Surface () ); + LWO::Surface& surf = mSurfaces.back(); + LWO::Texture* pTex = NULL; + + // at first we'll need to read the name of the surface + const uint8_t* sz = mFileBuffer; + while (*mFileBuffer) + { + if (++iCursor > size)throw new ImportErrorException("LWOB: Invalid file, surface name is too long"); + ++mFileBuffer; + } + unsigned int len = unsigned int (mFileBuffer-sz); + surf.mName = std::string((const char*)sz,len); + mFileBuffer += 1-(len & 1); // skip one byte if the length of the string is odd + while (true) + { + if ((iCursor += sizeof(IFF::ChunkHeader)) > size)break; + LE_NCONST IFF::ChunkHeader* head = (LE_NCONST IFF::ChunkHeader*)mFileBuffer; + AI_LSWAP4(head->length); + AI_LSWAP4(head->type); + if ((iCursor += head->length) > size) + { + throw new ImportErrorException("LWOB: Invalid file, the size attribute of " + "a surface sub chunk points behind the end of the file"); + } + mFileBuffer += sizeof(IFF::ChunkHeader); + switch (head->type) + { + // diffuse color + case AI_LWO_COLR: + { + if (head->length < 3) + { + DefaultLogger::get()->warn("LWO: COLR chunk is expected to be at least 3 bytes in size"); + break; + } + surf.mColor.r = *mFileBuffer++ / 255.0f; + surf.mColor.g = *mFileBuffer++ / 255.0f; + surf.mColor.b = *mFileBuffer / 255.0f; + break; + } + // diffuse strength ... hopefully + case AI_LWO_DIFF: + { + AI_LSWAP2(mFileBuffer); + surf.mDiffuseValue = *((int16_t*)mFileBuffer) / 255.0f; + break; + } + // specular strength ... hopefully + case AI_LWO_SPEC: + { + AI_LSWAP2(mFileBuffer); + surf.mSpecularValue = *((int16_t*)mFileBuffer) / 255.0f; + break; + } + // transparency + case AI_LWO_TRAN: + { + AI_LSWAP2(mFileBuffer); + surf.mTransparency = *((int16_t*)mFileBuffer) / 255.0f; + break; + } + // glossiness + case AI_LWO_GLOS: + { + AI_LSWAP2(mFileBuffer); + surf.mGlossiness = float(*((int16_t*)mFileBuffer)); + break; + } + // color texture + case AI_LWO_CTEX: + { + pTex = &surf.mColorTexture; + break; + } + // diffuse texture + case AI_LWO_DTEX: + { + pTex = &surf.mDiffuseTexture; + break; + } + // specular texture + case AI_LWO_STEX: + { + pTex = &surf.mSpecularTexture; + break; + } + // bump texture + case AI_LWO_BTEX: + { + pTex = &surf.mBumpTexture; + break; + } + // transparency texture + case AI_LWO_TTEX: + { + pTex = &surf.mTransparencyTexture; + break; + } + // texture path + case AI_LWO_TIMG: + { + if (pTex) + { + unsigned int iCursor = 0; + while (*mFileBuffer) + { + if (++iCursor > head->length) + { + DefaultLogger::get()->warn("LWOB: Invalid file, texture name (TIMG) is too long"); + break; + } + ++mFileBuffer; + } + unsigned int len = unsigned int (mFileBuffer-sz); + pTex->mFileName = std::string((const char*)sz,len); + } + else DefaultLogger::get()->warn("LWOB: TIMG tag was encuntered although " + "there was no xTEX tag before"); + break; + } + // texture strength + case AI_LWO_TVAL: + { + if (pTex)pTex->mStrength = *mFileBuffer / 255.0f; + else DefaultLogger::get()->warn("LWOB: TVAL tag was encuntered " + "although there was no xTEX tag before"); + break; + } + } + mFileBuffer += head->length; + } +} +// ------------------------------------------------------------------------------------------------ +void LWOImporter::LoadLWOBFile() +{ + uint32_t iCursor = 0; + while (true) + { + if ((iCursor += sizeof(IFF::ChunkHeader)) > this->fileSize)break; + LE_NCONST IFF::ChunkHeader* head = (LE_NCONST IFF::ChunkHeader*)mFileBuffer; + AI_LSWAP4(head->length); + AI_LSWAP4(head->type); + if ((iCursor += head->length) > this->fileSize) + { + //throw new ImportErrorException("LWOB: Invalid file, the size attribute of " + // "a chunk points behind the end of the file"); + break; + } + mFileBuffer += sizeof(IFF::ChunkHeader); + switch (head->type) + { + // vertex list + case AI_LWO_PNTS: + { + mTempPoints.resize( head->length / 12 ); +#ifndef AI_BUILD_BIG_ENDIAN + for (unsigned int i = 0; i < head->length>>2;++i) + ByteSwap::Swap4( mFileBuffer + (i << 2)); +#endif + ::memcpy(&mTempPoints[0],mFileBuffer,head->length); + break; + } + // face list + case AI_LWO_POLS: + { + // first find out how many faces and vertices we'll finally need + const uint8_t* const end = mFileBuffer + head->length; + LE_NCONST uint8_t* cursor = mFileBuffer; + +#ifndef AI_BUILD_BIG_ENDIAN + while (cursor < end)ByteSwap::Swap2(cursor++); + cursor = mFileBuffer; +#endif + + unsigned int iNumFaces = 0,iNumVertices = 0; + CountVertsAndFaces(iNumVertices,iNumFaces,cursor,end); + + // allocate the output array and copy face indices + if (iNumFaces) + { + this->mTempPoints.resize(iNumVertices); + this->mFaces.resize(iNumFaces); + FaceList::iterator it = this->mFaces.begin(); + CopyFaceIndices(it,mFileBuffer,end); + } + break; + } + // surface chunk + case AI_LWO_SURF: + { + LoadLWOBSurface(head->length); + break; + } + } + mFileBuffer += head->length; + } +} +// ------------------------------------------------------------------------------------------------ +void LWOImporter::LoadLWO2File() +{ +} \ No newline at end of file diff --git a/code/LWOLoader.h b/code/LWOLoader.h new file mode 100644 index 000000000..c102c199c --- /dev/null +++ b/code/LWOLoader.h @@ -0,0 +1,158 @@ +/* +Open Asset Import Library (ASSIMP) +---------------------------------------------------------------------- + +Copyright (c) 2006-2008, ASSIMP Development 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 Development 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. + +---------------------------------------------------------------------- +*/ + +/** @file Declaration of the LWO importer class. */ +#ifndef AI_LWOLOADER_H_INCLUDED +#define AI_LWOLOADER_H_INCLUDED + +#include "../include/aiTypes.h" + +#include "BaseImporter.h" +#include "LWOFileData.h" + +#include + +namespace Assimp { +using namespace LWO; + +// --------------------------------------------------------------------------- +/** Clas to load LWO files +*/ +class LWOImporter : public BaseImporter +{ + friend class Importer; + +protected: + /** Constructor to be privately used by Importer */ + LWOImporter(); + + /** Destructor, private as well */ + ~LWOImporter(); + +public: + + // ------------------------------------------------------------------- + /** Returns whether the class can handle the format of the given file. + * See BaseImporter::CanRead() for details. */ + bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const; + +protected: + + // ------------------------------------------------------------------- + /** Called by Importer::GetExtensionList() for each loaded importer. + * See BaseImporter::GetExtensionList() for details + */ + void GetExtensionList(std::string& append) + { + append.append("*.lwo"); + } + + // ------------------------------------------------------------------- + /** Imports the given file into the given scene structure. + * See BaseImporter::InternReadFile() for details + */ + void InternReadFile( const std::string& pFile, aiScene* pScene, + IOSystem* pIOHandler); + + + // ------------------------------------------------------------------- + /** Loads a LWO file in the older LWOB format (LW < 6) + */ + void LoadLWOBFile(); + + // ------------------------------------------------------------------- + /** Loads a LWO file in the newer LWO2 format (LW >= 6) + */ + void LoadLWO2File(); + + // ------------------------------------------------------------------- + /** Loads a surface chunk from an LWOB file + */ + void LoadLWOBSurface(unsigned int size); + + + typedef std::vector PointList; + typedef std::vector FaceList; + typedef std::vector SurfaceList; + +private: + + // ------------------------------------------------------------------- + /** Count vertices and faces in a LWOB file + */ + void CountVertsAndFaces(unsigned int& verts, + unsigned int& faces, + LE_NCONST uint8_t*& cursor, + const uint8_t* const end, + unsigned int max = 0xffffffff); + + // ------------------------------------------------------------------- + /** Read vertices and faces in a LWOB file + */ + void CopyFaceIndices(FaceList::iterator& it, + LE_NCONST uint8_t*& cursor, + const uint8_t* const end, + unsigned int max = 0xffffffff); + +protected: + + /** Temporary point list from the file */ + PointList mTempPoints; + + /** Temporary face list from the file*/ + FaceList mFaces; + + /** Temporary surface list from the file */ + SurfaceList mSurfaces; + + /** file buffer */ + LE_NCONST uint8_t* mFileBuffer; + + /** Size of the file, in bytes */ + unsigned int fileSize; + + /** Output scene */ + aiScene* pScene; + +}; + +} // end of namespace Assimp + +#endif // AI_LWOIMPORTER_H_INCLUDED \ No newline at end of file diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index 71d30f37f..d700818d7 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -347,6 +347,7 @@ bool STLImporter::LoadBinaryFile() sz += sizeof(aiVector3D); *(vn+1) = *vn; *(vn+2) = *vn; + vn += 3; *vp++ = *((aiVector3D*)sz); sz += sizeof(aiVector3D); diff --git a/workspaces/vc8/assimp.vcproj b/workspaces/vc8/assimp.vcproj index 3d1dec99b..095ab6c00 100644 --- a/workspaces/vc8/assimp.vcproj +++ b/workspaces/vc8/assimp.vcproj @@ -734,6 +734,10 @@ RelativePath="..\..\code\Hash.h" > + + @@ -1042,6 +1046,18 @@ > + + + + + + + + + +