From 9d167d20dcfde925ac906e9fc12db5ad5da8d358 Mon Sep 17 00:00:00 2001 From: aramis_acg Date: Sat, 13 Sep 2008 11:11:51 +0000 Subject: [PATCH] LWO2 partial support, makefile fix. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@135 67173fc5-114c-0410-ac8e-9d2fd5bffc1f --- code/LWOBLoader.cpp | 33 +++- code/LWOFileData.h | 2 +- code/LWOLoader.cpp | 179 ++++++++---------- code/LWOLoader.h | 15 +- code/LWOMaterial.cpp | 2 +- code/makefile | 7 + .../LWO2/sphere_with_mat_gloss_10pc.lwo | Bin 0 -> 7584 bytes 7 files changed, 130 insertions(+), 108 deletions(-) create mode 100644 test/LWOFiles/LWO2/sphere_with_mat_gloss_10pc.lwo diff --git a/code/LWOBLoader.cpp b/code/LWOBLoader.cpp index cfab9473b..100d278be 100644 --- a/code/LWOBLoader.cpp +++ b/code/LWOBLoader.cpp @@ -89,7 +89,7 @@ void LWOImporter::LoadLWOBFile() { if (!mCurLayer->mFaces.empty()) DefaultLogger::get()->warn("LWO: POLS chunk encountered twice"); - else LoadLWOPolygons(head->length); + else LoadLWOBPolygons(head->length); break; } // list of tags @@ -104,9 +104,7 @@ void LWOImporter::LoadLWOBFile() // surface chunk case AI_LWO_SURF: { - if (!mSurfaces->empty()) - DefaultLogger::get()->warn("LWO: SURF chunk encountered twice"); - else LoadLWOBSurface(head->length); + LoadLWOBSurface(head->length); break; } } @@ -114,6 +112,33 @@ void LWOImporter::LoadLWOBFile() } } +// ------------------------------------------------------------------------------------------------ +void LWOImporter::LoadLWOBPolygons(unsigned int length) +{ + // first find out how many faces and vertices we'll finally need + LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length); + LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer; + + // perform endianess conversions +#ifndef AI_BUILD_BIG_ENDIAN + while (cursor < end)ByteSwap::Swap2(cursor++); + cursor = (LE_NCONST uint16_t*)mFileBuffer; +#endif + + unsigned int iNumFaces = 0,iNumVertices = 0; + CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end); + + // allocate the output array and copy face indices + if (iNumFaces) + { + cursor = (LE_NCONST uint16_t*)mFileBuffer; + + mCurLayer->mFaces.resize(iNumFaces); + FaceList::iterator it = mCurLayer->mFaces.begin(); + CopyFaceIndicesLWOB(it,cursor,end); + } +} + // ------------------------------------------------------------------------------------------------ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces, LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max) diff --git a/code/LWOFileData.h b/code/LWOFileData.h index 82b21aaf7..cc0c1cc3b 100644 --- a/code/LWOFileData.h +++ b/code/LWOFileData.h @@ -427,7 +427,7 @@ struct Layer Layer() : mFaceIDXOfs(0) , mPointIDXOfs(0) - , mParent (0xffff) + , mParent (0x0) {} /** Temporary point list from the file */ diff --git a/code/LWOLoader.cpp b/code/LWOLoader.cpp index e0db97dcd..a602fbff0 100644 --- a/code/LWOLoader.cpp +++ b/code/LWOLoader.cpp @@ -325,7 +325,7 @@ void LWOImporter::InternReadFile( const std::string& pFile, aiNode* pcNode = new aiNode(); apcNodes.push_back(pcNode); pcNode->mName.Set(layer.mName); - pcNode->mParent = reinterpret_cast(layer.mParent); + pcNode->mParent = (aiNode*)(uintptr_t)(layer.mParent); pcNode->mNumMeshes = (unsigned int)apcMeshes.size() - meshStart; pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes]; for (unsigned int p = 0; p < pcNode->mNumMeshes;++p) @@ -341,58 +341,87 @@ void LWOImporter::InternReadFile( const std::string& pFile, ConvertMaterial((*mSurfaces)[mat],pcMat); } - // generate the final node graph - GenerateNodeGraph(apcNodes); - // copy the meshes to the output structure if (apcMeshes.size()) // shouldn't occur, just to be sure we don't crash { pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = (unsigned int)apcMeshes.size() ]; ::memcpy(pScene->mMeshes,&apcMeshes[0],pScene->mNumMeshes*sizeof(void*)); } + + // generate the final node graph + GenerateNodeGraph(apcNodes); +} + +// ------------------------------------------------------------------------------------------------ +void LWOImporter::AddChildren(aiNode* node, uintptr_t parent, std::vector& apcNodes) +{ + unsigned int numChilds = 0; + + for (uintptr_t i = 0; i < (uintptr_t)apcNodes.size();++i) + { + if (i == parent)continue; + if (apcNodes[i] && (uintptr_t)apcNodes[i]->mParent == parent)++node->mNumChildren; + } + + if (node->mNumChildren) + { + node->mChildren = new aiNode* [ node->mNumChildren ]; + for (uintptr_t i = 0, p = 0; i < (uintptr_t)apcNodes.size();++i) + { + if (i == parent)continue; + + if (apcNodes[i] && parent == (uintptr_t)(apcNodes[i]->mParent)) + { + node->mChildren[p++] = apcNodes[i]; + apcNodes[i]->mParent = node; + + // recursively add more children + AddChildren(apcNodes[i],i,apcNodes); + apcNodes[i] = NULL; + } + } + } } // ------------------------------------------------------------------------------------------------ void LWOImporter::GenerateNodeGraph(std::vector& apcNodes) { - // now generate the final nodegraph - uint16_t curIndex = 0; - while (curIndex < (uint16_t)apcNodes.size()) - { - aiNode* node; - uint16_t iCurParent = curIndex-1; - node = curIndex ? apcNodes[iCurParent] : new aiNode(""); - if (!node){++curIndex;continue;} + // now generate the final nodegraph - generate a root node + pScene->mRootNode = new aiNode(); + pScene->mRootNode->mName.Set(""); + AddChildren(pScene->mRootNode,0,apcNodes); - unsigned int numChilds = 0; + unsigned int extra = 0; + for (unsigned int i = 0; i < apcNodes.size();++i) + if (apcNodes[i] && apcNodes[i]->mNumMeshes)++extra; + + if (extra) + { + // we need to add extra nodes to the root + const unsigned int newSize = extra + pScene->mRootNode->mNumChildren; + aiNode** const apcNewNodes = new aiNode*[newSize]; + if((extra = pScene->mRootNode->mNumChildren)) + ::memcpy(apcNewNodes,pScene->mRootNode->mChildren,extra*sizeof(void*)); + + aiNode** cc = apcNewNodes+extra; for (unsigned int i = 0; i < apcNodes.size();++i) { - if (i == iCurParent)continue; - if ( (uint16_t)(uintptr_t)apcNodes[i]->mParent == iCurParent)++numChilds; - } - if (numChilds) - { - if (!pScene->mRootNode) + if (apcNodes[i] && apcNodes[i]->mNumMeshes) { - pScene->mRootNode = node; + *cc++ = apcNodes[i]; + apcNodes[i]->mParent = pScene->mRootNode; + + // recursively add more children + AddChildren(apcNodes[i],i,apcNodes); + apcNodes[i] = NULL; } - node->mChildren = new aiNode* [ node->mNumChildren = numChilds ]; - for (unsigned int i = 0, p = 0; i < apcNodes.size();++i) - { - if (i == iCurParent)continue; - uint16_t parent = (uint16_t)(uintptr_t)(apcNodes[i]->mParent); - if (parent == iCurParent) - { - node->mChildren[p++] = apcNodes[i]; - apcNodes[i]->mParent = node; - apcNodes[i] = NULL; - } - } - if (curIndex)apcNodes[iCurParent] = NULL; } - else if (!curIndex)delete node; - ++curIndex; + delete[] pScene->mRootNode->mChildren; + pScene->mRootNode->mChildren = apcNewNodes; + pScene->mRootNode->mNumChildren = newSize; } + if (!pScene->mRootNode->mNumChildren)throw new ImportErrorException("LWO: Unable to build a valid node graph"); + // remove a single root node // TODO: implement directly in the above loop, no need to deallocate here if (1 == pScene->mRootNode->mNumChildren) @@ -402,39 +431,6 @@ void LWOImporter::GenerateNodeGraph(std::vector& apcNodes) delete pScene->mRootNode; pScene->mRootNode = pc; } - - // add unreferenced nodes to a dummy root - unsigned int m = 0; - for (std::vector::iterator it = apcNodes.begin(), end = apcNodes.end(); - it != end;++it) - { - aiNode* p = *it; - if (p)++m; - } - if (m) - { - aiNode* pc = new aiNode(); - pc->mName.Set(""); - aiNode** cc = pc->mChildren = new aiNode*[ pc->mNumChildren = m+1 ]; - for (std::vector::iterator it = apcNodes.begin(), end = apcNodes.end(); - it != end;++it) - { - aiNode* p = *it; - if (p) - { - *cc++ = p; - p->mParent = pc; - } - } - if (pScene->mRootNode) - { - *cc = pScene->mRootNode; - pScene->mRootNode->mParent = pc; - } - else --pc->mNumChildren; - pScene->mRootNode = pc; - } - if (!pScene->mRootNode)throw new ImportErrorException("LWO: Unable to build a valid node graph"); } // ------------------------------------------------------------------------------------------------ @@ -546,34 +542,23 @@ void LWOImporter::LoadLWOPoints(unsigned int length) } // ------------------------------------------------------------------------------------------------ -void LWOImporter::LoadLWOPolygons(unsigned int length) +void LWOImporter::LoadLWO2Polygons(unsigned int length) { - // --- this function is used for both LWO2 and LWOB - if (mIsLWO2) - { - uint32_t type = *((LE_NCONST uint32_t*)mFileBuffer);mFileBuffer += 4; - AI_LSWAP4(type); + uint32_t type = *((LE_NCONST uint32_t*)mFileBuffer);mFileBuffer += 4;length-=4; + AI_LSWAP4(type); - if (type != AI_LWO_FACE) - { - DefaultLogger::get()->warn("LWO2: Only POLS.FACE chunsk are supported."); - return; - } + if (type != AI_LWO_FACE) + { + DefaultLogger::get()->warn("LWO2: Only POLS.FACE chunsk are supported."); + return; } // first find out how many faces and vertices we'll finally need LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length); LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer; - // perform endianess conversions -#ifndef AI_BUILD_BIG_ENDIAN - while (cursor < end)ByteSwap::Swap2(cursor++); - cursor = (LE_NCONST uint16_t*)mFileBuffer; -#endif - unsigned int iNumFaces = 0,iNumVertices = 0; - if (mIsLWO2)CountVertsAndFacesLWO2(iNumVertices,iNumFaces,cursor,end); - else CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end); + CountVertsAndFacesLWO2(iNumVertices,iNumFaces,cursor,end); // allocate the output array and copy face indices if (iNumFaces) @@ -582,8 +567,7 @@ void LWOImporter::LoadLWOPolygons(unsigned int length) mCurLayer->mFaces.resize(iNumFaces); FaceList::iterator it = mCurLayer->mFaces.begin(); - if (mIsLWO2)CopyFaceIndicesLWO2(it,cursor,end); - else CopyFaceIndicesLWOB(it,cursor,end); + CopyFaceIndicesLWO2(it,cursor,end); } } @@ -593,6 +577,7 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face { while (cursor < end && max--) { + AI_LSWAP2P(cursor); uint16_t numIndices = *cursor++; numIndices &= 0x03FF; verts += numIndices;++faces; @@ -605,16 +590,14 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face // ------------------------------------------------------------------------------------------------ void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it, LE_NCONST uint16_t*& cursor, - const uint16_t* const end, - unsigned int max) + const uint16_t* const end) { - while (cursor < end && max--) + while (cursor < end) { LWO::Face& face = *it;++it; - if((face.mNumIndices = (*cursor++) & 0x03FF)) + if((face.mNumIndices = (*cursor++) & 0x03FF)) // swapping has already been done { face.mIndices = new unsigned int[face.mNumIndices]; - for(unsigned int i = 0; i < face.mNumIndices; i++) { face.mIndices[i] = ReadVSizedIntLWO2((uint8_t*&)cursor) + mCurLayer->mPointIDXOfs; @@ -794,7 +777,7 @@ void LWOImporter::LoadLWO2File() case AI_LWO_POLS: { unsigned int old = (unsigned int)mCurLayer->mFaces.size(); - LoadLWOPolygons(head->length); + LoadLWO2Polygons(head->length); mCurLayer->mFaceIDXOfs = old; break; } @@ -807,7 +790,7 @@ void LWOImporter::LoadLWO2File() break; } // list of tags - case AI_LWO_SRFS: + case AI_LWO_TAGS: { if (!mTags->empty()) DefaultLogger::get()->warn("LWO2: SRFS chunk encountered twice"); @@ -818,9 +801,7 @@ void LWOImporter::LoadLWO2File() // surface chunk case AI_LWO_SURF: { - if (!mSurfaces->empty()) - DefaultLogger::get()->warn("LWO2: SURF chunk encountered twice"); - else LoadLWO2Surface(head->length); + LoadLWO2Surface(head->length); break; } } diff --git a/code/LWOLoader.h b/code/LWOLoader.h index e2a35f449..f33c19120 100644 --- a/code/LWOLoader.h +++ b/code/LWOLoader.h @@ -161,7 +161,8 @@ private: /** Load polygons from a POLS chunk * @param length Size of the chunk */ - void LoadLWOPolygons(unsigned int length); + void LoadLWO2Polygons(unsigned int length); + void LoadLWOBPolygons(unsigned int length); // ------------------------------------------------------------------- /** Load polygon tags from a PTAG chunk @@ -203,8 +204,7 @@ private: */ void CopyFaceIndicesLWO2(LWO::FaceList::iterator& it, LE_NCONST uint16_t*& cursor, - const uint16_t* const end, - unsigned int max = 0xffffffff); + const uint16_t* const end); void CopyFaceIndicesLWOB(LWO::FaceList::iterator& it, LE_NCONST uint16_t*& cursor, @@ -256,6 +256,15 @@ private: */ void GenerateNodeGraph(std::vector& apcNodes); + // ------------------------------------------------------------------- + /** Add children to a node + * @param node Node to become a father + * @param parent Index of the node + * @param apcNodes Flat list of nodes - used nodes are set to NULL. + */ + void AddChildren(aiNode* node, uintptr_t parent, + std::vector& apcNodes); + // ------------------------------------------------------------------- /** Read a variable sized integer * @param inout Input and output buffer diff --git a/code/LWOMaterial.cpp b/code/LWOMaterial.cpp index 26e4e518f..3f655aaf4 100644 --- a/code/LWOMaterial.cpp +++ b/code/LWOMaterial.cpp @@ -74,7 +74,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat // this is only an assumption, needs to be confirmed. // the values have been tweaked by hand and seem to be correct. float fGloss; - if (mIsLWO2)fGloss = surf.mGlossiness * 0.8f; + if (mIsLWO2)fGloss = surf.mGlossiness * 50.0f; else { if (16.0f >= surf.mGlossiness)fGloss = 6.0f; diff --git a/code/makefile b/code/makefile index 1d6c9672c..1bbdad60d 100644 --- a/code/makefile +++ b/code/makefile @@ -69,3 +69,10 @@ $(TARGET): $(OBJECTS) $(CXX) -g -Wall -c $? -o $@ -I../include -fPIC clean: rm -f $(OBJECTS) $(TARGET) + + +STATIC = ./../bin/libassimp.a +static: $(STATIC) +$(STATIC): $(OBJECTS) + ar rcs $@ $(OBJECTS) + diff --git a/test/LWOFiles/LWO2/sphere_with_mat_gloss_10pc.lwo b/test/LWOFiles/LWO2/sphere_with_mat_gloss_10pc.lwo new file mode 100644 index 0000000000000000000000000000000000000000..bb52c6c4265ef79e3758a3c95582f009481a64cb GIT binary patch literal 7584 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 literal 0 HcmV?d00001