diff --git a/code/3DSLoader.cpp b/code/3DSLoader.cpp index 212b1d868..b8fa232f6 100644 --- a/code/3DSLoader.cpp +++ b/code/3DSLoader.cpp @@ -1091,9 +1091,9 @@ void Dot3DSImporter::ParseMaterialChunk(int* piRemaining) pcf = &this->mScene->mMaterials.back().mTransparency; *pcf = this->ParsePercentageChunk(); // NOTE: transparency, not opacity - *pcf = 1.0f - *pcf; if (is_qnan(*pcf)) - *pcf = 0.0f; + *pcf = 1.0f; + else *pcf = 1.0f - *pcf * (float)0xFFFF / 100.0f; break; case Dot3DSFile::CHUNK_MAT_SHADING: @@ -1121,10 +1121,12 @@ void Dot3DSImporter::ParseMaterialChunk(int* piRemaining) break; case Dot3DSFile::CHUNK_MAT_SELF_ILPCT: + // TODO: need to multiply with emissive base color? pcf = &this->mScene->mMaterials.back().sTexEmissive.mTextureBlend; *pcf = this->ParsePercentageChunk(); if (is_qnan(*pcf)) - *pcf = 1.0f; + *pcf = 0.0f; + else *pcf = *pcf * (float)0xFFFF / 100.0f; break; // parse texture chunks diff --git a/code/ASELoader.cpp b/code/ASELoader.cpp index b1324666f..888382bb5 100644 --- a/code/ASELoader.cpp +++ b/code/ASELoader.cpp @@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ASELoader.h" #include "3DSSpatialSort.h" #include "MaterialSystem.h" +#include "fast_atof.h" #include "../include/IOStream.h" #include "../include/IOSystem.h" @@ -126,11 +127,23 @@ void ASEImporter::InternReadFile( this->mParser = new ASE::Parser((const char*)this->mBuffer); this->mParser->Parse(); + // the .ask file format contains normally three LODs of + // a single object. Named n, where n = 1 designates + // the highest level of detail. + if (this->mIsAsk) + { + this->AskFilterLOD(this->mParser->m_vMeshes); + } + // process all meshes + std::vector avOutMeshes; + avOutMeshes.reserve(this->mParser->m_vMeshes.size()*2); for (std::vector::iterator i = this->mParser->m_vMeshes.begin(); i != this->mParser->m_vMeshes.end();++i) { + if ((*i).bSkip)continue; + // transform all vertices into worldspace // world2obj transform is specified in the // transformation matrix of a scenegraph node @@ -144,8 +157,15 @@ void ASEImporter::InternReadFile( this->GenerateNormals(*i); // convert all meshes to aiMesh objects - this->ConvertMeshes(*i,pScene); + this->ConvertMeshes(*i,avOutMeshes); } + + // now build the output mesh list + pScene->mNumMeshes = avOutMeshes.size(); + pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; + for (unsigned int i = 0; i < pScene->mNumMeshes;++i) + pScene->mMeshes[i] = avOutMeshes[i]; + // buil final material indices (remove submaterials and make the final list) this->BuildMaterialIndices(pScene); @@ -158,69 +178,87 @@ void ASEImporter::InternReadFile( return; } // ------------------------------------------------------------------------------------------------ +void ASEImporter::AddNodes(aiScene* pcScene,aiNode* pcParent, + const char* szName) +{ + ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS); + std::vector apcNodes; + for (unsigned int i = 0; i < pcScene->mNumMeshes;++i) + { + // get the name of the mesh ([0] = name, [1] = parent) + std::string* szMyName = (std::string*)pcScene->mMeshes[i]->mColors[1]; + if (!szMyName) + { + continue; + } + if (szName) + { + if(0 != ASSIMP_stricmp ( szName, szMyName[1].c_str() )) + continue; + } + else if ('\0' != szMyName[1].c_str()[0])continue; + + apcNodes.push_back(new aiNode()); + aiNode* node = apcNodes.back(); + + // get the transformation matrix of the mesh + aiMatrix4x4* pmTransform = (aiMatrix4x4*)pcScene->mMeshes[i]->mColors[2]; + + node->mName.Set(szMyName[0]); + node->mNumMeshes = 1; + node->mMeshes = new unsigned int[1]; + node->mMeshes[0] = i; + node->mParent = pcParent; + node->mTransformation = *pmTransform; + + // delete the matrix (a mesh is always the child of ONE node, so this is safe) + delete pmTransform; + pcScene->mMeshes[i]->mColors[2] = NULL; + + delete[] szMyName; + pcScene->mMeshes[i]->mColors[1] = NULL; + + // add sub nodes + this->AddNodes(pcScene,node,node->mName.data); + } + + // allocate enough space for the child nodes + pcParent->mNumChildren = apcNodes.size(); + pcParent->mChildren = new aiNode*[apcNodes.size()]; + + // now build all nodes + for (unsigned int p = 0; p < apcNodes.size();++p) + { + pcParent->mChildren[p] = apcNodes[p]; + } + return; +} +// ------------------------------------------------------------------------------------------------ void ASEImporter::BuildNodes(aiScene* pcScene) { ai_assert(NULL != pcScene); + // allocate the root node pcScene->mRootNode = new aiNode(); pcScene->mRootNode->mNumMeshes = 0; pcScene->mRootNode->mMeshes = 0; + pcScene->mRootNode->mName.Set(""); - ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS); - std::vector > > stack; - stack.reserve(pcScene->mNumMeshes); - for (unsigned int i = 0; i < pcScene->mNumMeshes;++i) + // add all nodes + this->AddNodes(pcScene,pcScene->mRootNode,NULL); + + // if there is only one subnode, set it as root node + if (1 == pcScene->mRootNode->mNumChildren) { - // get the transformation matrix of the node - aiMatrix4x4* pmTransform = (aiMatrix4x4*)pcScene->mMeshes[i]->mColors[2]; - - // search for an identical matrix in our list - for (std::vector > >::iterator - a = stack.begin(); - a != stack.end();++a) - { - if ((*a).first == *pmTransform) - { - (*a).second.push_back(i); - pmTransform->a1 = std::numeric_limits::quiet_NaN(); - break; - } - } - if (is_not_qnan(pmTransform->a1)) - { - // add a new entry ... - stack.push_back(std::pair >( - *pmTransform,std::list())); - stack.back().second.push_back(i); - } - // delete the matrix - delete pmTransform; - pcScene->mMeshes[i]->mColors[2] = NULL; + aiNode* pc = pcScene->mRootNode; + pcScene->mRootNode = pcScene->mRootNode->mChildren[0]; + pcScene->mRootNode->mParent = NULL; + delete pc; } - - // allocate enough space for the child nodes - pcScene->mRootNode->mNumChildren = stack.size(); - pcScene->mRootNode->mChildren = new aiNode*[stack.size()]; - - // now build all nodes - for (std::vector > >::iterator - a = stack.begin(); - a != stack.end();++a) + else if (0 == pcScene->mRootNode->mNumChildren) { - aiNode* pcNode = new aiNode(); - pcNode->mNumMeshes = (*a).second.size(); - pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes]; - for (std::list::const_iterator - i = (*a).second.begin(); - i != (*a).second.end();++i) - { - *pcNode->mMeshes++ = *i; - } - pcNode->mMeshes -= pcNode->mNumMeshes; - pcNode->mTransformation = (*a).first; - *pcScene->mRootNode->mChildren++ = pcNode; + throw new ImportErrorException("No nodes loaded. The ASE/ASK file is either empty or corrupt"); } - pcScene->mRootNode->mChildren -= stack.size(); return; } // ------------------------------------------------------------------------------------------------ @@ -229,16 +267,6 @@ void ASEImporter::TransformVertices(ASE::Mesh& mesh) // the matrix data is stored in column-major format, // but we need row major mesh.mTransform.Transpose(); - - aiMatrix4x4 m = mesh.mTransform; - m.Inverse(); - - for (std::vector::iterator - i = mesh.mPositions.begin(); - i != mesh.mPositions.end();++i) - { - (*i) = m * (*i); - } } // ------------------------------------------------------------------------------------------------ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) @@ -315,10 +343,11 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) // will fix that again ...) mBoneVertices[iCurrent] = mesh.mBoneVertices[(*i).mIndices[n]]; } - - // assign a new valid index to the face - (*i).mIndices[n] = iCurrent; } + // we need to flip the order of the indices + (*i).mIndices[0] = iCurrent-1; + (*i).mIndices[1] = iCurrent-2; + (*i).mIndices[2] = iCurrent-3; } // replace the old arrays @@ -373,7 +402,8 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat) } // if there is no shininess, we can disable phong lighting else if (Dot3DS::Dot3DSFile::Metal == mat.mShading || - Dot3DS::Dot3DSFile::Phong == mat.mShading) + Dot3DS::Dot3DSFile::Phong == mat.mShading || + Dot3DS::Dot3DSFile::Blinn == mat.mShading) { mat.mShading = Dot3DS::Dot3DSFile::Gouraud; } @@ -390,6 +420,8 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat) eShading = aiShadingMode_Flat; break; case Dot3DS::Dot3DSFile::Phong : eShading = aiShadingMode_Phong; break; + case Dot3DS::Dot3DSFile::Blinn : + eShading = aiShadingMode_Blinn; break; // I don't know what "Wire" shading should be, // assume it is simple lambertian diffuse (L dot N) shading @@ -490,10 +522,8 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat) return; } // ------------------------------------------------------------------------------------------------ -void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene) +void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector& avOutMeshes) { - ai_assert(NULL != pcScene); - // validate the material index of the mesh if (mesh.iMaterialIndex >= this->mParser->m_vMaterials.size()) { @@ -501,8 +531,6 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene) LOGOUT_WARN("Material index is out of range"); } - // List of all output meshes - std::vector avOutMeshes; // if the material the mesh is assigned to is consisting of submeshes // we'll need to split it ... Quak. @@ -544,8 +572,16 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene) // store the real index here ... color channel 3 p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex; + // store the real transformation matrix in color channel 2 p_pcOut->mColors[2] = (aiColor4D*) new aiMatrix4x4(mesh.mTransform); + + // store the name of the mesh and the + // name of its parent in color channel 1 + p_pcOut->mColors[1] = (aiColor4D*) new std::string[2]; + ((std::string*)p_pcOut->mColors[1])[0] = mesh.mName; + ((std::string*)p_pcOut->mColors[1])[1] = mesh.mParent; + avOutMeshes.push_back(p_pcOut); // convert vertices @@ -647,24 +683,24 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene) if (!avOutputBones[mrspock].empty())p_pcOut->mNumBones++; p_pcOut->mBones = new aiBone* [ p_pcOut->mNumBones ]; - aiBone** pcBone = &p_pcOut->mBones[0]; + aiBone** pcBone = p_pcOut->mBones; for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock) { if (!avOutputBones[mrspock].empty()) { // we will need this bone. add it to the output mesh and // add all per-vertex weights - *pcBone = new aiBone(); - (**pcBone).mName.Set(mesh.mBones[mrspock].mName); + aiBone* pc = *pcBone = new aiBone(); + pc->mName.Set(mesh.mBones[mrspock].mName); - (**pcBone).mNumWeights = avOutputBones[mrspock].size(); - (**pcBone).mWeights = new aiVertexWeight[(**pcBone).mNumWeights]; + pc->mNumWeights = avOutputBones[mrspock].size(); + pc->mWeights = new aiVertexWeight[pc->mNumWeights]; - for (unsigned int captainkirk = 0; captainkirk < (**pcBone).mNumWeights;++captainkirk) + for (unsigned int captainkirk = 0; captainkirk < pc->mNumWeights;++captainkirk) { const std::pair& ref = avOutputBones[mrspock][captainkirk]; - (**pcBone).mWeights[captainkirk].mVertexId = ref.first; - (**pcBone).mWeights[captainkirk].mWeight = ref.second; + pc->mWeights[captainkirk].mVertexId = ref.first; + pc->mWeights[captainkirk].mWeight = ref.second; } ++pcBone; } @@ -688,10 +724,17 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene) // store the real index here ... in color channel 3 p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex; + // store the transformation matrix in color channel 2 p_pcOut->mColors[2] = (aiColor4D*) new aiMatrix4x4(mesh.mTransform); avOutMeshes.push_back(p_pcOut); + // store the name of the mesh and the + // name of its parent in color channel 1 + p_pcOut->mColors[1] = (aiColor4D*) new std::string[2]; + ((std::string*)p_pcOut->mColors[1])[0] = mesh.mName; + ((std::string*)p_pcOut->mColors[1])[1] = mesh.mParent; + // convert vertices p_pcOut->mNumVertices = mesh.mPositions.size(); p_pcOut->mNumFaces = mesh.mFaces.size(); @@ -772,29 +815,59 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene) if (!avBonesOut[jfkennedy].empty())p_pcOut->mNumBones++; p_pcOut->mBones = new aiBone*[p_pcOut->mNumBones]; - aiBone** pcBone = &p_pcOut->mBones[0]; + aiBone** pcBone = p_pcOut->mBones; for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy) { if (!avBonesOut[jfkennedy].empty()) { - *pcBone = new aiBone(); - (**pcBone).mName.Set(mesh.mBones[jfkennedy].mName); - (**pcBone).mNumWeights = avBonesOut[jfkennedy].size(); - (**pcBone).mWeights = new aiVertexWeight[(**pcBone).mNumWeights]; - memcpy((**pcBone).mWeights,&avBonesOut[jfkennedy][0], - sizeof(aiVertexWeight) * (**pcBone).mNumWeights); + aiBone* pc = *pcBone = new aiBone(); + pc->mName.Set(mesh.mBones[jfkennedy].mName); + pc->mNumWeights = avBonesOut[jfkennedy].size(); + pc->mWeights = new aiVertexWeight[pc->mNumWeights]; + memcpy(pc->mWeights,&avBonesOut[jfkennedy][0], + sizeof(aiVertexWeight) * pc->mNumWeights); ++pcBone; } } } } + return; +} +// ------------------------------------------------------------------------------------------------ +void ASEImporter::AskFilterLOD(std::vector& meshes) +{ + for (std::vector::iterator + i = meshes.begin(); + i != meshes.end();++i) + { + if ((*i).bSkip)continue; - // now build the output mesh list - pcScene->mNumMeshes = avOutMeshes.size(); - pcScene->mMeshes = new aiMesh*[pcScene->mNumMeshes]; - for (unsigned int i = 0; i < pcScene->mNumMeshes;++i) - pcScene->mMeshes[i] = avOutMeshes[i]; - + // search for a number in the name of the node + const char* sz = (*i).mName.c_str(); + while (*sz) + { + if (*sz >= '0' && *sz <= '9') + { + // check whether there is another mesh with exactly + // the same name, but a lower number out there ... + unsigned int iLen = (unsigned int)(sz - (*i).mName.c_str()); + unsigned int iMyNum = strtol10(sz,NULL); + for (std::vector::iterator + f = meshes.begin(); + f != meshes.end();++f) + { + const char* sz = (*f).mName.c_str(); + if (i != f && !(*f).bSkip && + 0 == memcmp(sz,(*i).mName.c_str(),iLen) && + iMyNum > strtol10(sz)) + { + (*f).bSkip = true; + } + } + break; + }++sz; + } + } return; } // ------------------------------------------------------------------------------------------------ @@ -889,9 +962,9 @@ void ASEImporter::GenerateNormals(ASE::Mesh& mesh) const ASE::Face& face = mesh.mFaces[a]; // assume it is a triangle - aiVector3D* pV1 = &mesh.mPositions[face.mIndices[0]]; + aiVector3D* pV1 = &mesh.mPositions[face.mIndices[2]]; aiVector3D* pV2 = &mesh.mPositions[face.mIndices[1]]; - aiVector3D* pV3 = &mesh.mPositions[face.mIndices[2]]; + aiVector3D* pV3 = &mesh.mPositions[face.mIndices[0]]; aiVector3D pDelta1 = *pV2 - *pV1; aiVector3D pDelta2 = *pV3 - *pV1; diff --git a/code/ASELoader.h b/code/ASELoader.h index 0016db39b..c433ea4d5 100644 --- a/code/ASELoader.h +++ b/code/ASELoader.h @@ -115,12 +115,19 @@ protected: */ void TransformVertices(ASE::Mesh& mesh); + // ------------------------------------------------------------------- + /** The ASK file format contains LOD nodes. + * We do only use the highest level of detail, all others + * are skipped. + */ + void AskFilterLOD(std::vector& meshes); + // ------------------------------------------------------------------- /** Create one-material-per-mesh meshes ;-) * \param mesh Mesh to work with - * \param pcScene Scene object to be filled + * \param Receives the list of all created meshes */ - void ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene); + void ConvertMeshes(ASE::Mesh& mesh, std::vector& avOut); // ------------------------------------------------------------------- /** Convert a material to a MaterialHelper object @@ -140,6 +147,15 @@ protected: */ void BuildNodes(aiScene* pcScene); + // ------------------------------------------------------------------- + /** Add sub nodes to a node + * \param pcScene Scene object to be filled + * \param pcParent parent node to be filled + * \param szName Name of the parent node + */ + void AddNodes(aiScene* pcScene,aiNode* pcParent, + const char* szName); + protected: /** Parser instance */ diff --git a/code/ASEParser.cpp b/code/ASEParser.cpp index 8ed32335c..3ba133b08 100644 --- a/code/ASEParser.cpp +++ b/code/ASEParser.cpp @@ -175,6 +175,7 @@ void Parser::Parse() this->LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \ be 200. Continuing happily ..."); } + continue; } // main scene information if (0 == strncmp(this->m_szFile,"*SCENE",6) && @@ -182,6 +183,7 @@ void Parser::Parse() { this->m_szFile+=7; this->ParseLV1SceneBlock(); + continue; } // material list if (0 == strncmp(this->m_szFile,"*MATERIAL_LIST",14) && @@ -189,24 +191,25 @@ void Parser::Parse() { this->m_szFile+=15; this->ParseLV1MaterialListBlock(); + continue; } // geometric object (mesh) if (0 == strncmp(this->m_szFile,"*GEOMOBJECT",11) && IsSpaceOrNewLine(*(this->m_szFile+11))) { this->m_szFile+=12; - this->m_vMeshes.push_back(Mesh()); this->ParseLV1GeometryObjectBlock(this->m_vMeshes.back()); + continue; } // ignore comments, lights and cameras } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } - if ('\0' == *this->m_szFile) + else if ('\0' == *this->m_szFile) { // END OF FILE ... why not? return; @@ -231,6 +234,7 @@ void Parser::ParseLV1SceneBlock() // parse a color triple and assume it is really the bg color this->ParseLV4MeshFloatTriple( &this->m_clrBackground.r ); + continue; } if (0 == strncmp(this->m_szFile,"*SCENE_AMBIENT_STATIC",21) && IsSpaceOrNewLine(*(this->m_szFile+21))) @@ -239,10 +243,11 @@ void Parser::ParseLV1SceneBlock() // parse a color triple and assume it is really the bg color this->ParseLV4MeshFloatTriple( &this->m_clrAmbient.r ); + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -261,6 +266,7 @@ void Parser::ParseLV1MaterialListBlock() { int iDepth = 0; unsigned int iMaterialCount = 0; + unsigned int iOldMaterialCount = this->m_vMaterials.size(); while (true) { if ('*' == *this->m_szFile) @@ -272,7 +278,8 @@ void Parser::ParseLV1MaterialListBlock() this->ParseLV4MeshLong(iMaterialCount); // now allocate enough storage to hold all materials - this->m_vMaterials.resize(iMaterialCount); + this->m_vMaterials.resize(iOldMaterialCount+iMaterialCount); + continue; } if (0 == strncmp(this->m_szFile,"*MATERIAL",9) && IsSpaceOrNewLine(*(this->m_szFile+9))) @@ -288,17 +295,18 @@ void Parser::ParseLV1MaterialListBlock() } // get a reference to the material - Material& sMat = this->m_vMaterials[iIndex]; + Material& sMat = this->m_vMaterials[iIndex+iOldMaterialCount]; // skip the '{' this->SkipOpeningBracket(); // parse the material block this->ParseLV2MaterialBlock(sMat); + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -326,36 +334,29 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) { this->m_szFile+=15; - // NOTE: The name could also be the texture in some cases - // be prepared that this might occur ... - if (!SkipSpaces(this->m_szFile,&this->m_szFile)) - BLUBB("Unable to parse *MATERIAL_NAME block: Unexpected EOL") - - const char* sz = this->m_szFile; - while (!IsSpaceOrNewLine(*sz))sz++; - mat.mName = std::string(this->m_szFile,(uintptr_t)sz-(uintptr_t)this->m_szFile); - this->m_szFile = sz; + if (!this->ParseString(mat.mName,"*MATERIAL_NAME"))this->SkipToNextToken(); + continue; } // ambient material color if (0 == strncmp(this->m_szFile,"*MATERIAL_AMBIENT",17) && IsSpaceOrNewLine(*(this->m_szFile+17))) { this->m_szFile+=18; - this->ParseLV4MeshFloatTriple(&mat.mAmbient.r); + this->ParseLV4MeshFloatTriple(&mat.mAmbient.r);continue; } // diffuse material color if (0 == strncmp(this->m_szFile,"*MATERIAL_DIFFUSE",17) && IsSpaceOrNewLine(*(this->m_szFile+17))) { this->m_szFile+=18; - this->ParseLV4MeshFloatTriple(&mat.mDiffuse.r); + this->ParseLV4MeshFloatTriple(&mat.mDiffuse.r);continue; } // specular material color if (0 == strncmp(this->m_szFile,"*MATERIAL_SPECULAR",18) && IsSpaceOrNewLine(*(this->m_szFile+18))) { this->m_szFile+=19; - this->ParseLV4MeshFloatTriple(&mat.mSpecular.r); + this->ParseLV4MeshFloatTriple(&mat.mSpecular.r);continue; } // material shading type if (0 == strncmp(this->m_szFile,"*MATERIAL_SHADING",17) && @@ -393,6 +394,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) mat.mShading = Dot3DSFile::Gouraud; this->SkipToNextToken(); } + continue; } // material transparency if (0 == strncmp(this->m_szFile,"*MATERIAL_TRANSPARENCY",22) && @@ -400,7 +402,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) { this->m_szFile+=23; this->ParseLV4MeshFloat(mat.mTransparency); - mat.mTransparency = 1.0f - mat.mTransparency; + mat.mTransparency = 1.0f - mat.mTransparency;continue; } // material self illumination if (0 == strncmp(this->m_szFile,"*MATERIAL_SELFILLUM",19) && @@ -413,6 +415,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) mat.mEmissive.r = f; mat.mEmissive.g = f; mat.mEmissive.b = f; + continue; } // material shininess if (0 == strncmp(this->m_szFile,"*MATERIAL_SHINE",15) && @@ -420,14 +423,14 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) { this->m_szFile+=16; this->ParseLV4MeshFloat(mat.mSpecularExponent); - mat.mSpecularExponent *= 15; + mat.mSpecularExponent *= 15;continue; } // material shininess strength if (0 == strncmp(this->m_szFile,"*MATERIAL_SHINESTRENGTH",23) && IsSpaceOrNewLine(*(this->m_szFile+23))) { this->m_szFile+=24; - this->ParseLV4MeshFloat(mat.mShininessStrength); + this->ParseLV4MeshFloat(mat.mShininessStrength);continue; } // diffuse color map if (0 == strncmp(this->m_szFile,"*MAP_DIFFUSE",12) && @@ -437,7 +440,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) // skip the opening bracket this->SkipOpeningBracket(); // parse the texture block - this->ParseLV3MapBlock(mat.sTexDiffuse); + this->ParseLV3MapBlock(mat.sTexDiffuse);continue; } // ambient color map if (0 == strncmp(this->m_szFile,"*MAP_AMBIENT",12) && @@ -447,7 +450,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) // skip the opening bracket this->SkipOpeningBracket(); // parse the texture block - this->ParseLV3MapBlock(mat.sTexAmbient); + this->ParseLV3MapBlock(mat.sTexAmbient);continue; } // specular color map if (0 == strncmp(this->m_szFile,"*MAP_SPECULAR",13) && @@ -457,7 +460,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) // skip the opening bracket this->SkipOpeningBracket(); // parse the texture block - this->ParseLV3MapBlock(mat.sTexSpecular); + this->ParseLV3MapBlock(mat.sTexSpecular);continue; } // opacity map if (0 == strncmp(this->m_szFile,"*MAP_OPACITY",12) && @@ -467,7 +470,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) // skip the opening bracket this->SkipOpeningBracket(); // parse the texture block - this->ParseLV3MapBlock(mat.sTexOpacity); + this->ParseLV3MapBlock(mat.sTexOpacity);continue; } // emissive map if (0 == strncmp(this->m_szFile,"*MAP_SELFILLUM",14) && @@ -477,7 +480,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) // skip the opening bracket this->SkipOpeningBracket(); // parse the texture block - this->ParseLV3MapBlock(mat.sTexEmissive); + this->ParseLV3MapBlock(mat.sTexEmissive);continue; } // bump map if (0 == strncmp(this->m_szFile,"*MAP_BUMP",9) && @@ -497,7 +500,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) // skip the opening bracket this->SkipOpeningBracket(); // parse the texture block - this->ParseLV3MapBlock(mat.sTexShininess); + this->ParseLV3MapBlock(mat.sTexShininess);continue; } // number of submaterials if (0 == strncmp(this->m_szFile,"*NUMSUBMTLS",11) && @@ -532,11 +535,11 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat) // parse the material block this->ParseLV2MaterialBlock(sMat); + continue; } - } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -564,77 +567,54 @@ void Parser::ParseLV3MapBlock(Texture& map) IsSpaceOrNewLine(*(this->m_szFile+7))) { this->m_szFile+=8; - - // NOTE: The name could also be the texture in some cases - // be prepared that this might occur ... - if (!SkipSpaces(this->m_szFile,&this->m_szFile)) - BLUBB("Unable to parse *BITMAP block: Unexpected EOL") - - // there must be " - if ('\"' != *this->m_szFile) - BLUBB("Unable to parse *BITMAP block: Path is expected to be enclosed in double quotation marks") - - ++this->m_szFile; - const char* sz = this->m_szFile; - while (true) - { - if ('\"' == *sz)break; - else if ('\0' == sz) - { - BLUBB("Unable to parse *BITMAP block: Path is expected to be enclosed in double quotation marks \ - but EOF was reached before a closing quotation mark was found") - } - sz++; - } - - map.mMapName = std::string(this->m_szFile,(uintptr_t)sz-(uintptr_t)this->m_szFile); - this->m_szFile = sz; + if(!this->ParseString(map.mMapName,"*BITMAP"))SkipToNextToken(); + continue; } // offset on the u axis if (0 == strncmp(this->m_szFile,"*UVW_U_OFFSET" ,13) && IsSpaceOrNewLine(*(this->m_szFile+13))) { this->m_szFile+=14; - this->ParseLV4MeshFloat(map.mOffsetU); + this->ParseLV4MeshFloat(map.mOffsetU);continue; } // offset on the v axis if (0 == strncmp(this->m_szFile,"*UVW_V_OFFSET" ,13) && IsSpaceOrNewLine(*(this->m_szFile+13))) { this->m_szFile+=14; - this->ParseLV4MeshFloat(map.mOffsetV); + this->ParseLV4MeshFloat(map.mOffsetV);continue; } // tiling on the u axis if (0 == strncmp(this->m_szFile,"*UVW_U_TILING" ,13) && IsSpaceOrNewLine(*(this->m_szFile+13))) { this->m_szFile+=14; - this->ParseLV4MeshFloat(map.mScaleU); + this->ParseLV4MeshFloat(map.mScaleU);continue; } // tiling on the v axis if (0 == strncmp(this->m_szFile,"*UVW_V_TILING" ,13) && IsSpaceOrNewLine(*(this->m_szFile+13))) { this->m_szFile+=14; - this->ParseLV4MeshFloat(map.mScaleV); + this->ParseLV4MeshFloat(map.mScaleV);continue; } // rotation around the z-axis if (0 == strncmp(this->m_szFile,"*UVW_ANGLE" ,10) && IsSpaceOrNewLine(*(this->m_szFile+10))) { this->m_szFile+=11; - this->ParseLV4MeshFloat(map.mRotation); + this->ParseLV4MeshFloat(map.mRotation);continue; } // map blending factor if (0 == strncmp(this->m_szFile,"*MAP_AMOUNT" ,11) && IsSpaceOrNewLine(*(this->m_szFile+11))) { this->m_szFile+=12; - this->ParseLV4MeshFloat(map.mTextureBlend); + this->ParseLV4MeshFloat(map.mTextureBlend);continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -652,7 +632,7 @@ void Parser::ParseLV3MapBlock(Texture& map) bool Parser::ParseString(std::string& out,const char* szName) { char szBuffer[1024]; - ai_assert(strlen(szName < 750)); + ai_assert(strlen(szName) < 750); // NOTE: The name could also be the texture in some cases // be prepared that this might occur ... @@ -702,47 +682,41 @@ void Parser::ParseLV1GeometryObjectBlock(ASE::Mesh& mesh) IsSpaceOrNewLine(*(this->m_szFile+10))) { this->m_szFile+=11; - if(!this->ParseString(mesh.mName,"*NODE_NAME")) - { - this->SkipToNextToken(); - continue; - } + if(!this->ParseString(mesh.mName,"*NODE_NAME"))this->SkipToNextToken(); + continue; } // name of the parent of the node if (0 == strncmp(this->m_szFile,"*NODE_PARENT" ,12) && IsSpaceOrNewLine(*(this->m_szFile+12))) { this->m_szFile+=13; - if(!this->ParseString(mesh.mParent,"*NODE_PARENT")) - { - this->SkipToNextToken(); - continue; - } + if(!this->ParseString(mesh.mParent,"*NODE_PARENT"))this->SkipToNextToken(); + continue; } // transformation matrix of the node if (0 == strncmp(this->m_szFile,"*NODE_TM" ,8) && IsSpaceOrNewLine(*(this->m_szFile+8))) { this->m_szFile+=9; - this->ParseLV2NodeTransformBlock(mesh); + this->ParseLV2NodeTransformBlock(mesh);continue; } // mesh data if (0 == strncmp(this->m_szFile,"*MESH" ,5) && IsSpaceOrNewLine(*(this->m_szFile+5))) { this->m_szFile+=6; - this->ParseLV2MeshBlock(mesh); + this->ParseLV2MeshBlock(mesh);continue; } // mesh material index - else if (0 == strncmp(this->m_szFile,"*MATERIAL_REF" ,13) && + if (0 == strncmp(this->m_szFile,"*MATERIAL_REF" ,13) && IsSpaceOrNewLine(*(this->m_szFile+13))) { this->m_szFile+=14; - this->ParseLV4MeshLong(mesh.iMaterialIndex); + this->ParseLV4MeshLong(mesh.iMaterialIndex);continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -769,32 +743,32 @@ void Parser::ParseLV2NodeTransformBlock(ASE::Mesh& mesh) IsSpaceOrNewLine(*(this->m_szFile+8))) { this->m_szFile+=9; - this->ParseLV4MeshFloatTriple(mesh.mTransform[0]); + this->ParseLV4MeshFloatTriple(mesh.mTransform[0]);continue; } // second row of the transformation matrix if (0 == strncmp(this->m_szFile,"*TM_ROW1" ,8) && IsSpaceOrNewLine(*(this->m_szFile+8))) { this->m_szFile+=9; - this->ParseLV4MeshFloatTriple(mesh.mTransform[1]); + this->ParseLV4MeshFloatTriple(mesh.mTransform[1]);continue; } // third row of the transformation matrix if (0 == strncmp(this->m_szFile,"*TM_ROW2" ,8) && IsSpaceOrNewLine(*(this->m_szFile+8))) { this->m_szFile+=9; - this->ParseLV4MeshFloatTriple(mesh.mTransform[2]); + this->ParseLV4MeshFloatTriple(mesh.mTransform[2]);continue; } // fourth row of the transformation matrix if (0 == strncmp(this->m_szFile,"*TM_ROW3" ,8) && IsSpaceOrNewLine(*(this->m_szFile+8))) { this->m_szFile+=9; - this->ParseLV4MeshFloatTriple(mesh.mTransform[3]); + this->ParseLV4MeshFloatTriple(mesh.mTransform[3]);continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -827,42 +801,44 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) IsSpaceOrNewLine(*(this->m_szFile+15))) { this->m_szFile+=16; - this->ParseLV4MeshLong(iNumVertices); + this->ParseLV4MeshLong(iNumVertices);continue; } // Number of texture coordinates in the mesh if (0 == strncmp(this->m_szFile,"*MESH_NUMTVERTEX" ,16) && IsSpaceOrNewLine(*(this->m_szFile+16))) { this->m_szFile+=17; - this->ParseLV4MeshLong(iNumTVertices); + this->ParseLV4MeshLong(iNumTVertices);continue; } // Number of vertex colors in the mesh if (0 == strncmp(this->m_szFile,"*MESH_NUMCVERTEX" ,16) && IsSpaceOrNewLine(*(this->m_szFile+16))) { this->m_szFile+=17; - this->ParseLV4MeshLong(iNumCVertices); + this->ParseLV4MeshLong(iNumCVertices);continue; } // Number of regular faces in the mesh if (0 == strncmp(this->m_szFile,"*MESH_NUMFACES" ,14) && IsSpaceOrNewLine(*(this->m_szFile+14))) { this->m_szFile+=15; - this->ParseLV4MeshLong(iNumFaces); + this->ParseLV4MeshLong(iNumFaces);continue; + // fix ... + //mesh.mFaces.resize(iNumFaces); } // Number of UVWed faces in the mesh if (0 == strncmp(this->m_szFile,"*MESH_NUMTVFACES" ,16) && IsSpaceOrNewLine(*(this->m_szFile+16))) { this->m_szFile+=17; - this->ParseLV4MeshLong(iNumTFaces); + this->ParseLV4MeshLong(iNumTFaces);continue; } // Number of colored faces in the mesh if (0 == strncmp(this->m_szFile,"*MESH_NUMCVFACES" ,16) && IsSpaceOrNewLine(*(this->m_szFile+16))) { this->m_szFile+=17; - this->ParseLV4MeshLong(iNumCFaces); + this->ParseLV4MeshLong(iNumCFaces);continue; } // mesh vertex list block if (0 == strncmp(this->m_szFile,"*MESH_VERTEX_LIST" ,17) && @@ -870,6 +846,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) { this->m_szFile+=18; this->ParseLV3MeshVertexListBlock(iNumVertices,mesh); + continue; } // mesh face list block if (0 == strncmp(this->m_szFile,"*MESH_FACE_LIST" ,15) && @@ -877,7 +854,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) { this->m_szFile+=16; this->SkipOpeningBracket(); - this->ParseLV3MeshFaceListBlock(iNumFaces,mesh); + this->ParseLV3MeshFaceListBlock(iNumFaces,mesh);continue; } // mesh texture vertex list block if (0 == strncmp(this->m_szFile,"*MESH_TVERTLIST" ,15) && @@ -885,7 +862,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) { this->m_szFile+=16; this->SkipOpeningBracket(); - this->ParseLV3MeshTListBlock(iNumTVertices,mesh); + this->ParseLV3MeshTListBlock(iNumTVertices,mesh);continue; } // mesh texture face block if (0 == strncmp(this->m_szFile,"*MESH_TFACELIST" ,15) && @@ -893,7 +870,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) { this->m_szFile+=16; this->SkipOpeningBracket(); - this->ParseLV3MeshTFaceListBlock(iNumTFaces,mesh); + this->ParseLV3MeshTFaceListBlock(iNumTFaces,mesh);continue; } // mesh color vertex list block if (0 == strncmp(this->m_szFile,"*MESH_CVERTLIST" ,15) && @@ -901,7 +878,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) { this->m_szFile+=16; this->SkipOpeningBracket(); - this->ParseLV3MeshCListBlock(iNumCVertices,mesh); + this->ParseLV3MeshCListBlock(iNumCVertices,mesh);continue; } // mesh color face block if (0 == strncmp(this->m_szFile,"*MESH_CFACELIST" ,15) && @@ -909,7 +886,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) { this->m_szFile+=16; this->SkipOpeningBracket(); - this->ParseLV3MeshCFaceListBlock(iNumCFaces,mesh); + this->ParseLV3MeshCFaceListBlock(iNumCFaces,mesh);continue; } // another mesh UV channel ... if (0 == strncmp(this->m_szFile,"*MESH_MAPPINGCHANNEL" ,20) && @@ -942,9 +919,10 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) // parse the mapping channel this->ParseLV3MappingChannel(iIndex-1,mesh); } + continue; } // mesh animation keyframe. Not supported - else if (0 == strncmp(this->m_szFile,"*MESH_ANIMATION" ,15) && + if (0 == strncmp(this->m_szFile,"*MESH_ANIMATION" ,15) && IsSpaceOrNewLine(*(this->m_szFile+15))) { this->m_szFile+=16; @@ -952,17 +930,18 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh) this->LogWarning("Found *MESH_ANIMATION element in ASE/ASK file. " "Keyframe animation is not supported by Assimp, this element " "will be ignored"); + continue; } // mesh animation keyframe. Not supported - else if (0 == strncmp(this->m_szFile,"*MESH_WEIGHTS" ,13) && + if (0 == strncmp(this->m_szFile,"*MESH_WEIGHTS" ,13) && IsSpaceOrNewLine(*(this->m_szFile+13))) { this->m_szFile+=14; - this->ParseLV3MeshWeightsBlock(mesh); + this->ParseLV3MeshWeightsBlock(mesh);continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -991,14 +970,14 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh) IsSpaceOrNewLine(*(this->m_szFile+15))) { this->m_szFile+=16; - this->ParseLV4MeshLong(iNumVertices); + this->ParseLV4MeshLong(iNumVertices);continue; } // Number of bones if (0 == strncmp(this->m_szFile,"*MESH_NUMBONE" ,13) && IsSpaceOrNewLine(*(this->m_szFile+13))) { this->m_szFile+=14; - this->ParseLV4MeshLong(iNumBones); + this->ParseLV4MeshLong(iNumBones);continue; } // parse the list of bones if (0 == strncmp(this->m_szFile,"*MESH_BONE_LIST" ,15) && @@ -1006,7 +985,7 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh) { this->m_szFile+=16; this->SkipOpeningBracket(); - this->ParseLV4MeshBones(iNumBones,mesh); + this->ParseLV4MeshBones(iNumBones,mesh);continue; } // parse the list of bones vertices if (0 == strncmp(this->m_szFile,"*MESH_BONE_VERTEX_LIST" ,22) && @@ -1015,10 +994,11 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh) this->m_szFile+=23; this->SkipOpeningBracket(); this->ParseLV4MeshBonesVertices(iNumVertices,mesh); + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -1058,14 +1038,12 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh) "bone index instead"); } if (!this->ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME")) - { this->SkipToNextToken(); - continue; - } + continue; } } } - if ('{' == *this->m_szFile)iDepth++; + else if ('{' == *this->m_szFile)iDepth++; else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} @@ -1127,9 +1105,10 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh mesh.mBoneVertices[iIndex].mBoneWeights.push_back(pairOut); } } + continue; } } - if ('{' == *this->m_szFile)iDepth++; + else if ('{' == *this->m_szFile)iDepth++; else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} @@ -1170,9 +1149,10 @@ void Parser::ParseLV3MeshVertexListBlock( this->LogWarning("Vertex has an invalid index. It will be ignored"); } else mesh.mPositions[iIndex] = vTemp; + continue; } } - if ('{' == *this->m_szFile)iDepth++; + else if ('{' == *this->m_szFile)iDepth++; else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} @@ -1211,10 +1191,11 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh) this->LogWarning("Face has an invalid index. It will be ignored"); } else mesh.mFaces[mFace.iFace] = mFace; + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -1260,10 +1241,11 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices, // we need 3 coordinate channels mesh.mNumUVComponents[iChannel] = 3; } + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -1307,10 +1289,11 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces, mesh.mFaces[iIndex].amUVIndices[iChannel][1] = aiValues[1]; mesh.mFaces[iIndex].amUVIndices[iChannel][2] = aiValues[2]; } + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -1340,14 +1323,14 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh) IsSpaceOrNewLine(*(this->m_szFile+16))) { this->m_szFile+=17; - this->ParseLV4MeshLong(iNumTVertices); + this->ParseLV4MeshLong(iNumTVertices);continue; } // Number of UVWed faces in the mesh if (0 == strncmp(this->m_szFile,"*MESH_NUMTVFACES" ,16) && IsSpaceOrNewLine(*(this->m_szFile+16))) { this->m_szFile+=17; - this->ParseLV4MeshLong(iNumTFaces); + this->ParseLV4MeshLong(iNumTFaces);continue; } // mesh texture vertex list block if (0 == strncmp(this->m_szFile,"*MESH_TVERTLIST" ,15) && @@ -1356,6 +1339,7 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh) this->m_szFile+=16; this->SkipOpeningBracket(); this->ParseLV3MeshTListBlock(iNumTVertices,mesh,iChannel); + continue; } // mesh texture face block if (0 == strncmp(this->m_szFile,"*MESH_TFACELIST" ,15) && @@ -1364,10 +1348,11 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh) this->m_szFile+=16; this->SkipOpeningBracket(); this->ParseLV3MeshTFaceListBlock(iNumTFaces,mesh, iChannel); + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -1407,10 +1392,11 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh) this->LogWarning("Vertex color has an invalid index. It will be ignored"); } else mesh.mVertexColors[iIndex] = vTemp; + continue; } } if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -1453,10 +1439,11 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh) mesh.mFaces[iIndex].mColorIndices[1] = aiValues[1]; mesh.mFaces[iIndex].mColorIndices[2] = aiValues[2]; } + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } @@ -1500,10 +1487,11 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh) // important: this->m_szFile might now point to '}' ... sMesh.mNormals[iIndex] = vNormal; + continue; } } - if ('{' == *this->m_szFile)iDepth++; - if ('}' == *this->m_szFile) + else if ('{' == *this->m_szFile)iDepth++; + else if ('}' == *this->m_szFile) { if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;} } diff --git a/code/ASEParser.h b/code/ASEParser.h index 83215dbdf..3e28b6371 100644 --- a/code/ASEParser.h +++ b/code/ASEParser.h @@ -160,7 +160,7 @@ struct BoneVertex struct Mesh { //! Constructor. Creates a default name for the mesh - Mesh() + Mesh() : bSkip(false) { static int iCnt = 0; std::stringstream ss(mName); @@ -211,6 +211,9 @@ struct Mesh //! Number of vertex components for each UVW set unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS]; + + //! used internally + bool bSkip; }; // --------------------------------------------------------------------------------- diff --git a/code/ConvertToLHProcess.cpp b/code/ConvertToLHProcess.cpp index 2e8f049da..7ffc62b41 100644 --- a/code/ConvertToLHProcess.cpp +++ b/code/ConvertToLHProcess.cpp @@ -24,7 +24,7 @@ const aiMatrix3x3 Assimp::ConvertToLHProcess::sToDXTransform( // Constructor to be privately used by Importer ConvertToLHProcess::ConvertToLHProcess() { - // nothing to do here + bTransformVertices = false; } // ------------------------------------------------------------------------------------------------ @@ -38,7 +38,13 @@ ConvertToLHProcess::~ConvertToLHProcess() // Returns whether the processing step is present in the given flag field. bool ConvertToLHProcess::IsActive( unsigned int pFlags) const { - return (pFlags & aiProcess_ConvertToLeftHanded) != 0; + if (pFlags & aiProcess_ConvertToLeftHanded) + { + if (pFlags & aiProcess_PreTransformVertices) + this->bTransformVertices = true; + return true; + } + return false; } // ------------------------------------------------------------------------------------------------ @@ -54,8 +60,34 @@ void ConvertToLHProcess::Execute( aiScene* pScene) DefaultLogger::get()->debug("ConvertToLHProcess begin"); - // transform the root node of the scene, the other nodes will follow then - ConvertToDX( pScene->mRootNode->mTransformation); + // transform vertex by vertex or change the root transform? + if (this->bTransformVertices) + { + this->bTransformVertices = false; + aiMatrix4x4 mTransform; + this->ConvertToDX(mTransform); + for (unsigned int i = 0; i < pScene->mNumMeshes;++i) + { + aiMesh* pcMesh = pScene->mMeshes[i]; + for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) + { + pcMesh->mVertices[n] = mTransform * pcMesh->mVertices[n]; + } + if (pcMesh->HasNormals()) + { + mTransform.Inverse().Transpose(); + for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) + { + pcMesh->mNormals[n] = mTransform * pcMesh->mNormals[n]; + } + } + } + } + else + { + // transform the root node of the scene, the other nodes will follow then + ConvertToDX( pScene->mRootNode->mTransformation); + } // transform all meshes accordingly for( unsigned int a = 0; a < pScene->mNumMeshes; a++) diff --git a/code/ConvertToLHProcess.h b/code/ConvertToLHProcess.h index 9f2adcf16..49390fe83 100644 --- a/code/ConvertToLHProcess.h +++ b/code/ConvertToLHProcess.h @@ -116,6 +116,10 @@ protected: */ void ProcessAnimation( aiBoneAnim* pAnim); + //! true if the transformation matrix for the OGL-to-DX is + //! directly used to transform all vertices. + mutable bool bTransformVertices; + public: /** The transformation matrix to convert from DirectX coordinates to OpenGL coordinates. */ static const aiMatrix3x3 sToOGLTransform; diff --git a/code/HalfLifeFileData.h b/code/HalfLifeFileData.h new file mode 100644 index 000000000..fb55bec31 --- /dev/null +++ b/code/HalfLifeFileData.h @@ -0,0 +1,161 @@ +/* +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 Definition of in-memory structures for the HL2 MDL file format +// and for the HalfLife text format (SMD) +// +// The specification has been taken from various sources on the internet. + + +#ifndef AI_MDLFILEHELPER2_H_INC +#define AI_MDLFILEHELPER2_H_INC + + +// ugly compiler dependent packing stuff +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack(push,1) +# define PACK_STRUCT +#elif defined( __GNUC__ ) +# define PACK_STRUCT __attribute__((packed)) +#else +# error Compiler not supported. Never do this again. +#endif + +namespace Assimp +{ +namespace MDL +{ + +// magic bytes used in Half Life 2 MDL models +#define AI_MDL_MAGIC_NUMBER_BE_HL2a 'IDST' +#define AI_MDL_MAGIC_NUMBER_LE_HL2a 'TSDI' +#define AI_MDL_MAGIC_NUMBER_BE_HL2b 'IDSQ' +#define AI_MDL_MAGIC_NUMBER_LE_HL2b 'QSDI' + +// --------------------------------------------------------------------------- +/** \struct Header_HL2 + * \brief Data structure for the HL2 main header + */ +// --------------------------------------------------------------------------- +struct Header_HL2 +{ + //! magic number: "IDST"/"IDSQ" + char ident[4]; + + //! Version number + int32_t version; + + //! Original file name in pak ? + char name[64]; + + //! Length of file name/length of file? + int32_t length; + + //! For viewer, ignored + aiVector3D eyeposition; + aiVector3D min; + aiVector3D max; + + //! AABB of the model + aiVector3D bbmin; + aiVector3D bbmax; + + // File flags + int32_t flags; + + //! NUmber of bones contained in the file + int32_t numbones; + int32_t boneindex; + + //! Number of bone controllers for bone animation + int32_t numbonecontrollers; + int32_t bonecontrollerindex; + + //! More bounding boxes ... + int32_t numhitboxes; + int32_t hitboxindex; + + //! Animation sequences in the file + int32_t numseq; + int32_t seqindex; + + //! Loaded sequences. Ignored + int32_t numseqgroups; + int32_t seqgroupindex; + + //! Raw texture data + int32_t numtextures; + int32_t textureindex; + int32_t texturedataindex; + + //! Number of skins (=textures?) + int32_t numskinref; + int32_t numskinfamilies; + int32_t skinindex; + + //! Number of parts + int32_t numbodyparts; + int32_t bodypartindex; + + //! attachable points for gameplay and physics + int32_t numattachments; + int32_t attachmentindex; + + //! Table of sound effects associated with the model + int32_t soundtable; + int32_t soundindex; + int32_t soundgroups; + int32_t soundgroupindex; + + //! Number of animation transitions + int32_t numtransitions; + int32_t transitionindex; +} PACK_STRUCT; + +// reset packing to the original value +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) +# pragma pack( pop ) +#endif +#undef PACK_STRUCT + +};}; // end namespaces +#endif // ! AI_MDLFILEHELPER2_H_INC \ No newline at end of file diff --git a/code/Importer.cpp b/code/Importer.cpp index 7fdda5022..0d8dd4ab7 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -88,6 +88,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "GenVertexNormalsProcess.h" #include "KillNormalsProcess.h" #include "SplitLargeMeshes.h" +#include "PretransformVertices.h" #include "../include/DefaultLogger.h" using namespace Assimp; @@ -133,6 +134,7 @@ Importer::Importer() : // add an instance of each post processing step here in the order of sequence it is executed mPostProcessingSteps.push_back( new TriangulateProcess()); + mPostProcessingSteps.push_back( new PretransformVertices()); mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Triangle()); mPostProcessingSteps.push_back( new KillNormalsProcess()); mPostProcessingSteps.push_back( new GenFaceNormalsProcess()); diff --git a/code/MDLFileData.h b/code/MDLFileData.h index e49e0abcc..e34da4399 100644 --- a/code/MDLFileData.h +++ b/code/MDLFileData.h @@ -67,7 +67,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # error Compiler not supported. Never do this again. #endif - namespace Assimp { namespace MDL @@ -95,11 +94,6 @@ namespace MDL #define AI_MDL_MAGIC_NUMBER_BE_GS7 'MDL7' #define AI_MDL_MAGIC_NUMBER_LE_GS7 '7LDM' -// magic bytes used in Half Life 2 MDL models -#define AI_MDL_MAGIC_NUMBER_BE_HL2a 'IDST' -#define AI_MDL_MAGIC_NUMBER_LE_HL2a 'TSDI' -#define AI_MDL_MAGIC_NUMBER_BE_HL2b 'IDSQ' -#define AI_MDL_MAGIC_NUMBER_LE_HL2b 'QSDI' // common limitations for Quake1 meshes. The loader does not check them, // but models should not exceed these limits. @@ -217,86 +211,6 @@ struct Header_MDL7 } PACK_STRUCT; -// --------------------------------------------------------------------------- -/** \struct Header_HL2 - * \brief Data structure for the HL2 main header - */ -// --------------------------------------------------------------------------- -struct Header_HL2 -{ - //! magic number: "IDST"/"IDSQ" - char ident[4]; - - //! Version number - int32_t version; - - //! Original file name in pak ? - char name[64]; - - //! Length of file name/length of file? - int32_t length; - - //! For viewer, ignored - aiVector3D eyeposition; - aiVector3D min; - aiVector3D max; - - //! AABB of the model - aiVector3D bbmin; - aiVector3D bbmax; - - // File flags - int32_t flags; - - //! NUmber of bones contained in the file - int32_t numbones; - int32_t boneindex; - - //! Number of bone controllers for bone animation - int32_t numbonecontrollers; - int32_t bonecontrollerindex; - - //! More bounding boxes ... - int32_t numhitboxes; - int32_t hitboxindex; - - //! Animation sequences in the file - int32_t numseq; - int32_t seqindex; - - //! Loaded sequences. Ignored - int32_t numseqgroups; - int32_t seqgroupindex; - - //! Raw texture data - int32_t numtextures; - int32_t textureindex; - int32_t texturedataindex; - - //! Number of skins (=textures?) - int32_t numskinref; - int32_t numskinfamilies; - int32_t skinindex; - - //! Number of parts - int32_t numbodyparts; - int32_t bodypartindex; - - //! attachable points for gameplay and physics - int32_t numattachments; - int32_t attachmentindex; - - //! Table of sound effects associated with the model - int32_t soundtable; - int32_t soundindex; - int32_t soundgroups; - int32_t soundgroupindex; - - //! Number of animation transitions - int32_t numtransitions; - int32_t transitionindex; -} PACK_STRUCT; - #define AI_MDL7_MAX_BONENAMESIZE 20 // --------------------------------------------------------------------------- @@ -372,6 +286,12 @@ struct Deformer_MDL7 int32_t deformerdata_size; } PACK_STRUCT; + +// --------------------------------------------------------------------------- +/** \struct DeformerElement_MDL7 + * \brief Deformer element in a MDL7 file + */ +// --------------------------------------------------------------------------- struct DeformerElement_MDL7 { //! bei deformer_typ==0 (==bones) element_index == bone index @@ -380,6 +300,12 @@ struct DeformerElement_MDL7 int32_t weights; } PACK_STRUCT; + +// --------------------------------------------------------------------------- +/** \struct DeformerWeight_MDL7 + * \brief Deformer weight in a MDL7 file + */ +// --------------------------------------------------------------------------- struct DeformerWeight_MDL7 { //! for deformer_typ==0 (==bones) index == vertex index @@ -387,8 +313,11 @@ struct DeformerWeight_MDL7 float weight; } PACK_STRUCT; +// maximum length of texture file name #define AI_MDL7_MAX_TEXNAMESIZE 0x10 +// don't know why this was in the original headers ... +// to be removed in future versions typedef int32_t MD7_MATERIAL_ASCDEFSIZE; // --------------------------------------------------------------------------- diff --git a/code/MDLLoader.h b/code/MDLLoader.h index a1b75e6d5..c50b682bc 100644 --- a/code/MDLLoader.h +++ b/code/MDLLoader.h @@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct aiNode; #include "MDLFileData.h" +#include "HalfLifeFileData.h" namespace Assimp { diff --git a/code/PretransformVertices.cpp b/code/PretransformVertices.cpp new file mode 100644 index 000000000..f99e04894 --- /dev/null +++ b/code/PretransformVertices.cpp @@ -0,0 +1,378 @@ +/* +--------------------------------------------------------------------------- +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 "PretransformVertices" post processing step +*/ +#include "PretransformVertices.h" +#include "../include/DefaultLogger.h" +#include "../include/aiPostProcess.h" +#include "../include/aiMesh.h" +#include "../include/aiScene.h" +#include "../include/aiAssert.h" + +#include + +using namespace Assimp; + +// Constructor to be privately used by Importer +PretransformVertices::PretransformVertices() + { + } + +// Destructor, private as well +PretransformVertices::~PretransformVertices() + { + // nothing to do here + } + +// ------------------------------------------------------------------------------------------------ +// Returns whether the processing step is present in the given flag field. +bool PretransformVertices::IsActive( unsigned int pFlags) const +{ + return (pFlags & aiProcess_PreTransformVertices) != 0; +} +// ------------------------------------------------------------------------------------------------ +// Count the number of nodes +unsigned int CountNodes( aiNode* pcNode ) +{ + unsigned int iRet = 1; + for (unsigned int i = 0;i < pcNode->mNumChildren;++i) + { + iRet += CountNodes(pcNode->mChildren[i]); + } + return iRet; +} +// ------------------------------------------------------------------------------------------------ +// Get a bitwise combination identifying the vertex format of a mesh +unsigned int GetMeshVFormat(aiMesh* pcMesh) +{ + if (0xdeadbeef == pcMesh->mNumUVComponents[0]) + return pcMesh->mNumUVComponents[1]; + + unsigned int iRet = 0; + + // normals + if (pcMesh->HasNormals())iRet |= 0x1; + // tangents and bitangents + if (pcMesh->HasTangentsAndBitangents())iRet |= 0x2; + + // texture coordinates + unsigned int p = 0; + ai_assert(4 >= AI_MAX_NUMBER_OF_TEXTURECOORDS); + while (pcMesh->HasTextureCoords(p)) + { + iRet |= (0x100 << p++); + if (3 == pcMesh->mNumUVComponents[p]) + iRet |= (0x1000 << p++); + } + // vertex colors + p = 0; + while (pcMesh->HasVertexColors(p))iRet |= (0x10000 << p++); + + // store the value for later use + pcMesh->mNumUVComponents[0] = 0xdeadbeef; + pcMesh->mNumUVComponents[1] = iRet; + + return iRet; +} +// ------------------------------------------------------------------------------------------------ +// Count the number of vertices in the whole scene and a given +// material index +void CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, unsigned int iMat, + unsigned int iVFormat, unsigned int* piFaces, unsigned int* piVertices) +{ + for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) + { + aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ]; + if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh)) + { + *piVertices += pcMesh->mNumVertices; + *piFaces += pcMesh->mNumFaces; + } + } + for (unsigned int i = 0;i < pcNode->mNumChildren;++i) + { + CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat, + iVFormat,piFaces,piVertices); + } + return; +} + +#define AI_PTVS_VERTEX 0x0 +#define AI_PTVS_FACE 0x1 + +// ------------------------------------------------------------------------------------------------ +// Collect vertex/face data +void CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat, + unsigned int iVFormat, aiMesh* pcMeshOut, + unsigned int aiCurrent[2]) +{ + for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) + { + aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ]; + if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh)) + { + // copy positions, transform them to worldspace + for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) + { + pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] = + pcNode->mTransformation * pcMesh->mVertices[n]; + } + if (iVFormat & 0x1) + { + aiMatrix4x4 mWorldIT = pcNode->mTransformation; + mWorldIT.Inverse().Transpose(); + + // copy normals, transform them to worldspace + for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) + { + pcMeshOut->mNormals[aiCurrent[AI_PTVS_VERTEX]+n] = + mWorldIT * pcMesh->mNormals[n]; + } + } + if (iVFormat & 0x2) + { + // copy tangents + memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX], + pcMesh->mTangents, + pcMesh->mNumVertices * sizeof(aiVector3D)); + // copy bitangents + memcpy(pcMeshOut->mBitangents + aiCurrent[AI_PTVS_VERTEX], + pcMesh->mBitangents, + pcMesh->mNumVertices * sizeof(aiVector3D)); + } + unsigned int p = 0; + while (iVFormat & (0x100 << p)) + { + // copy texture coordinates + memcpy(pcMeshOut->mTextureCoords[p] + aiCurrent[AI_PTVS_VERTEX], + pcMesh->mTextureCoords[p], + pcMesh->mNumVertices * sizeof(aiVector3D)); + ++p; + } + p = 0; + while (iVFormat & (0x10000 << p)) + { + // copy vertex colors + memcpy(pcMeshOut->mColors[p] + aiCurrent[AI_PTVS_VERTEX], + pcMesh->mColors[p], + pcMesh->mNumVertices * sizeof(aiColor4D)); + ++p; + } + // now we need to copy all faces + // since we will delete the source mesh afterwards, + // we don't need to reallocate the array of indices + for (unsigned int planck = 0;planckmNumFaces;++planck) + { + pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck].mNumIndices = + pcMesh->mFaces[planck].mNumIndices; + + unsigned int* pi = pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck]. + mIndices = pcMesh->mFaces[planck].mIndices; + + // offset all vrtex indices + for (unsigned int hahn = 0; hahn < pcMesh->mFaces[planck].mNumIndices;++hahn) + { + pi[hahn] += aiCurrent[AI_PTVS_VERTEX]; + } + + // just make sure the array won't be deleted by the + // aiFace destructor ... + pcMesh->mFaces[planck].mIndices = NULL; + } + aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices; + aiCurrent[AI_PTVS_FACE] += pcMesh->mNumFaces; + } + } + for (unsigned int i = 0;i < pcNode->mNumChildren;++i) + { + CollectData(pcScene,pcNode->mChildren[i],iMat, + iVFormat,pcMeshOut,aiCurrent); + } + return; +} +// ------------------------------------------------------------------------------------------------ +// Get a list of all vertex formats that occur for a given material index +// The output list contains duplicate elements +void GetVFormatList( aiScene* pcScene, aiNode* pcNode, unsigned int iMat, + std::list& aiOut) +{ + for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) + { + aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ]; + if (iMat == pcMesh->mMaterialIndex) + { + aiOut.push_back(GetMeshVFormat(pcMesh)); + } + } + for (unsigned int i = 0;i < pcNode->mNumChildren;++i) + { + GetVFormatList(pcScene,pcNode->mChildren[i],iMat,aiOut); + } + return; +} +// ------------------------------------------------------------------------------------------------ +// Compute the absolute transformation matrices of each node +void ComputeAbsoluteTransform( aiNode* pcNode ) +{ + if (pcNode->mParent) + { + pcNode->mTransformation = pcNode->mTransformation*pcNode->mParent->mTransformation; + } + + for (unsigned int i = 0;i < pcNode->mNumChildren;++i) + { + ComputeAbsoluteTransform(pcNode->mChildren[i]); + } + return; +} +// ------------------------------------------------------------------------------------------------ +// Executes the post processing step on the given imported data. +void PretransformVertices::Execute( aiScene* pScene) +{ + DefaultLogger::get()->debug("PretransformVerticesProcess begin"); + + // first compute absolute transformation matrices for all nodes + ComputeAbsoluteTransform(pScene->mRootNode); + + // now build a list of output meshes + std::vector apcOutMeshes; + apcOutMeshes.reserve(pScene->mNumMaterials*2); + std::list aiVFormats; + for (unsigned int i = 0; i < pScene->mNumMaterials;++i) + { + // get the list of all vertex formats for this material + aiVFormats.clear(); + GetVFormatList(pScene,pScene->mRootNode,i,aiVFormats); + aiVFormats.sort(std::less()); + aiVFormats.unique(); + for (std::list::const_iterator + j = aiVFormats.begin(); + j != aiVFormats.end();++j) + { + unsigned int iVertices = 0; + unsigned int iFaces = 0; + CountVerticesAndFaces(pScene,pScene->mRootNode,i,*j,&iFaces,&iVertices); + if (iFaces && iVertices) + { + apcOutMeshes.push_back(new aiMesh()); + aiMesh* pcMesh = apcOutMeshes.back(); + pcMesh->mNumFaces = iFaces; + pcMesh->mNumVertices = iVertices; + pcMesh->mFaces = new aiFace[iFaces]; + pcMesh->mVertices = new aiVector3D[iVertices]; + pcMesh->mMaterialIndex = i; + if ((*j) & 0x1)pcMesh->mNormals = new aiVector3D[iVertices]; + if ((*j) & 0x2) + { + pcMesh->mTangents = new aiVector3D[iVertices]; + pcMesh->mBitangents = new aiVector3D[iVertices]; + } + iFaces = 0; + while ((*j) & (0x100 << iFaces)) + { + pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices]; + if ((*j) & (0x1000 << iFaces))pcMesh->mNumUVComponents[iFaces] = 3; + else pcMesh->mNumUVComponents[iFaces] = 2; + iFaces++; + } + iFaces = 0; + while ((*j) & (0x10000 << iFaces)) + pcMesh->mColors[iFaces] = new aiColor4D[iVertices]; + + // fill the mesh ... + unsigned int aiTemp[2] = {0,0}; + CollectData(pScene,pScene->mRootNode,i,*j,pcMesh,aiTemp); + } + } + } + + // remove all animations from the scene + for (unsigned int i = 0; i < pScene->mNumAnimations;++i) + delete pScene->mAnimations[i]; + pScene->mAnimations = NULL; + pScene->mNumAnimations = 0; + + // now delete all meshes in the scene and build a new mesh list + for (unsigned int i = 0; i < pScene->mNumMeshes;++i) + delete pScene->mMeshes[i]; + if (apcOutMeshes.size() != pScene->mNumMeshes) + { + delete[] pScene->mMeshes; + pScene->mNumMeshes = apcOutMeshes.size(); + pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; + } + for (unsigned int i = 0; i < pScene->mNumMeshes;++i) + pScene->mMeshes[i] = apcOutMeshes[i]; + + // now delete all nodes in the scene and build a new + // flat node graph with a root node and some level 1 children + delete pScene->mRootNode; + pScene->mRootNode = new aiNode(); + pScene->mRootNode->mName.Set(""); + + if (1 == pScene->mNumMeshes) + { + pScene->mRootNode->mNumMeshes = 1; + pScene->mRootNode->mMeshes = new unsigned int[1]; + pScene->mRootNode->mMeshes[0] = 0; + } + else + { + pScene->mRootNode->mNumChildren = pScene->mNumMeshes; + pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes]; + for (unsigned int i = 0; i < pScene->mNumMeshes;++i) + { + aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode(); + pcNode->mName.length = sprintf(pcNode->mName.data,"dummy_%i",i); + + pcNode->mNumMeshes = 1; + pcNode->mMeshes = new unsigned int[1]; + pcNode->mMeshes[0] = i; + pcNode->mParent = pScene->mRootNode; + } + } + + DefaultLogger::get()->debug("PretransformVerticesProcess finished. All " + "vertices are in worldspace now"); + return; +} + diff --git a/code/PretransformVertices.h b/code/PretransformVertices.h new file mode 100644 index 000000000..b939317c9 --- /dev/null +++ b/code/PretransformVertices.h @@ -0,0 +1,88 @@ +/* +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 a post processing step to pretransform all + vertices in the scenegraph */ +#ifndef AI_PRETRANSFORMVERTICES_H_INC +#define AI_PRETRANSFORMVERTICES_H_INC + +#include "BaseProcess.h" +#include "../include/aiMesh.h" + +namespace Assimp +{ + +// --------------------------------------------------------------------------- +/** The PretransformVertices pretransforms all vertices in the nodegraph + * and removes the whole graph. The output is a list of meshes, one for + * each material. +*/ +class PretransformVertices : public BaseProcess +{ + friend class Importer; + +protected: + /** Constructor to be privately used by Importer */ + PretransformVertices (); + + /** Destructor, private as well */ + ~PretransformVertices (); + +public: + // ------------------------------------------------------------------- + /** Returns whether the processing step is present in the given flag field. + * @param pFlags The processing flags the importer was called with. A bitwise + * combination of #aiPostProcessSteps. + * @return true if the process is present in this flag fields, false if not. + */ + bool IsActive( unsigned int pFlags) const; + + // ------------------------------------------------------------------- + /** Executes the post processing step on the given imported data. + * At the moment a process is not supposed to fail. + * @param pScene The imported data to work at. + */ + void Execute( aiScene* pScene); + +}; + +} // end of namespace Assimp + +#endif // !!AI_GENFACENORMALPROCESS_H_INC \ No newline at end of file diff --git a/code/unused/MakeVerboseFormat.cpp b/code/extra/MakeVerboseFormat.cpp similarity index 100% rename from code/unused/MakeVerboseFormat.cpp rename to code/extra/MakeVerboseFormat.cpp diff --git a/code/unused/MakeVerboseFormat.h b/code/extra/MakeVerboseFormat.h similarity index 100% rename from code/unused/MakeVerboseFormat.h rename to code/extra/MakeVerboseFormat.h diff --git a/doc/dox.h b/doc/dox.h index f00a8fdb2..61a9c6c47 100644 --- a/doc/dox.h +++ b/doc/dox.h @@ -565,8 +565,8 @@ Textures are generally defined by a set of parameters, including 1. The path to the texture. This property is always set. If it is not set, a texture is not existing. This can either be a valid path (beware, sometimes it could be a 8.3 file name!) or an asterisk (*) suceeded by a zero-based index, the latter being -a reference to an embedded texture (@link textures more details @endlink). I suggest using code -like this to find out whether a texture is embedded: +a reference to an embedded texture (see the "Textures" section for more details). I suggest using code +like this to find out whether a texture is embedded or not: @code aiString path; // contains the path obtained via aiGetMaterialString() const aiScene* scene; // valid aiScene instance @@ -606,6 +606,26 @@ the first texture in a texture slot (e.g. diffuse 0) specifies how the diffuse b vertex color have to be combined with the texture color value.
+You can use the aiGetMaterialTexture() function to read all texture parameters at once (maybe +if you're too lazy to read 4 or 5 values manually if there's a smart helper function +doing all the work for you ...). + +@code +if (AI_SUCCESS != aiGetMaterialTexture( + pcMat, // Material object + 0, // first texture in the diffuse slot + AI_TEXTYPE_DIFFUSE, // purpose of texture is diffuse + &path, // receives the path of the texture + &uv, // receives the UV index of the texture + &blend, // receives the blend factor of the texture + &op, // receives the blend operation of the texture + // (you may also specify 0 for a parameter if you don't need it) + )) +{ + // cry, jump out of the window, but don't take drugs if this occurs! +} +@endcode + @section bones Bones A mesh may have a set of bones in the form of aiBone structures.. Bones are a means to deform a mesh @@ -672,6 +692,28 @@ need them at all. @section textures Textures +Normally textures used by assets are stored in separate files, however, +there are file formats embedding their textures directly into the model file. +Such textures are loaded into an aiTexture structure. +
+There are two cases: +
+1) The texture is NOT compressed. Its color data is directly stored +in the aiTexture structure as an array of aiTexture::mWidth * aiTexture::mHeight aiTexel structures. Each aiTexel represents a pixel (or "texel") of the texture +image. The color data is stored in an unsigned RGBA8888 format, which can be easily used for +both Direct3D and OpenGL (swizzling the order of the color components might be necessary). +RGBA8888 has been chosen because it is well-known, easy to use and natively +supported by nearly all graphics APIs. +
+2) This is the case for aiTexture::mHeight == 0. The texture is stored in a +"compressed" format such as DDS or PNG. The term "compressed" does not mean that the +texture data must actually be compressed, however the texture was stored in the +model file as if it was stored in a separate file on the harddisk. Appropriate +decoders (such as libjpeg, libpng, D3DX, DevIL) are required to load theses textures. +aiTexture::mWidth specifies the size of the texture data in bytes, aiTexture::pcData is +a pointer to the raw image data and aiTexture::achFormatHint is either zeroed or +containing the file extension of the format of the embedded texture. This is only +set if ASSIMP is able to determine the file format. */ /** diff --git a/include/aiPostProcess.h b/include/aiPostProcess.h index 052e67da3..d9f82e6d5 100644 --- a/include/aiPostProcess.h +++ b/include/aiPostProcess.h @@ -108,7 +108,23 @@ enum aiPostProcessSteps * in the internal SplitLargeMeshes.h header as AI_SLM_DEFAULT_MAX_VERTICES * and AI_SLM_DEFAULT_MAX_TRIANGLES. */ - aiProcess_SplitLargeMeshes = 0x80 + aiProcess_SplitLargeMeshes = 0x80, + + /** Removes the node graph and pretransforms all vertices with + * the local transformation matrices of their nodes. The output + * scene does still contain nodes, however, there is only a + * root node with childs, each one referencing only one mesh, + * each mesh referencing one material. For rendering, you can + * simply render all meshes in order, you don't need to pay + * attention to local transformations and the node hierarchy. + * Animations are removed during this step. + * This step is intended for applications that have no scenegraph. + * The step CAN cause some problems: if e.g. a mesh of the asset + * contains normals and another, using the same material index, does not, + * they will be brought together, but the first meshes's part of + * the normal list will be zeroed. + */ + aiProcess_PreTransformVertices = 0x100, }; // --------------------------------------------------------------------------- diff --git a/include/aiTexture.h b/include/aiTexture.h index 333c9321f..7c26cce41 100644 --- a/include/aiTexture.h +++ b/include/aiTexture.h @@ -87,7 +87,7 @@ struct aiTexture { /** Width of the texture, in pixels * - * If mHeight is zero the texture is compressedin a format + * If mHeight is zero the texture is compressed in a format * like JPEG. In this case mWidth specifies the size of the * memory area pcData is pointing to, in bytes. */ diff --git a/port/jAssimp/src/assimp/Animation.java b/port/jAssimp/src/assimp/Animation.java index cf9b525b0..487809079 100644 --- a/port/jAssimp/src/assimp/Animation.java +++ b/port/jAssimp/src/assimp/Animation.java @@ -62,6 +62,6 @@ public class Animation extends Mappable { } protected void onMap() throws NativeError { - + } } diff --git a/port/jAssimp/src/assimp/CompressedTexture.java b/port/jAssimp/src/assimp/CompressedTexture.java index af1624a41..dea38c7e9 100644 --- a/port/jAssimp/src/assimp/CompressedTexture.java +++ b/port/jAssimp/src/assimp/CompressedTexture.java @@ -70,8 +70,8 @@ public class CompressedTexture extends Texture { super(parent, index); // need to get the format of the texture via the JNI - if ((m_format = this._NativeGetCTextureFormat(((Scene) this.getParent()). - getImporter().getContext(), this.getArrayIndex())).equals("")) { + if ((m_format = this._NativeGetCTextureFormat(((Scene) this.getParent()). + getImporter().getContext(), this.getArrayIndex())).equals("")) { throw new NativeError("Unable to get the format of the compressed texture"); } } @@ -80,8 +80,9 @@ public class CompressedTexture extends Texture { * Retrieves the format of the texture data. This is * the most common file extension of the format (without a * dot at the beginning). Examples include dds, png, jpg ... + * * @return Extension string or null if the format of the texture - * data is not known to ASSIMP. + * data is not known to ASSIMP. */ public String getFormat() { return m_format; @@ -89,6 +90,7 @@ public class CompressedTexture extends Texture { /** * Get a pointer to the data of the compressed texture + * * @return Data poiner */ public byte[] getData() { @@ -100,11 +102,12 @@ public class CompressedTexture extends Texture { return null; } } - return (byte[])data; + return (byte[]) data; } /** * Get the length of the data of the compressed texture + * * @return Data poiner */ public int getLength() { @@ -113,39 +116,43 @@ public class CompressedTexture extends Texture { /** * Returns 0 for compressed textures + * * @return n/a */ - @Override + @Override public int getHeight() { return 0; } /** * Returns 0 for compressed textures + * * @return n/a */ - @Override + @Override public int getWidth() { return 0; } /** * Returns null for compressed textures + * * @return n/a */ - @Override - public Color getPixel(int x, int y) { + @Override + public Color getPixel(int x, int y) { return null; - } + } /** * Returns null for compressed textures + * * @return n/a */ @Override public Color[] getColorArray() { - return null; - } + return null; + } /** * Internal helper function to map the native texture data into @@ -162,14 +169,14 @@ public class CompressedTexture extends Texture { // and copy the native color data to it if (0xffffffff == this._NativeMapColorData( - ((Scene)this.getParent()).getImporter().getContext(), - this.getArrayIndex(),temp)) { - throw new NativeError("Unable to map compressed aiTexture into the Java-VM"); + ((Scene) this.getParent()).getImporter().getContext(), + this.getArrayIndex(), temp)) { + throw new NativeError("Unable to map compressed aiTexture into the Java-VM"); } DefaultLogger.get().debug("CompressedTexture.onMap successful"); return; } - private native String _NativeGetCTextureFormat(long context, int arrayIndex); + private native String _NativeGetCTextureFormat(long context, int arrayIndex); } diff --git a/port/jAssimp/src/assimp/DefaultLogger.java b/port/jAssimp/src/assimp/DefaultLogger.java index 847c3f47f..1d2ab08d9 100644 --- a/port/jAssimp/src/assimp/DefaultLogger.java +++ b/port/jAssimp/src/assimp/DefaultLogger.java @@ -390,12 +390,15 @@ public class DefaultLogger implements Logger { public static void _NativeCallWriteError(String message) { DefaultLogger.get().error(message); } + public static void _NativeCallWriteWarn(String message) { DefaultLogger.get().warn(message); } + public static void _NativeCallWriteInfo(String message) { DefaultLogger.get().info(message); } + public static void _NativeCallWriteDebug(String message) { DefaultLogger.get().debug(message); } diff --git a/port/jAssimp/src/assimp/Importer.java b/port/jAssimp/src/assimp/Importer.java index e1db29102..7fad5cf4a 100644 --- a/port/jAssimp/src/assimp/Importer.java +++ b/port/jAssimp/src/assimp/Importer.java @@ -188,7 +188,7 @@ public class Importer { * @param path Path to the file to be read * @return null if the import failed, otherwise a valid Scene instance * @throws NativeError This exception is thrown when an unknown error - * occurs in the JNI bridge module. + * occurs in the JNI bridge module. */ public Scene readFile(String path) throws NativeError { this.scene = new Scene(this); @@ -212,6 +212,7 @@ public class Importer { else if (step.equals(PostProcessStep.GenFaceNormals)) flags |= 0x20; else if (step.equals(PostProcessStep.GenSmoothNormals)) flags |= 0x40; else if (step.equals(PostProcessStep.SplitLargeMeshes)) flags |= 0x80; + else if (step.equals(PostProcessStep.PreTransformVertices)) flags |= 0x100; } // now load the mesh @@ -222,7 +223,7 @@ public class Importer { } // and setup our Scene object try { - this.scene.construct(); + this.scene.construct(); } catch (NativeError exc) { @@ -288,6 +289,7 @@ public class Importer { /** * Retrieves the native context of the class. This is normally the * address of the native Importer object. + * * @return Native context */ public long getContext() { diff --git a/port/jAssimp/src/assimp/LogStream.java b/port/jAssimp/src/assimp/LogStream.java index 21d18c442..e824834d3 100644 --- a/port/jAssimp/src/assimp/LogStream.java +++ b/port/jAssimp/src/assimp/LogStream.java @@ -56,6 +56,7 @@ public interface LogStream { /** * Override this for your own output implementations + * * @param message Message to be written to the log stream */ public void write(String message); diff --git a/port/jAssimp/src/assimp/Logger.java b/port/jAssimp/src/assimp/Logger.java index b2e4e363c..3c19d103a 100644 --- a/port/jAssimp/src/assimp/Logger.java +++ b/port/jAssimp/src/assimp/Logger.java @@ -54,63 +54,69 @@ public interface Logger { /** * Debug log message */ - public static final int ERRORSEVERITY_DEBUGGING = 0x1; + public static final int ERRORSEVERITY_DEBUGGING = 0x1; - /** + /** * Information log message */ - public static final int ERRORSEVERITY_INFO = 0x2; + public static final int ERRORSEVERITY_INFO = 0x2; - /** + /** * Warn log message */ - public static final int ERRORSEVERITY_WARN = 0x4; + public static final int ERRORSEVERITY_WARN = 0x4; - /** + /** * Error log message */ - public static final int ERRORSEVERITY_ERR = 0x8; + public static final int ERRORSEVERITY_ERR = 0x8; /** * Write a debug message to the log + * * @param message Message to be logged */ public void debug(String message); /** * Write an error message to the log + * * @param message Message to be logged */ public void error(String message); /** * Write a warn message to the log + * * @param message Message to be logged */ public void warn(String message); /** * Write an info message to the log + * * @param message Message to be logged */ public void info(String message); /** * Attach a logstream to the logger - * @param stream Log stream instance + * + * @param stream Log stream instance * @param severity Error severity. Bitwise combination of the - * ERRORSEVERITY_XXX constants. Specify 0 to attach the - * stream to all types of log messages. + * ERRORSEVERITY_XXX constants. Specify 0 to attach the + * stream to all types of log messages. */ public void attachStream(LogStream stream, int severity); /** * Detach a logstream from the logger - * @param stream Log stream instance + * + * @param stream Log stream instance * @param severity Error severities to detach the stream from. - * Bitwise combination of the ERRORSEVERITY_XXX constants. - * Specify 0 to detach the stream from all types of log messages. + * Bitwise combination of the ERRORSEVERITY_XXX constants. + * Specify 0 to detach the stream from all types of log messages. */ public void detachStream(LogStream stream, int severity); } diff --git a/port/jAssimp/src/assimp/Mappable.java b/port/jAssimp/src/assimp/Mappable.java index f10868b1b..ddfa73158 100644 --- a/port/jAssimp/src/assimp/Mappable.java +++ b/port/jAssimp/src/assimp/Mappable.java @@ -64,8 +64,9 @@ public abstract class Mappable { /** * Construction from a given parent object and array index + * * @param parent Must be valid, null is not allowed - * @param index Valied index in the parent's list + * @param index Valied index in the parent's list */ public Mappable(Object parent, int index) { m_parent = parent; @@ -77,6 +78,7 @@ public abstract class Mappable { * data into the address space of the Java virtual machine. * After this method has been called the class instance must * be ready to be used without an underyling native aiScene + * * @throws NativeError */ protected abstract void onMap() throws NativeError; @@ -84,6 +86,7 @@ public abstract class Mappable { /** * Retrieve the index ofthe mappable object in the parent mesh + * * @return Value between 0 and n-1 */ public int getArrayIndex() { @@ -92,6 +95,7 @@ public abstract class Mappable { /** * Provide access to the parent + * * @return Never null ... */ public Object getParent() { diff --git a/port/jAssimp/src/assimp/Mesh.java b/port/jAssimp/src/assimp/Mesh.java index bbc84af16..ecac0353a 100644 --- a/port/jAssimp/src/assimp/Mesh.java +++ b/port/jAssimp/src/assimp/Mesh.java @@ -782,7 +782,7 @@ public class Mesh extends Mappable { this.m_vFaces)) { // this should occur rarely. No need to throw an exception, // simply write to log and let the array at 0 - DefaultLogger.get().error("Unable to map faces into JVM memory"); + DefaultLogger.get().error("Unable to map faces into JVM memory"); } } @@ -793,7 +793,7 @@ public class Mesh extends Mappable { channel, this.m_avUVs[channel])) { // this should occur rarely. No need to throw an exception, // simply write to log and let the array at 0.0f - DefaultLogger.get().error("Unable to map UV coordinate set " + channel + " into JVM memory"); + DefaultLogger.get().error("Unable to map UV coordinate set " + channel + " into JVM memory"); } } @@ -804,7 +804,7 @@ public class Mesh extends Mappable { channel, this.m_avColors[channel])) { // this should occur rarely. No need to throw an exception, // simply write to log and let the array at 0.0f - DefaultLogger.get().error("Unable to map vertex color channel " + channel + " into JVM memory"); + DefaultLogger.get().error("Unable to map vertex color channel " + channel + " into JVM memory"); } } diff --git a/port/jAssimp/src/assimp/NativeError.java b/port/jAssimp/src/assimp/NativeError.java index 49688dcae..4775c2b82 100644 --- a/port/jAssimp/src/assimp/NativeError.java +++ b/port/jAssimp/src/assimp/NativeError.java @@ -48,10 +48,10 @@ package assimp; public class NativeError extends Exception { public NativeError() { - super("Unknown error"); + super("Unknown error"); } public NativeError(String sz) { - super(sz); + super(sz); } } diff --git a/port/jAssimp/src/assimp/PostProcessStep.java b/port/jAssimp/src/assimp/PostProcessStep.java index 3561dae94..b1983d1de 100644 --- a/port/jAssimp/src/assimp/PostProcessStep.java +++ b/port/jAssimp/src/assimp/PostProcessStep.java @@ -52,11 +52,13 @@ package assimp; */ public class PostProcessStep { - /** Default vertex split limit for the SplitLargeMeshes process + /** + * Default vertex split limit for the SplitLargeMeshes process */ public static final int DEFAULT_VERTEX_SPLIT_LIMIT = 1000000; - /** Default triangle split limit for the SplitLargeMeshes process + /** + * Default triangle split limit for the SplitLargeMeshes process */ public static final int DEFAULT_TRIANGLE_SPLIT_LIMIT = 1000000; @@ -140,13 +142,26 @@ public class PostProcessStep { new PostProcessStep("ConvertToLeftHanded "); + /** + * Removes the node graph and pretransforms all vertices with the local + * transformation matrices of their nodes. The output scene does still + * contain nodes, however, there is only a root node with childs, each + * one referencing only one mesh, each mesh referencing one material. + * For rendering, you can simply render all meshes in order, you don't + * need to pay attention to local transformations and the node hierarchy. + * Animations are removed during this step. + */ + public static final PostProcessStep PreTransformVertices = + new PostProcessStep("PreTransformVertices"); + + /** * Set the vertex split limit for the "SplitLargeMeshes" process * If a mesh exceeds this limit it will be splitted * * @param limit New vertex split limit. Pass 0xffffffff to disable - * a vertex split limit. However, splitting by triangles is still active - * then. + * a vertex split limit. However, splitting by triangles is still active + * then. * @return Old vertex split limit */ public static synchronized int setVertexSplitLimit(int limit) { @@ -163,8 +178,8 @@ public class PostProcessStep { * If a mesh exceeds this limit it will be splitted * * @param limit new triangle split limit. Pass 0xffffffff to disable - * a triangle split limit. However, splitting by vertices is still active - * then. + * a triangle split limit. However, splitting by vertices is still active + * then. * @return Old triangle split limit */ public static synchronized int setTriangleSplitLimit(int limit) { diff --git a/port/jAssimp/src/assimp/Texture.java b/port/jAssimp/src/assimp/Texture.java index b4ead21f4..e3c1b41d8 100644 --- a/port/jAssimp/src/assimp/Texture.java +++ b/port/jAssimp/src/assimp/Texture.java @@ -73,12 +73,12 @@ public class Texture extends Mappable { super(parent, index); long lTemp; - if (0x0 == (lTemp = this._NativeGetTextureInfo(((Scene)this.getParent()). - getImporter().getContext(),this.getArrayIndex()))) { + if (0x0 == (lTemp = this._NativeGetTextureInfo(((Scene) this.getParent()). + getImporter().getContext(), this.getArrayIndex()))) { throw new NativeError("Unable to get the width and height of the texture"); } - this.width = (int)(lTemp); - this.height = (int)(lTemp >> 32); + this.width = (int) (lTemp); + this.height = (int) (lTemp >> 32); } @@ -119,16 +119,17 @@ public class Texture extends Mappable { return Color.black; } } - return ((Color[])data)[y * width + x]; + return ((Color[]) data)[y * width + x]; } /** * Get a pointer to the color buffer of the texture + * * @return Array of java.awt.Color, size: width * height */ public Color[] getColorArray() { - // map the color data in memory if required ... + // map the color data in memory if required ... if (null == data) { try { this.onMap(); @@ -136,7 +137,7 @@ public class Texture extends Mappable { return null; } } - return (Color[])data; + return (Color[]) data; } /** @@ -154,9 +155,9 @@ public class Texture extends Mappable { byte[] temp = new byte[(iNumPixels) << 2]; // and copy the native color data to it - if (0xffffffff == this._NativeMapColorData(((Scene)this.getParent()).getImporter().getContext(), - this.getArrayIndex(),temp)) { - throw new NativeError("Unable to map aiTexture into the Java-VM"); + if (0xffffffff == this._NativeMapColorData(((Scene) this.getParent()).getImporter().getContext(), + this.getArrayIndex(), temp)) { + throw new NativeError("Unable to map aiTexture into the Java-VM"); } DefaultLogger.get().debug("Texture.onMap successful"); @@ -164,7 +165,7 @@ public class Texture extends Mappable { // now convert the temporary representation to a Color array // (data is given in BGRA order, we need RGBA) for (int i = 0, iBase = 0; i < iNumPixels; ++i, iBase += 4) { - ((Color[])data)[i] = new Color(temp[iBase + 2], temp[iBase + 1], temp[iBase], temp[iBase + 3]); + ((Color[]) data)[i] = new Color(temp[iBase + 2], temp[iBase + 1], temp[iBase], temp[iBase + 3]); } return; } @@ -175,8 +176,8 @@ public class Texture extends Mappable { * the native memory area will be deleted afterwards. * * @param context Current importer context (imp.hashCode) - * @param index Index of the texture in the scene - * @param temp Output array. Assumed to be width * height * 4 in size + * @param index Index of the texture in the scene + * @param temp Output array. Assumed to be width * height * 4 in size * @return 0xffffffff if an error occured */ protected native int _NativeMapColorData(long context, long index, byte[] temp); @@ -186,10 +187,9 @@ public class Texture extends Mappable { * The method retrieves information on the underlying texture * * @param context Current importer context (imp.hashCode) - * @param index Index of the texture in the scene + * @param index Index of the texture in the scene * @return 0x0 if an error occured, otherwise the width in the lower 32 bits - * and the height in the higher 32 bits - * + * and the height in the higher 32 bits */ private native long _NativeGetTextureInfo(long context, long index); } diff --git a/port/jAssimp/src/assimp/test/DumpToFile.java b/port/jAssimp/src/assimp/test/DumpToFile.java index 3a01db3b7..2d48fc395 100644 --- a/port/jAssimp/src/assimp/test/DumpToFile.java +++ b/port/jAssimp/src/assimp/test/DumpToFile.java @@ -67,8 +67,7 @@ public class DumpToFile { arguments = new String[2]; arguments[0] = s; arguments[1] = "output.txt"; - } - else if (2 != arguments.length)return; + } else if (2 != arguments.length) return; FileWriter stream; try { @@ -136,10 +135,10 @@ public class DumpToFile { * at the moment! */ float[] positions = mesh.getPositionArray(); - float[] normals = mesh.getNormalArray(); + float[] normals = mesh.getNormalArray(); float[] tangents = mesh.getTangentArray(); float[] bitangents = mesh.getBitangentArray(); - for (int i = 0;i < mesh.getNumVertices();++i) { + for (int i = 0; i < mesh.getNumVertices(); ++i) { // format: "Vertex pos(x|y|z) nor(x|y|z) tan(x|y|) bit(x|y|z)" // great that this IDE is automatically able to replace + with append ... ;-) @@ -167,7 +166,7 @@ public class DumpToFile { /* Now write a list of all faces in this model */ int[] faces = mesh.getFaceArray(); - for (int i = 0; i < mesh.getNumFaces();++i) { + for (int i = 0; i < mesh.getNumFaces(); ++i) { stream.write(new StringBuilder().append("\tFace ("). append(faces[i * 3]).append("|"). append(faces[i * 3 + 1]).append("|"). diff --git a/tools/assimp_view/Display.cpp b/tools/assimp_view/Display.cpp index 9d2b608e1..7a7d54baa 100644 --- a/tools/assimp_view/Display.cpp +++ b/tools/assimp_view/Display.cpp @@ -139,6 +139,7 @@ int CDisplay::ClearDisplayList(void) { // clear the combo box TreeView_DeleteAllItems(GetDlgItem(g_hDlg,IDC_TREE1)); + this->Reset(); return 1; } //------------------------------------------------------------------------------- @@ -756,8 +757,31 @@ int CDisplay::OnRender() return 1; } //------------------------------------------------------------------------------- +void UpdateColorFieldsInUI() +{ + InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE); + InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),NULL,TRUE); + InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE); + + UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1)); + UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2)); + UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3)); +} +//------------------------------------------------------------------------------- int CDisplay::FillDefaultStatistics(void) { + if (!g_pcAsset) + { + // clear all stats edit controls + SetDlgItemText(g_hDlg,IDC_EVERT,"0"); + SetDlgItemText(g_hDlg,IDC_EFACE,"0"); + SetDlgItemText(g_hDlg,IDC_EMAT,"0"); + SetDlgItemText(g_hDlg,IDC_ENODE,"0"); + SetDlgItemText(g_hDlg,IDC_ESHADER,"0"); + SetDlgItemText(g_hDlg,IDC_ETEX,"0"); + return 1; + } + // get the number of vertices/faces in the model unsigned int iNumVert = 0; unsigned int iNumFaces = 0; @@ -791,6 +815,7 @@ int CDisplay::FillDefaultStatistics(void) sprintf(szOut,"%.5f",(float)g_fLoadTime); SetDlgItemText(g_hDlg,IDC_ELOAD,szOut); + UpdateColorFieldsInUI(); UpdateWindow(g_hDlg); return 1; } @@ -807,19 +832,24 @@ int CDisplay::Reset(void) return this->OnSetupNormalView(); } //------------------------------------------------------------------------------- -void UpdateColorFieldsInUI() +void ShowNormalUIComponents() { - InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR1),NULL,TRUE); - InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR2),NULL,TRUE); - InvalidateRect(GetDlgItem(g_hDlg,IDC_LCOLOR3),NULL,TRUE); - - UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR1)); - UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR2)); - UpdateWindow(GetDlgItem(g_hDlg,IDC_LCOLOR3)); + ShowWindow(GetDlgItem(g_hDlg,IDC_NUMNODES),SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg,IDC_ENODEWND),SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg,IDC_NUMSHADERS),SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg,IDC_LOADTIME),SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg,IDC_ESHADER),SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg,IDC_ELOAD),SW_SHOW); + ShowWindow(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),SW_HIDE); } //------------------------------------------------------------------------------- int CDisplay::OnSetupNormalView() { + if (VIEWMODE_NODE == this->m_iViewMode) + { + ShowNormalUIComponents(); + } + // now ... change the meaning of the statistics fields back SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Verts:"); SetWindowText(GetDlgItem(g_hDlg,IDC_NUMNODES),"Nodes:"); @@ -848,6 +878,41 @@ int CDisplay::OnSetupNodeView(NodeInfo* pcNew) ai_assert(NULL != pcNew); if (this->m_pcCurrentNode == pcNew)return 2; + + // now ... change the meaning of the statistics fields back + SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Verts:"); + SetWindowText(GetDlgItem(g_hDlg,IDC_NUMFACES),"Faces:"); + SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMATS),"Mats:"); + SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMESHES),"Mesh:"); + + ShowWindow(GetDlgItem(g_hDlg,IDC_NUMNODES),SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg,IDC_ENODEWND),SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg,IDC_NUMSHADERS),SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg,IDC_LOADTIME),SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg,IDC_ESHADER),SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg,IDC_ELOAD),SW_HIDE); + ShowWindow(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),SW_SHOW); + + char szTemp[1024]; + sprintf(szTemp, + "%.2f %.2f %.2f\r\n" + "%.2f %.2f %.2f\r\n" + "%.2f %.2f %.2f\r\n" + "%.2f %.2f %.2f\r\n", + pcNew->psNode->mTransformation.a1, + pcNew->psNode->mTransformation.b1, + pcNew->psNode->mTransformation.c1, + pcNew->psNode->mTransformation.a2, + pcNew->psNode->mTransformation.b2, + pcNew->psNode->mTransformation.c2, + pcNew->psNode->mTransformation.a3, + pcNew->psNode->mTransformation.b3, + pcNew->psNode->mTransformation.c3, + pcNew->psNode->mTransformation.a4, + pcNew->psNode->mTransformation.b4, + pcNew->psNode->mTransformation.c4); + SetWindowText(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),szTemp); + this->m_pcCurrentNode = pcNew; this->SetViewMode(VIEWMODE_NODE); @@ -861,6 +926,11 @@ int CDisplay::OnSetupMaterialView(MaterialInfo* pcNew) if (this->m_pcCurrentMaterial == pcNew)return 2; + if (VIEWMODE_NODE == this->m_iViewMode) + { + ShowNormalUIComponents(); + } + this->m_pcCurrentMaterial = pcNew; this->SetViewMode(VIEWMODE_MATERIAL); @@ -876,6 +946,12 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew) ai_assert(NULL != pcNew); if (this->m_pcCurrentTexture == pcNew)return 2; + + if (VIEWMODE_NODE == this->m_iViewMode) + { + ShowNormalUIComponents(); + } + if ((AI_TEXTYPE_OPACITY | 0x40000000) == pcNew->iType) { // for opacity textures display a warn message diff --git a/tools/assimp_view/MessageProc.cpp b/tools/assimp_view/MessageProc.cpp index 9bb83dcf1..ff85bf777 100644 --- a/tools/assimp_view/MessageProc.cpp +++ b/tools/assimp_view/MessageProc.cpp @@ -1329,6 +1329,10 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg, b = (unsigned char)(CDisplay::Instance().GetFirstCheckerColor()->z * 255.0f); szText = "B0"; } + else if (!g_pcAsset) + { + r = g = b = 150;szText = "-"; + } else { r = (unsigned char)((g_avLightColors[0] >> 16) & 0xFF); @@ -1358,6 +1362,10 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg, b = (unsigned char)(CDisplay::Instance().GetSecondCheckerColor()->z * 255.0f); szText = "B1"; } + else if (!g_pcAsset) + { + r = g = b = 150;szText = "-"; + } else { r = (unsigned char)((g_avLightColors[1] >> 16) & 0xFF); @@ -1383,6 +1391,10 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg, r = g = b = 0; szText = "-"; } + else if (!g_pcAsset) + { + r = g = b = 150;szText = "-"; + } else { r = (unsigned char)((g_avLightColors[2] >> 16) & 0xFF); diff --git a/tools/assimp_view/Normals.cpp b/tools/assimp_view/Normals.cpp index fc1b1d6ba..1c9ce0948 100644 --- a/tools/assimp_view/Normals.cpp +++ b/tools/assimp_view/Normals.cpp @@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "GenVertexNormalsProcess.h" #include "JoinVerticesProcess.h" #include "CalcTangentsProcess.h" -#include "unused/MakeVerboseFormat.h" +#include "extra/MakeVerboseFormat.h" namespace AssimpView { diff --git a/tools/assimp_view/assimp_view.aps b/tools/assimp_view/assimp_view.aps index 2c2ad83f5..23b7098a4 100644 Binary files a/tools/assimp_view/assimp_view.aps and b/tools/assimp_view/assimp_view.aps differ diff --git a/tools/assimp_view/assimp_view.cpp b/tools/assimp_view/assimp_view.cpp index 6064acb33..d3b4c041f 100644 --- a/tools/assimp_view/assimp_view.cpp +++ b/tools/assimp_view/assimp_view.cpp @@ -268,14 +268,6 @@ int DeleteAsset(void) delete g_pcAsset; g_pcAsset = NULL; - // clear all stats edit controls - SetDlgItemText(g_hDlg,IDC_EVERT,"0"); - SetDlgItemText(g_hDlg,IDC_EFACE,"0"); - SetDlgItemText(g_hDlg,IDC_EMAT,"0"); - SetDlgItemText(g_hDlg,IDC_ENODE,"0"); - SetDlgItemText(g_hDlg,IDC_ESHADER,"0"); - SetDlgItemText(g_hDlg,IDC_ETEX,"0"); - // reset the caption of the viewer window SetWindowText(g_hDlg,AI_VIEW_CAPTION_BASE); @@ -284,6 +276,7 @@ int DeleteAsset(void) CDisplay::Instance().ClearDisplayList(); CMaterialManager::Instance().Reset(); + UpdateWindow(g_hDlg); return 1; } diff --git a/tools/assimp_view/assimp_view.rc b/tools/assimp_view/assimp_view.rc index 1a16da64c..58eeeee2e 100644 --- a/tools/assimp_view/assimp_view.rc +++ b/tools/assimp_view/assimp_view.rc @@ -67,16 +67,16 @@ BEGIN CONTROL "Toggle Wireframe",IDC_TOGGLEWIRE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,183,73,10 CONTROL "Disable Materials",IDC_TOGGLEMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,193,69,10 LTEXT "Verts:",IDC_NUMVERTS,475,14,47,8 - LTEXT "Faces:\t",IDC_NUMFACES,475,26,45,8 + LTEXT "Faces:\t",IDC_NUMFACES,539,14,27,8 LTEXT "Mats:",IDC_NUMMATS,540,26,26,8 LTEXT "FPS:",IDC_FPS,540,51,21,8 CONTROL "Display Normals",IDC_TOGGLENORMALS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,203,66,10 CONTROL "Toggle AutoRotate",IDC_AUTOROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,257,74,10 CONTROL 130,IDC_STATIC,"Static",SS_BITMAP,0,360,600,25 EDITTEXT IDC_EVERT,504,11,32,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_EFACE,504,24,32,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_EMAT,564,24,27,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_EFPS,564,50,27,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EFACE,562,11,29,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EMAT,562,24,29,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EFPS,562,50,29,12,ES_AUTOHSCROLL | ES_READONLY CONTROL "Rotate light sources",IDC_LIGHTROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,276,74,10 CONTROL "2 directional lights",IDC_3LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,213,73,10 LTEXT "Time:",IDC_LOADTIME,475,51,46,8 @@ -113,16 +113,17 @@ BEGIN CONTROL 149,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,583,161,10,9 CONTROL 149,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,584,245,10,9 CONTROL 149,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,584,287,10,9 - LTEXT "Nodes:",IDC_NUMNODES,540,13,24,8 - EDITTEXT IDC_ENODEWND,564,11,27,12,ES_AUTOHSCROLL | ES_READONLY + LTEXT "Nodes:",IDC_NUMNODES,476,26,24,8 + EDITTEXT IDC_ENODEWND,504,24,32,12,ES_AUTOHSCROLL | ES_READONLY CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,470,74,123,88 LTEXT "Mesh:",IDC_NUMMESHES,540,39,20,8 - EDITTEXT IDC_EMESH,564,37,27,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_EMESH,562,37,29,12,ES_AUTOHSCROLL | ES_READONLY CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,567,170,1,75 CONTROL "Button1",IDC_LCOLOR1,"Button",BS_OWNERDRAW | WS_TABSTOP,570,174,21,17 CONTROL "Button1",IDC_LCOLOR2,"Button",BS_OWNERDRAW | WS_TABSTOP,570,194,21,17 CONTROL "Button1",IDC_LCOLOR3,"Button",BS_OWNERDRAW | WS_TABSTOP,570,214,21,17 PUSHBUTTON "R",IDC_LRESET,576,232,15,11,BS_BOTTOM + EDITTEXT IDC_VIEWMATRIX,475,24,61,38,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_VISIBLE END IDD_LOADDIALOG DIALOGEX 0, 0, 278, 99 diff --git a/tools/assimp_view/resource.h b/tools/assimp_view/resource.h index b2bf9354f..fc279e9b2 100644 --- a/tools/assimp_view/resource.h +++ b/tools/assimp_view/resource.h @@ -97,6 +97,8 @@ #define IDC_LCOLOR3 1044 #define IDC_LRESET 1046 #define IDC_NUMMESHES 1047 +#define IDC_VIEWMAT 1048 +#define IDC_VIEWMATRIX 1048 #define ID_VIEWER_OPEN 32771 #define ID_VIEWER_CLOSETHIS 32772 #define ID_VIEWER_CLOSEASSET 32773 @@ -158,7 +160,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 158 #define _APS_NEXT_COMMAND_VALUE 32823 -#define _APS_NEXT_CONTROL_VALUE 1048 +#define _APS_NEXT_CONTROL_VALUE 1049 #define _APS_NEXT_SYMED_VALUE 110 #endif #endif diff --git a/workspaces/vc8/assimp.vcproj b/workspaces/vc8/assimp.vcproj index 8f3042429..a92c24abb 100644 --- a/workspaces/vc8/assimp.vcproj +++ b/workspaces/vc8/assimp.vcproj @@ -588,6 +588,10 @@ RelativePath="..\..\code\MaterialSystem.h" > + + @@ -719,6 +723,10 @@ + + @@ -804,7 +812,7 @@ Name="extra" > @@ -864,6 +872,10 @@ RelativePath="..\..\code\MaterialSystem.cpp" > + + @@ -1008,7 +1020,7 @@ Name="extra" >