diff --git a/code/3DSConverter.cpp b/code/3DSConverter.cpp index 995b0f631..7336b9251 100644 --- a/code/3DSConverter.cpp +++ b/code/3DSConverter.cpp @@ -330,9 +330,12 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat, if( oldMat.sTexShininess.mMapName.length() > 0) CopyTexture(mat,oldMat.sTexShininess, aiTextureType_SHININESS); + // REFLECTION texture + if( oldMat.sTexReflective.mMapName.length() > 0) + CopyTexture(mat,oldMat.sTexReflective, aiTextureType_REFLECTION); + // Store the name of the material itself, too - if( oldMat.mName.length()) - { + if( oldMat.mName.length()) { aiString tex; tex.Set( oldMat.mName); mat.AddProperty( &tex, AI_MATKEY_NAME); @@ -435,8 +438,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, iArray.reserve(3); aiMatrix4x4 abs; - if (pcIn->mName == "$$$DUMMY") - { + if (pcIn->mName == "$$$DUMMY") { // FIX: Append the "real" name of the dummy to the string pcIn->mName = "Dummy." + pcIn->mDummyName; } @@ -495,11 +497,10 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut, // Now build the transformation matrix of the node // ROTATION - if (pcIn->aRotationKeys.size()) - { + if (pcIn->aRotationKeys.size()){ pcOut->mTransformation = aiMatrix4x4( pcIn->aRotationKeys[0].mValue.GetMatrix() ); } - else if (pcIn->aCameraRollKeys.size()) + else if (pcIn->aCameraRollKeys.size()) { aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(- pcIn->aCameraRollKeys[0].mValue), pcOut->mTransformation); diff --git a/code/3DSHelper.h b/code/3DSHelper.h index ae4bfb2ec..40ea8ab79 100644 --- a/code/3DSHelper.h +++ b/code/3DSHelper.h @@ -400,6 +400,8 @@ struct Material Texture sTexOpacity; //! Specular texture channel Texture sTexSpecular; + //! Reflective texture channel + Texture sTexReflective; //! Bump texture channel Texture sTexBump; //! Emissive texture channel diff --git a/code/3DSLoader.cpp b/code/3DSLoader.cpp index ad8deccd0..5f63e8fce 100644 --- a/code/3DSLoader.cpp +++ b/code/3DSLoader.cpp @@ -669,8 +669,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent) // This is the "real" name of a $$$DUMMY object { - if (mCurrentNode->mName != "$$$DUMMY") - { + if (mCurrentNode->mName != "$$$DUMMY") { DefaultLogger::get()->warn("3DS: Skipping dummy object name for non-dummy object"); break; } @@ -947,11 +946,11 @@ void Discreet3DSImporter::ParseFaceChunk() { DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz); - // ****************************************************************** + // -------------------------------------------------------------- // This material is not known. Ignore this. We will later // assign the default material to all faces using *this* // material. We use 0xcdcdcdcd as special value to indicate this. - // ****************************************************************** + // -------------------------------------------------------------- } // Now continue and read all material indices @@ -1126,8 +1125,7 @@ void Discreet3DSImporter::ParseMaterialChunk() // This is the diffuse material color aiColor3D* pc = &mScene->mMaterials.back().mDiffuse; ParseColorChunk(pc); - if (is_qnan(pc->r)) - { + if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it DefaultLogger::get()->error("3DS: Unable to read DIFFUSE chunk"); pc->r = pc->g = pc->b = 1.0f; @@ -1139,8 +1137,7 @@ void Discreet3DSImporter::ParseMaterialChunk() // This is the specular material color aiColor3D* pc = &mScene->mMaterials.back().mSpecular; ParseColorChunk(pc); - if (is_qnan(pc->r)) - { + if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it DefaultLogger::get()->error("3DS: Unable to read SPECULAR chunk"); pc->r = pc->g = pc->b = 1.0f; @@ -1152,8 +1149,7 @@ void Discreet3DSImporter::ParseMaterialChunk() // This is the ambient material color aiColor3D* pc = &mScene->mMaterials.back().mAmbient; ParseColorChunk(pc); - if (is_qnan(pc->r)) - { + if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it DefaultLogger::get()->error("3DS: Unable to read AMBIENT chunk"); pc->r = pc->g = pc->b = 0.0f; @@ -1165,8 +1161,7 @@ void Discreet3DSImporter::ParseMaterialChunk() // This is the emissive material color aiColor3D* pc = &mScene->mMaterials.back().mEmissive; ParseColorChunk(pc); - if (is_qnan(pc->r)) - { + if (is_qnan(pc->r)) { // color chunk is invalid. Simply ignore it DefaultLogger::get()->error("3DS: Unable to read EMISSIVE chunk"); pc->r = pc->g = pc->b = 0.0f; @@ -1248,9 +1243,8 @@ void Discreet3DSImporter::ParseMaterialChunk() ParseTextureChunk(&mScene->mMaterials.back().sTexEmissive); break; case Discreet3DS::CHUNK_MAT_REFLMAP: - // Reflection map - no support in Assimp - DefaultLogger::get()->warn("3DS: Found reflection map in file. This is not supported"); - + // Reflection map + ParseTextureChunk(&mScene->mMaterials.back().sTexReflective); break; }; ASSIMP_3DS_END_CHUNK(); diff --git a/code/ColladaHelper.h b/code/ColladaHelper.h index 95f5814b5..2d8a822f9 100644 --- a/code/ColladaHelper.h +++ b/code/ColladaHelper.h @@ -46,6 +46,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { namespace Collada { +/** Collada file versions which evolved during the years ... */ +enum FormatVersion +{ + FV_1_5_n, + FV_1_4_n, + FV_1_3_n +}; + + /** Transformation types that can be applied to a node */ enum TransformType { @@ -382,56 +391,80 @@ struct Sampler , mMixWithPrevious (1.f) {} - // Name of image reference + /** Name of image reference + */ std::string mName; - // Wrap U? + /** Wrap U? + */ bool mWrapU; - // Wrap V? + /** Wrap V? + */ bool mWrapV; - // Mirror U? + /** Mirror U? + */ bool mMirrorU; - // Mirror V? + /** Mirror V? + */ bool mMirrorV; - // Blend mode + /** Blend mode + */ aiTextureOp mOp; - // UV transformation + /** UV transformation + */ aiUVTransform mTransform; - // Name of source UV channel + /** Name of source UV channel + */ std::string mUVChannel; - // Resolved UV channel index or 0xffffffff if not known + /** Resolved UV channel index or 0xffffffff if not known + */ unsigned int mUVId; // OKINO/MAX3D extensions from here // ------------------------------------------------------- - // Weighting factor + /** Weighting factor + */ float mWeighting; - // Mixing factor from OKINO + /** Mixing factor from OKINO + */ float mMixWithPrevious; }; -/** A collada effect. Can contain about anything according to the Collada spec, but we limit our version to a reasonable subset. */ +/** Describes different alpha blending modes. */ +enum AlphaMode +{ + AM_RGB_ZERO, + AM_RGB_ONE, + AM_ALPHA_ONE, + AM_ALPHA_ZERO +}; + +/** A collada effect. Can contain about anything according to the Collada spec, + but we limit our version to a reasonable subset. */ struct Effect { // Shading mode ShadeType mShadeType; + // Alpha mode + AlphaMode mAlphaMode; + // Colors - aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular; - aiColor4D mTransparent; + aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular, + mTransparent, mReflective; // Textures Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular, - mTexTransparent, mTexBump; + mTexTransparent, mTexBump, mTexReflective; // Scalar factory float mShininess, mRefractIndex; @@ -448,6 +481,7 @@ struct Effect Effect() : mShadeType (Shade_Phong) + , mAlphaMode (AM_ALPHA_ZERO) , mEmissive ( 0, 0, 0, 1) , mAmbient ( 0.1f, 0.1f, 0.1f, 1) , mDiffuse ( 0.6f, 0.6f, 0.6f, 1) @@ -467,6 +501,16 @@ struct Effect struct Image { std::string mFileName; + + /** If image file name is zero, embedded image data + */ + std::vector mImageData; + + /** If image file name is zero, file format of + * embedded image data. + */ + std::string mEmbeddedFormat; + }; } // end of namespace Collada diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index 07833f3a4..69058a5e6 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -107,6 +107,7 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I newMats.clear(); mLights.clear(); mCameras.clear(); + mTextures.clear(); // parse the input file ColladaParser parser( pFile); @@ -114,6 +115,13 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I if( !parser.mRootNode) throw new ImportErrorException( "Collada: File came out empty. Something is wrong here."); + // reserve some storage to avoid unnecessary reallocs + newMats.reserve(parser.mMaterialLibrary.size()*2); + mMeshes.reserve(parser.mMeshLibrary.size()*2); + + mCameras.reserve(parser.mCameraLibrary.size()); + mLights.reserve(parser.mLightLibrary.size()); + // create the materials first, for the meshes to find BuildMaterials( parser, pScene); @@ -394,6 +402,7 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll { // accumulated mesh references by this node std::vector newMeshRefs; + newMeshRefs.reserve(pNode->mMeshes.size()); // add a mesh for each subgroup in each collada mesh BOOST_FOREACH( const Collada::MeshInstance& mid, pNode->mMeshes) @@ -566,6 +575,7 @@ void ColladaLoader::StoreSceneMeshes( aiScene* pScene) pScene->mMeshes = new aiMesh*[mMeshes.size()]; std::copy( mMeshes.begin(), mMeshes.end(), pScene->mMeshes); } + mMeshes.clear(); } // ------------------------------------------------------------------------------------------------ @@ -578,6 +588,7 @@ void ColladaLoader::StoreSceneCameras( aiScene* pScene) pScene->mCameras = new aiCamera*[mCameras.size()]; std::copy( mCameras.begin(), mCameras.end(), pScene->mCameras); } + mCameras.clear(); } // ------------------------------------------------------------------------------------------------ @@ -590,6 +601,20 @@ void ColladaLoader::StoreSceneLights( aiScene* pScene) pScene->mLights = new aiLight*[mLights.size()]; std::copy( mLights.begin(), mLights.end(), pScene->mLights); } + mLights.clear(); +} + +// ------------------------------------------------------------------------------------------------ +// Stores all textures in the given scene +void ColladaLoader::StoreSceneTextures( aiScene* pScene) +{ + pScene->mNumTextures = mTextures.size(); + if( mTextures.size() > 0) + { + pScene->mTextures = new aiTexture*[mTextures.size()]; + std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures); + } + mTextures.clear(); } // ------------------------------------------------------------------------------------------------ @@ -601,6 +626,8 @@ void ColladaLoader::StoreSceneMaterials( aiScene* pScene) pScene->mMaterials = new aiMaterial*[newMats.size()]; for (unsigned int i = 0; i < newMats.size();++i) pScene->mMaterials[i] = newMats[i].second; + + newMats.clear(); } // ------------------------------------------------------------------------------------------------ @@ -714,16 +741,21 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* pScene mat.AddProperty( &shadeMode, 1, AI_MATKEY_ENABLE_WIREFRAME); // add material colors - mat.AddProperty( &effect.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT); + mat.AddProperty( &effect.mAmbient, 1,AI_MATKEY_COLOR_AMBIENT); mat.AddProperty( &effect.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); - mat.AddProperty( &effect.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); - mat.AddProperty( &effect.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); + mat.AddProperty( &effect.mSpecular, 1,AI_MATKEY_COLOR_SPECULAR); + mat.AddProperty( &effect.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); + mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT); + mat.AddProperty( &effect.mReflective, 1, AI_MATKEY_COLOR_REFLECTIVE); + + // scalar properties mat.AddProperty( &effect.mShininess, 1, AI_MATKEY_SHININESS); mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI); // add textures, if given if( !effect.mTexAmbient.mName.empty()) - AddTexture( mat, pParser, effect, effect.mTexAmbient,aiTextureType_AMBIENT); + /* It is merely a lightmap */ + AddTexture( mat, pParser, effect, effect.mTexAmbient,aiTextureType_LIGHTMAP); if( !effect.mTexEmissive.mName.empty()) AddTexture( mat, pParser, effect, effect.mTexEmissive,aiTextureType_EMISSIVE); @@ -739,6 +771,9 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* pScene if( !effect.mTexTransparent.mName.empty()) AddTexture( mat, pParser, effect, effect.mTexBump,aiTextureType_OPACITY); + + if( !effect.mTexReflective.mName.empty()) + AddTexture( mat, pParser, effect, effect.mTexReflective,aiTextureType_REFLECTION); } } @@ -797,7 +832,8 @@ void ColladaLoader::BuildMaterials( const ColladaParser& pParser, aiScene* pScen // ------------------------------------------------------------------------------------------------ // Resolves the texture name for the given effect texture entry -const aiString& ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser, const Collada::Effect& pEffect, const std::string& pName) +const aiString& ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser, + const Collada::Effect& pEffect, const std::string& pName) { // recurse through the param references until we end up at an image std::string name = pName; @@ -815,12 +851,42 @@ const aiString& ColladaLoader::FindFilenameForEffectTexture( const ColladaParser // find the image referred by this name in the image library of the scene ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name); - if( imIt == pParser.mImageLibrary.end()) - throw new ImportErrorException( boost::str( boost::format( "Collada: Unable to resolve effect texture entry \"%s\", ended up at ID \"%s\".") % pName % name)); - + if( imIt == pParser.mImageLibrary.end()) { + throw new ImportErrorException( boost::str( boost::format( + "Collada: Unable to resolve effect texture entry \"%s\", ended up at ID \"%s\".") % pName % name)); + } static aiString result; - result.Set( imIt->second.mFileName ); - ConvertPath(result); + + // if this is an embedded texture image setup an aiTexture for it + if (imIt->second.mFileName.empty()) { + if (imIt->second.mImageData.empty()) { + throw new ImportErrorException("Collada: Invalid texture, no data or file reference given"); + } + aiTexture* tex = new aiTexture(); + + // setup format hint + if (imIt->second.mEmbeddedFormat.length() > 3) { + DefaultLogger::get()->warn("Collada: texture format hint is too long, truncating to 3 characters"); + } + ::strncpy(tex->achFormatHint,imIt->second.mEmbeddedFormat.c_str(),3); + + // and copy texture data + tex->mHeight = 0; + tex->mWidth = imIt->second.mImageData.size(); + tex->pcData = (aiTexel*)new char[tex->mWidth]; + ::memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth); + + // setup texture reference string + result.data[0] = '*'; + result.length = 1 + ASSIMP_itoa10(result.data+1,MAXLEN-1,mTextures.size()); + + // and add this texture to the list + mTextures.push_back(tex); + } + else { + result.Set( imIt->second.mFileName ); + ConvertPath(result); + } return result; } diff --git a/code/ColladaLoader.h b/code/ColladaLoader.h index f4f30bb83..845667621 100644 --- a/code/ColladaLoader.h +++ b/code/ColladaLoader.h @@ -137,6 +137,9 @@ protected: /** Stores all cameras in the given scene */ void StoreSceneCameras( aiScene* pScene); + /** Stores all textures in the given scene */ + void StoreSceneTextures( aiScene* pScene); + /** Constructs materials from the collada material definitions */ void BuildMaterials( const ColladaParser& pParser, aiScene* pScene); @@ -181,6 +184,9 @@ protected: /** Temporary light list */ std::vector mLights; + + /** Temporary texture list */ + std::vector mTextures; }; } // end of namespace Assimp diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index 5c084abef..5182abf88 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -62,6 +62,9 @@ ColladaParser::ColladaParser( const std::string& pFile) mUnitSize = 1.0f; mUpDirection = UP_Z; + // We assume the newest file format by default + mFormat = FV_1_5_n; + // generate a XML reader for it mReader = irr::io::createIrrXMLReader( pFile.c_str()); if( !mReader) @@ -109,6 +112,25 @@ void ColladaParser::ReadContents() { if( IsElement( "COLLADA")) { + // check for 'version' attribute + const int attrib = TestAttribute("version"); + if (attrib != -1) { + const char* version = mReader->getAttributeValue(attrib); + + if (!::strncmp(version,"1.5",3)) { + mFormat = FV_1_5_n; + DefaultLogger::get()->debug("Collada schema version is 1.5.n"); + } + else if (!::strncmp(version,"1.4",3)) { + mFormat = FV_1_4_n; + DefaultLogger::get()->debug("Collada schema version is 1.4.n"); + } + else if (!::strncmp(version,"1.3",3)) { + mFormat = FV_1_3_n; + DefaultLogger::get()->debug("Collada schema version is 1.3.n"); + } + } + ReadStructure(); } else { @@ -245,23 +267,74 @@ void ColladaParser::ReadImage( Collada::Image& pImage) while( mReader->read()) { if( mReader->getNodeType() == irr::io::EXN_ELEMENT){ - if( IsElement( "init_from")) - { - // element content is filename - hopefully - const char* content = GetTextContent(); - pImage.mFileName = content; - TestClosing( "init_from"); - } else + // Need to run different code paths here, depending on the Collada XSD version + if( IsElement( "init_from")) { + if (mFormat == FV_1_4_n) { + // element content is filename - hopefully + const char* sz = TestTextContent(); + if (sz)pImage.mFileName = sz; + TestClosing( "init_from"); + } + else if (mFormat == FV_1_5_n) { + + // make sure we skip over mip and array initializations, which + // we don't support, but which could confuse the loader if + // they're not skipped. + int attrib = TestAttribute("array_index"); + if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) { + DefaultLogger::get()->warn("Collada: Ignoring texture array index"); + continue; + } + + attrib = TestAttribute("mip_index"); + if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) { + DefaultLogger::get()->warn("Collada: Ignoring MIP map layer"); + continue; + } + + // TODO: correctly jump over cube and volume maps? + } + } + else if (mFormat == FV_1_5_n) { + if( IsElement( "ref")) + { + // element content is filename - hopefully + const char* sz = TestTextContent(); + if (sz)pImage.mFileName = sz; + TestClosing( "ref"); + } + else if( IsElement( "hex") && !pImage.mFileName.length()) + { + // embedded image. get format + const int attrib = TestAttribute("format"); + if (-1 == attrib) + DefaultLogger::get()->warn("Collada: Unknown image file format"); + else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib); + + const char* data = GetTextContent(); + + // hexadecimal-encoded binary octets. First of all, find the + // required buffer size to reserve enough storage. + const char* cur = data; + while (!IsSpaceOrNewLine(*cur)) cur++; + + const unsigned int size = (unsigned int)(cur-data) * 2; + pImage.mImageData.resize(size); + for (unsigned int i = 0; i < size;++i) { + pImage.mImageData[i] = HexOctetToDecimal(data+(i<<1)); + } + TestClosing( "hex"); + } + } + else { // ignore the rest SkipElement(); } } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { - if( strcmp( mReader->getNodeName(), "image") != 0) - ThrowException( "Expected end of \"image\" element."); - - break; + if( strcmp( mReader->getNodeName(), "image") == 0) + break; } } } @@ -558,9 +631,9 @@ void ColladaParser::ReadEffect( Collada::Effect& pEffect) while( mReader->read()) { - if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { - if( IsElement( "newparam")) - { + if( mReader->getNodeType() == irr::io::EXN_ELEMENT) + { + if( IsElement( "newparam")) { // save ID int attrSID = GetAttribute( "sid"); std::string sid = mReader->getAttributeValue( attrSID); @@ -592,8 +665,7 @@ void ColladaParser::ReadEffect( Collada::Effect& pEffect) else if( IsElement( "specular")) ReadEffectColor( pEffect.mSpecular, pEffect.mTexSpecular); else if( IsElement( "reflective")) { - // Collada::Sampler dummy; - // ReadEffectColor( dummy,pEffect.mTexReflective); + ReadEffectColor( pEffect.mReflective, pEffect.mTexReflective); } else if( IsElement( "transparent")) ReadEffectColor( pEffect.mTransparent,pEffect.mTexTransparent); @@ -605,8 +677,6 @@ void ColladaParser::ReadEffect( Collada::Effect& pEffect) ReadEffectFloat( pEffect.mTransparency); else if( IsElement( "index_of_refraction")) ReadEffectFloat( pEffect.mRefractIndex); - // else if( IsElement( "reflectivity")) - // ReadEffectFloat( pEffect.mRefl); // GOOGLEEARTH/OKINO extensions // ------------------------------------------------------- @@ -1920,6 +1990,17 @@ int ColladaParser::TestAttribute( const char* pAttr) const // ------------------------------------------------------------------------------------------------ // Reads the text contents of an element, throws an exception if not given. Skips leading whitespace. const char* ColladaParser::GetTextContent() +{ + const char* sz = TestTextContent(); + if(!sz) { + ThrowException( "Invalid contents in element \"n\"."); + } + return sz; +} + +// ------------------------------------------------------------------------------------------------ +// Reads the text contents of an element, returns NULL if not given. Skips leading whitespace. +const char* ColladaParser::TestTextContent() { // present node should be the beginning of an element if( mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement()) @@ -1929,7 +2010,7 @@ const char* ColladaParser::GetTextContent() if( !mReader->read()) ThrowException( "Unexpected end of file while reading n element."); if( mReader->getNodeType() != irr::io::EXN_TEXT) - ThrowException( "Invalid contents in element \"n\"."); + return NULL; // skip leading whitespace const char* text = mReader->getNodeData(); diff --git a/code/ColladaParser.h b/code/ColladaParser.h index be9f92937..e601c182c 100644 --- a/code/ColladaParser.h +++ b/code/ColladaParser.h @@ -1,5 +1,3 @@ -/** Defines the parser helper class for the collada loader */ - /* Open Asset Import Library (ASSIMP) ---------------------------------------------------------------------- @@ -40,17 +38,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ +/** @file ColladaParser.h + * @brief Defines the parser helper class for the collada loader + */ + #ifndef AI_COLLADAPARSER_H_INC #define AI_COLLADAPARSER_H_INC #include "irrXMLWrapper.h" #include "ColladaHelper.h" -namespace Assimp -{ +namespace Assimp { -/** Parser helper class for the Collada loader. Does all the XML reading and builds internal data structures from it, - * but leaves the resolving of all the references to the loader. +// ------------------------------------------------------------------------------------------ +/** Parser helper class for the Collada loader. + * + * Does all the XML reading and builds internal data structures from it, + * but leaves the resolving of all the references to the loader. */ class ColladaParser { @@ -176,10 +180,7 @@ protected: void SkipElement( const char* pElement); /** Compares the current xml element name to the given string and returns true if equal */ - bool IsElement( const char* pName) const { - ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); - return ::strcmp( mReader->getNodeName(), pName) == 0; - } + bool IsElement( const char* pName) const; /** Tests for the opening tag of the given element, throws an exception if not found */ void TestOpening( const char* pName); @@ -199,13 +200,17 @@ protected: Skips leading whitespace. */ const char* GetTextContent(); + /** Reads the text contents of an element, returns NULL if not given. + Skips leading whitespace. */ + const char* ColladaParser::TestTextContent(); + /** Reads a single bool from current text content */ bool ReadBoolFromTextContent(); /** Reads a single float from current text content */ float ReadFloatFromTextContent(); - /** Calculates the resulting transformation fromm all the given transform steps */ + /** Calculates the resulting transformation from all the given transform steps */ aiMatrix4x4 CalculateResultTransform( const std::vector& pTransforms) const; /** Determines the input data type for the given semantic string */ @@ -222,7 +227,8 @@ protected: /** XML reader */ irr::io::IrrXMLReader* mReader; - /** All data arrays found in the file by ID. Might be referred to by actually everyone. Collada, you are a steaming pile of indirection. */ + /** All data arrays found in the file by ID. Might be referred to by actually + everyone. Collada, you are a steaming pile of indirection. */ typedef std::map DataLibrary; DataLibrary mDataLibrary; @@ -258,7 +264,8 @@ protected: typedef std::map CameraLibrary; CameraLibrary mCameraLibrary; - /** Pointer to the root node. Don't delete, it just points to one of the nodes in the node library. */ + /** Pointer to the root node. Don't delete, it just points to one of + the nodes in the node library. */ Collada::Node* mRootNode; /** Size unit: how large compared to a meter */ @@ -266,8 +273,19 @@ protected: /** Which is the up vector */ enum { UP_X, UP_Y, UP_Z } mUpDirection; + + /** Collada file format version */ + Collada::FormatVersion mFormat; }; +// ------------------------------------------------------------------------------------------------ +// Check for element match +inline bool ColladaParser::IsElement( const char* pName) const +{ + ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); + return ::strcmp( mReader->getNodeName(), pName) == 0; +} + // ------------------------------------------------------------------------------------------------ // Finds the item in the given library by its reference, throws if not found template diff --git a/code/ComputeUVMappingProcess.cpp b/code/ComputeUVMappingProcess.cpp index 328a01293..95b266b00 100644 --- a/code/ComputeUVMappingProcess.cpp +++ b/code/ComputeUVMappingProcess.cpp @@ -47,6 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; +namespace { + + const static aiVector3D base_axis_y(0.f,1.f,0.f); + const static aiVector3D base_axis_x(1.f,0.f,0.f); + const static aiVector3D base_axis_z(0.f,0.f,1.f); + const static float angle_epsilon = 0.95f; +}; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer @@ -69,40 +76,6 @@ bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const return (pFlags & aiProcess_GenUVCoords) != 0; } -// ------------------------------------------------------------------------------------------------ -// Compute the AABB of a mesh -inline void FindAABB (aiMesh* mesh, aiVector3D& min, aiVector3D& max) -{ - min = aiVector3D (10e10f, 10e10f, 10e10f); - max = aiVector3D (-10e10f,-10e10f,-10e10f); - for (unsigned int i = 0;i < mesh->mNumVertices;++i) - { - const aiVector3D& v = mesh->mVertices[i]; - min.x = ::std::min(v.x,min.x); - min.y = ::std::min(v.y,min.y); - min.z = ::std::min(v.z,min.z); - max.x = ::std::max(v.x,max.x); - max.y = ::std::max(v.y,max.y); - max.z = ::std::max(v.z,max.z); - } -} - -// ------------------------------------------------------------------------------------------------ -// Helper function to determine the 'real' center of a mesh -inline void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max) -{ - FindAABB(mesh,min,max); - out = min + (max-min)*0.5f; -} - -// ------------------------------------------------------------------------------------------------ -// Helper function to determine the 'real' center of a mesh -inline void FindMeshCenter (aiMesh* mesh, aiVector3D& out) -{ - aiVector3D min,max; - FindMeshCenter(mesh,out,min,max); -} - // ------------------------------------------------------------------------------------------------ // Check whether a ray intersects a plane and find the intersection point inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos, @@ -208,48 +181,75 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out) } // ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,aiAxis axis, aiVector3D* out) +void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) { - aiVector3D center; - FindMeshCenter (mesh, center); - - // For each point get a normalized projection vector in the sphere, - // get its longitude and latitude and map them to their respective - // UV axes. Problems occur around the poles ... unsolvable. - // - // The spherical coordinate system looks like this: - // x = cos(lon)*cos(lat) - // y = sin(lon)*cos(lat) - // z = sin(lat) - // - // Thus we can derive: - // lat = arcsin (z) - // lon = arctan (y/x) + aiVector3D center, min, max; - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) - { - const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); - float lat, lon; + // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... + // currently the mapping axis will always be one of x,y,z, except if the + // PretransformVertices step is used (it transforms the meshes into worldspace, + // thus changing the mapping axis) + if (axis * base_axis_x >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); - switch (axis) + // For each point get a normalized projection vector in the sphere, + // get its longitude and latitude and map them to their respective + // UV axes. Problems occur around the poles ... unsolvable. + // + // The spherical coordinate system looks like this: + // x = cos(lon)*cos(lat) + // y = sin(lon)*cos(lat) + // z = sin(lat) + // + // Thus we can derive: + // lat = arcsin (z) + // lon = arctan (y/x) + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { - case aiAxis_X: - lat = asin (diff.x); - lon = atan2 (diff.z, diff.y); - break; - case aiAxis_Y: - lat = asin (diff.y); - lon = atan2 (diff.x, diff.z); - break; - case aiAxis_Z: - lat = asin (diff.z); - lon = atan2 (diff.y, diff.x); - break; + const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); + out[pnt] = aiVector3D((atan2 (diff.z, diff.y) + (float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI, + (asin (diff.x) + (float)AI_MATH_HALF_PI) / (float)AI_MATH_PI, 0.f); } - out[pnt] = aiVector3D((lon + (float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI, - (lat + (float)AI_MATH_HALF_PI) / (float)AI_MATH_PI, 0.f); } + else if (axis * base_axis_y >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); + // ... just the same again + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) + { + const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); + out[pnt] = aiVector3D((atan2 (diff.x, diff.z) + (float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI, + (asin (diff.y) + (float)AI_MATH_HALF_PI) / (float)AI_MATH_PI, 0.f); + } + } + else if (axis * base_axis_z >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); + + // ... just the same again + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) + { + const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); + out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + (float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI, + (asin (diff.z) + (float)AI_MATH_HALF_PI) / (float)AI_MATH_PI, 0.f); + } + } + // slower code path in case the mapping axis is not one of the coordinate system axes + else + { + aiMatrix4x4 mTrafo; + aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); + FindMeshCenterTransformed(mesh, center, min, max,mTrafo); + + // again the same, except we're applying a transformation now + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) + { + const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize(); + out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + (float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI, + (asin (diff.z) + (float)AI_MATH_HALF_PI) / (float)AI_MATH_PI, 0.f); + } + } + + // Now find and remove UV seams. A seam occurs if a face has a tcoord // close to zero on the one side, and a tcoord close to one on the // other side. @@ -257,47 +257,71 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,aiAxis axis, aiV } // ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,aiAxis axis, aiVector3D* out) +void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) { aiVector3D center, min, max; - FindMeshCenter(mesh, center, min, max); - ai_assert(0 == aiAxis_X); - const float diff = max[axis] - min[axis]; - if (!diff) - { - DefaultLogger::get()->error("Can't compute cylindrical mapping, the mesh is " - "flat in the requested axis"); + // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... + // currently the mapping axis will always be one of x,y,z, except if the + // PretransformVertices step is used (it transforms the meshes into worldspace, + // thus changing the mapping axis) + if (axis * base_axis_x >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); + const float diff = max.x - min.x; - return; - } + // If the main axis is 'z', the z coordinate of a point 'p' is mapped + // directly to the texture V axis. The other axis is derived from + // the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where + // 'c' is the center point of the mesh. + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { + const aiVector3D& pos = mesh->mVertices[pnt]; + aiVector3D& uv = out[pnt]; - // If the main axis is 'z', the z coordinate of a point 'p' is mapped - // directly to the texture V axis. The other axis is derived from - // the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where - // 'c' is the center point of the mesh. - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) - { - const aiVector3D& pos = mesh->mVertices[pnt]; - aiVector3D& uv = out[pnt]; - - switch (axis) - { - case aiAxis_X: uv.y = (pos.x - min.x) / diff; - uv.x = atan2 ( pos.z - center.z, pos.y - center.y); - break; - case aiAxis_Y: - uv.y = (pos.y - min.y) / diff; - uv.x = atan2 ( pos.x - center.x, pos.z - center.z); - break; - case aiAxis_Z: - uv.y = (pos.z - min.z) / diff; - uv.x = atan2 ( pos.y - center.y, pos.x - center.x); - break; + uv.x = (atan2 ( pos.z - center.z, pos.y - center.y) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; + } + } + else if (axis * base_axis_y >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); + const float diff = max.y - min.y; + + // just the same ... + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { + const aiVector3D& pos = mesh->mVertices[pnt]; + aiVector3D& uv = out[pnt]; + + uv.y = (pos.y - min.y) / diff; + uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; + } + } + else if (axis * base_axis_z >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); + const float diff = max.z - min.z; + + // just the same ... + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { + const aiVector3D& pos = mesh->mVertices[pnt]; + aiVector3D& uv = out[pnt]; + + uv.y = (pos.z - min.z) / diff; + uv.x = (atan2 ( pos.y - center.y, pos.x - center.x) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; + } + } + // slower code path in case the mapping axis is not one of the coordinate system axes + else { + aiMatrix4x4 mTrafo; + aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); + FindMeshCenterTransformed(mesh, center, min, max,mTrafo); + const float diff = max.y - min.y; + + // again the same, except we're applying a transformation now + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){ + const aiVector3D pos = mTrafo* mesh->mVertices[pnt]; + aiVector3D& uv = out[pnt]; + + uv.y = (pos.y - min.y) / diff; + uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; } - uv.x = (uv.x +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; - uv.z = 0.f; } // Now find and remove UV seams. A seam occurs if a face has a tcoord @@ -307,61 +331,62 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,aiAxis axis, a } // ------------------------------------------------------------------------------------------------ -void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,aiAxis axis, aiVector3D* out) +void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) { - aiVector3D center, min, max; - FindMeshCenter(mesh, center, min, max); - float diffu,diffv; + aiVector3D center, min, max; - switch (axis) - { - case aiAxis_X: - diffu = max.z - min.z; - diffv = max.y - min.y; - break; - case aiAxis_Y: - diffu = max.x - min.x; - diffv = max.z - min.z; - break; - case aiAxis_Z: - diffu = max.y - min.y; - diffv = max.z - min.z; - break; - } - - if (!diffu || !diffv) - { - DefaultLogger::get()->error("Can't compute plane mapping, the mesh is " - "flat in the requested axis"); - return; - } + // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... + // currently the mapping axis will always be one of x,y,z, except if the + // PretransformVertices step is used (it transforms the meshes into worldspace, + // thus changing the mapping axis) + if (axis * base_axis_x >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); + diffu = max.z - min.z; + diffv = max.y - min.y; - // That's rather simple. We just project the vertices onto a plane - // that lies on the two coordinate aces orthogonal to the main axis - for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) - { - const aiVector3D& pos = mesh->mVertices[pnt]; - aiVector3D& uv = out[pnt]; - - switch (axis) - { - case aiAxis_X: - uv.x = (pos.z - min.z) / diffu; - uv.y = (pos.y - min.y) / diffv; - break; - case aiAxis_Y: - uv.x = (pos.x - min.x) / diffu; - uv.y = (pos.z - min.z) / diffv; - break; - case aiAxis_Z: - uv.x = (pos.y - min.y) / diffu; - uv.y = (pos.x - min.x) / diffv; - break; + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { + const aiVector3D& pos = mesh->mVertices[pnt]; + out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv); + } + } + else if (axis * base_axis_y >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); + diffu = max.x - min.x; + diffv = max.z - min.z; + + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { + const aiVector3D& pos = mesh->mVertices[pnt]; + out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv); + } + } + else if (axis * base_axis_z >= angle_epsilon) { + FindMeshCenter(mesh, center, min, max); + diffu = max.y - min.y; + diffv = max.z - min.z; + + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { + const aiVector3D& pos = mesh->mVertices[pnt]; + out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv); + } + } + // slower code path in case the mapping axis is not one of the coordinate system axes + else + { + aiMatrix4x4 mTrafo; + aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); + FindMeshCenterTransformed(mesh, center, min, max,mTrafo); + diffu = max.x - min.x; + diffv = max.z - min.z; + + // again the same, except we're applying a transformation now + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { + const aiVector3D pos = mTrafo * mesh->mVertices[pnt]; + out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv); } - uv.z = 0.f; } + // shouldn't be necessary to remove UV seams ... } // ------------------------------------------------------------------------------------------------ @@ -416,9 +441,8 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene) if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex) continue; - if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) - { - info.axis = *((aiAxis*)prop2->mData); + if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) { + info.axis = *((aiVector3D*)prop2->mData); break; } } diff --git a/code/ComputeUVMappingProcess.h b/code/ComputeUVMappingProcess.h index 36a77fa7c..1d090316e 100644 --- a/code/ComputeUVMappingProcess.h +++ b/code/ComputeUVMappingProcess.h @@ -91,7 +91,7 @@ protected: * @param axis Main axis * @param out Receives output UV coordinates */ - void ComputeSphereMapping(aiMesh* mesh,aiAxis axis, + void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out); // ------------------------------------------------------------------- @@ -101,7 +101,7 @@ protected: * @param axis Main axis * @param out Receives output UV coordinates */ - void ComputeCylinderMapping(aiMesh* mesh,aiAxis axis, + void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out); // ------------------------------------------------------------------- @@ -111,7 +111,7 @@ protected: * @param axis Main axis * @param out Receives output UV coordinates */ - void ComputePlaneMapping(aiMesh* mesh,aiAxis axis, + void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out); // ------------------------------------------------------------------- @@ -129,12 +129,12 @@ private: { MappingInfo(aiTextureMapping _type) : type (_type) - , axis (aiAxis_Y) + , axis (0.f,1.f,0.f) , uv (0u) {} aiTextureMapping type; - aiAxis axis; + aiVector3D axis; unsigned int uv; bool operator== (const MappingInfo& other) diff --git a/code/IRRLoader.cpp b/code/IRRLoader.cpp index 39760f755..74700b623 100644 --- a/code/IRRLoader.cpp +++ b/code/IRRLoader.cpp @@ -593,7 +593,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vectormKey.Set("$tex.mapaxis"); m->mIndex = prop->mIndex; m->mSemantic = prop->mSemantic; - m->mType = aiPTI_Integer; + m->mType = aiPTI_Float; - m->mDataLength = 4; - m->mData = new char[4]; - *((int*)m->mData) = axis; + m->mDataLength = 12; + m->mData = new char[12]; + *((aiVector3D*)m->mData) = axis; p.push_back(m); } } - else if (! ::strcmp( prop->mKey.data, "$tex.uvwsrc")) - { + else if (! ::strcmp( prop->mKey.data, "$tex.uvwsrc")) { delete mat->mProperties[i]; } else p.push_back(prop); @@ -647,8 +646,7 @@ void SetupMapping (MaterialHelper* mat, aiTextureMapping mode, aiAxis axis = aiA if (p.empty())return; // rebuild the output array - if (p.size() > mat->mNumAllocated) - { + if (p.size() > mat->mNumAllocated) { delete[] mat->mProperties; mat->mProperties = new aiMaterialProperty*[p.size()]; } @@ -793,12 +791,10 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene, if (mesh->HasTextureCoords(1)) { int idx = 1; - if (src.second & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) - { + if (src.second & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) { mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(0)); } - else if (src.second & AI_IRRMESH_MAT_normalmap_solid) - { + else if (src.second & AI_IRRMESH_MAT_normalmap_solid) { mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0)); } } @@ -836,7 +832,7 @@ void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene, // Now adjust this output material - if there is a first texture // set, setup spherical UV mapping around the Y axis. - SetupMapping ( (MaterialHelper*) materials.back(), aiTextureMapping_SPHERE, aiAxis_Y ); + SetupMapping ( (MaterialHelper*) materials.back(), aiTextureMapping_SPHERE); } break; diff --git a/code/IRRMeshLoader.cpp b/code/IRRMeshLoader.cpp index 6b1ee6e5a..1b5f13bc4 100644 --- a/code/IRRMeshLoader.cpp +++ b/code/IRRMeshLoader.cpp @@ -217,12 +217,10 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile, int idx = 1; MaterialHelper* mat = ( MaterialHelper* ) curMat; - if (curMatFlags & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) - { - mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(0)); + if (curMatFlags & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)){ + mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_LIGHTMAP(0)); } - else if (curMatFlags & AI_IRRMESH_MAT_normalmap_solid) - { + else if (curMatFlags & AI_IRRMESH_MAT_normalmap_solid){ mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0)); } } diff --git a/code/IRRShared.cpp b/code/IRRShared.cpp index 0f9c68695..a957834be 100644 --- a/code/IRRShared.cpp +++ b/code/IRRShared.cpp @@ -342,7 +342,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) } // Up to 4 texture channels are supported - else if (prop.name == "Texture1") + if (prop.name == "Texture1") { // Always accept the primary texture channel ++cnt; @@ -356,7 +356,7 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { ++cnt; s.Set(prop.value); - mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(1)); + mat->AddProperty(&s,AI_MATKEY_TEXTURE_LIGHTMAP(0)); // set the corresponding material flag matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE; @@ -366,31 +366,26 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { ++cnt; s.Set(prop.value); - mat->AddProperty(&s,AI_MATKEY_TEXTURE_NORMALS(1)); + mat->AddProperty(&s,AI_MATKEY_TEXTURE_NORMALS(0)); // set the corresponding material flag matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE; } + else DefaultLogger::get()->warn("IRRmat: Skipping second texture"); } else if (prop.name == "Texture3") { - // We don't process the third texture channel as Irrlicht - // does not seem to use it. -#if 0 + // Irrlicht does not seem to use these channels. ++cnt; s.Set(prop.value); - mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(2)); -#endif + mat->AddProperty(&s,AI_MATKEY_TEXTURE_UNKNOWN(0)); } else if (prop.name == "Texture4" ) { - // We don't process the fourth texture channel as Irrlicht - // does not seem to use it. -#if 0 + // Irrlicht does not seem to use these channels. ++cnt; s.Set(prop.value); - mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(3)); -#endif + mat->AddProperty(&s,AI_MATKEY_TEXTURE_UNKNOWN(1)); } // Texture mapping options @@ -403,20 +398,26 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) else if (prop.name == "TextureWrap2" && cnt >= 2) { int map = ConvertMappingMode(prop.value); - mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(1)); - mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(1)); + if (matFlags & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) { + mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(1)); + mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(1)); + } + else if (matFlags & (AI_IRRMESH_MAT_normalmap_solid)) { + mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_NORMALS(1)); + mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_NORMALS(1)); + } } else if (prop.name == "TextureWrap3" && cnt >= 3) { int map = ConvertMappingMode(prop.value); - mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(2)); - mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(2)); + mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_UNKNOWN(0)); + mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_UNKNOWN(0)); } else if (prop.name == "TextureWrap4" && cnt >= 4) { int map = ConvertMappingMode(prop.value); - mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(3)); - mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(3)); + mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_UNKNOWN(1)); + mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_UNKNOWN(1)); } } } @@ -451,8 +452,8 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags) { f = 4.f; } - mat->AddProperty( &f, 1, AI_MATKEY_TEXBLEND_DIFFUSE(cnt-1)); - mat->AddProperty( &op,1, AI_MATKEY_TEXOP_DIFFUSE(cnt-1)); + mat->AddProperty( &f, 1, AI_MATKEY_TEXBLEND_LIGHTMAP(0)); + mat->AddProperty( &op,1, AI_MATKEY_TEXOP_LIGHTMAP(0)); } return mat; diff --git a/code/LWOFileData.h b/code/LWOFileData.h index 408fc74ac..f018bfc23 100644 --- a/code/LWOFileData.h +++ b/code/LWOFileData.h @@ -560,7 +560,8 @@ struct Surface mSpecularTextures, mOpacityTextures, mBumpTextures, - mGlossinessTextures; + mGlossinessTextures, + mReflectionTextures; //! Index of refraction float mIOR; diff --git a/code/LWOMaterial.cpp b/code/LWOMaterial.cpp index c5147e769..1f0af20d2 100644 --- a/code/LWOMaterial.cpp +++ b/code/LWOMaterial.cpp @@ -138,9 +138,22 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, a if (mapping != aiTextureMapping_UV) { - // Setup the main axis (the enum values map one to one) - ai_assert(aiAxis_X == Texture::AXIS_X); - pcMat->AddProperty((int*)&(*it).majorAxis,1,AI_MATKEY_TEXMAP_AXIS(type,cur)); + // Setup the main axis + aiVector3D v; + switch ((*it).majorAxis) + { + case Texture::AXIS_X: + v = aiVector3D(1.f,0.f,0.f); + break; + case Texture::AXIS_Y: + v = aiVector3D(0.f,1.f,0.f); + break; + default: // case Texture::AXIS_Z: + v = aiVector3D(0.f,0.f,1.f); + break; + } + + pcMat->AddProperty(&v,1,AI_MATKEY_TEXMAP_AXIS(type,cur)); // Setup UV scalings for cylindric and spherical projections if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE) @@ -164,17 +177,14 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, a for (ClipList::iterator end = mClips.end(); clip != end; ++clip) { if ((*clip).idx == temp) - { break; - } + } - if (mClips.end() == clip) - { + if (mClips.end() == clip) { DefaultLogger::get()->error("LWO2: Clip index is out of bounds"); temp = 0; } - if (Clip::UNSUPPORTED == (*clip).type) - { + if (Clip::UNSUPPORTED == (*clip).type) { DefaultLogger::get()->error("LWO2: Clip type is not supported"); continue; } @@ -184,8 +194,7 @@ bool LWOImporter::HandleTextures(MaterialHelper* pcMat, const TextureList& in, a else { std::string ss = (*it).mFileName; - if (!ss.length()) - { + if (!ss.length()) { DefaultLogger::get()->error("LWOB: Empty file name"); continue; } @@ -304,6 +313,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat HandleTextures(pcMat,surf.mGlossinessTextures,aiTextureType_SHININESS); HandleTextures(pcMat,surf.mBumpTextures,aiTextureType_HEIGHT); HandleTextures(pcMat,surf.mOpacityTextures,aiTextureType_OPACITY); + HandleTextures(pcMat,surf.mReflectionTextures,aiTextureType_REFLECTION); // now we need to know which shader we must use // iterate through the shader list of the surface and @@ -315,7 +325,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat if ((*it).functionName == "LW_SuperCelShader" || (*it).functionName == "AH_CelShader") { - DefaultLogger::get()->info("Mapping LW_SuperCelShader/AH_CelShader " + DefaultLogger::get()->info("LWO2: Mapping LW_SuperCelShader/AH_CelShader " "to aiShadingMode_Toon"); m = aiShadingMode_Toon; @@ -324,7 +334,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat else if ((*it).functionName == "LW_RealFresnel" || (*it).functionName == "LW_FastFresnel") { - DefaultLogger::get()->info("Mapping LW_RealFresnel/LW_FastFresnel " + DefaultLogger::get()->info("LWO2: Mapping LW_RealFresnel/LW_FastFresnel " "to aiShadingMode_Fresnel"); m = aiShadingMode_Fresnel; @@ -367,8 +377,7 @@ void LWOImporter::FindUVChannels(LWO::TextureList& list, LWO::Layer& layer, // check whether we have this channel already for (unsigned int m = 0; m < next;++m) { - if (i == out[m]) - { + if (i == out[m]) { (*it).mRealUVIndex = m; } } @@ -383,7 +392,7 @@ void LWOImporter::FindUVChannels(LWO::TextureList& list, LWO::Layer& layer, } } if (0xffffffff == (*it).mRealUVIndex) - DefaultLogger::get()->error("LWO2: Unable to find matching UV channel for a texture"); + DefaultLogger::get()->error("LWO2: Unable to find matching UV channel for texture"); } } @@ -400,6 +409,7 @@ void LWOImporter::FindUVChannels(LWO::Surface& surf, LWO::Layer& layer, FindUVChannels(surf.mGlossinessTextures,layer,out,next); FindUVChannels(surf.mOpacityTextures,layer,out,next); FindUVChannels(surf.mBumpTextures,layer,out,next); + FindUVChannels(surf.mReflectionTextures,layer,out,next); } // ------------------------------------------------------------------------------------------------ @@ -560,6 +570,8 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsi listRef = &surf.mBumpTextures;break; case AI_LWO_TRAN: listRef = &surf.mOpacityTextures;break; + case AI_LWO_REFL: + listRef = &surf.mReflectionTextures;break; default: DefaultLogger::get()->warn("LWO2: Encountered unknown texture type"); return; @@ -623,8 +635,7 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* head, unsig for (ShaderList::iterator it = surf.mShaders.begin(); it != surf.mShaders.end(); ++it) { - if (::strcmp(shader.ordinal.c_str(),(*it).ordinal.c_str()) < 0) - { + if (::strcmp(shader.ordinal.c_str(),(*it).ordinal.c_str()) < 0) { surf.mShaders.insert(it,shader); return; } diff --git a/code/MaterialSystem.cpp b/code/MaterialSystem.cpp index 83a6e0801..f1a16ee06 100644 --- a/code/MaterialSystem.cpp +++ b/code/MaterialSystem.cpp @@ -487,46 +487,44 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat, unsigned int* uvindex /*= NULL*/, float* blend /*= NULL*/, aiTextureOp* op /*= NULL*/, - aiTextureMapMode* mapmode /*= NULL*/) + aiTextureMapMode* mapmode /*= NULL*/, + unsigned int* flags /*= NULL*/ + ) { ai_assert(NULL != mat && NULL != path); // Get the path to the texture - if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) - { + if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) { return AI_FAILURE; } - - // Determine the mapping type of the texture + // Determine mapping type aiTextureMapping mapping = aiTextureMapping_UV; aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index),(int*)&mapping); - if (_mapping)*_mapping = mapping; + if (_mapping) + *_mapping = mapping; - // Get the UV index of the texture - if (aiTextureMapping_UV == mapping && uvindex) - { + // Get UV index + if (aiTextureMapping_UV == mapping && uvindex) { aiGetMaterialInteger(mat,AI_MATKEY_UVWSRC(type,index),(int*)uvindex); } - - // Get the blend factor of the texture - if (blend) - { + // Get blend factor + if (blend) { aiGetMaterialFloat(mat,AI_MATKEY_TEXBLEND(type,index),blend); } - - // Get the texture operation of the texture - if (op) - { + // Get texture operation + if (op){ aiGetMaterialInteger(mat,AI_MATKEY_TEXOP(type,index),(int*)op); } - - // get the texture mapping modes for the texture - if (mapmode) - { + // Get texture mapping modes + if (mapmode) { aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U(type,index),(int*)&mapmode[0]); aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V(type,index),(int*)&mapmode[1]); - aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_W(type,index),(int*)&mapmode[2]); } + // Get texture flags + if (flags){ + aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags); + } + return AI_SUCCESS; } diff --git a/code/MaterialSystem.h b/code/MaterialSystem.h index f2370cc0e..7aa06763e 100644 --- a/code/MaterialSystem.h +++ b/code/MaterialSystem.h @@ -216,6 +216,19 @@ inline aiReturn MaterialHelper::AddProperty (const aiColor3D* pInput, pKey,type,index,aiPTI_Float); } +// ---------------------------------------------------------------------------------------- +template<> +inline aiReturn MaterialHelper::AddProperty (const aiVector3D* pInput, + const unsigned int pNumValues, + const char* pKey, + unsigned int type, + unsigned int index) +{ + return AddBinaryProperty((const void*)pInput, + pNumValues * sizeof(aiVector3D), + pKey,type,index,aiPTI_Float); +} + // ---------------------------------------------------------------------------------------- template<> inline aiReturn MaterialHelper::AddProperty (const int* pInput, diff --git a/code/NFFLoader.cpp b/code/NFFLoader.cpp index c5b5a3c21..a806545ff 100644 --- a/code/NFFLoader.cpp +++ b/code/NFFLoader.cpp @@ -1089,9 +1089,8 @@ void NFFImporter::InternReadFile( const std::string& pFile, c->mPosition = camPos; c->mUp = camUp; - // If the resolution is not specified in the file we - // need to set 1.0 as aspect. The division would become - // INF otherwise. + // If the resolution is not specified in the file, we + // need to set 1.0 as aspect. c->mAspect = (!resolution.y ? 0.f : resolution.x / resolution.y); ++ppcChildren; } @@ -1231,8 +1230,12 @@ void NFFImporter::InternReadFile( const std::string& pFile, s.Set(src.shader.texFile); pcMat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0)); - if (aiTextureMapping_UV != src.shader.mapping) + if (aiTextureMapping_UV != src.shader.mapping) { + + aiVector3D v(0.f,-1.f,0.f); + pcMat->AddProperty(&v, 1,AI_MATKEY_TEXMAP_AXIS_DIFFUSE(0)); pcMat->AddProperty((int*)&src.shader.mapping, 1,AI_MATKEY_MAPPING_DIFFUSE(0)); + } } // setup the name of the material diff --git a/code/ProcessHelper.h b/code/ProcessHelper.h index 8aec59b86..c076ba0fc 100644 --- a/code/ProcessHelper.h +++ b/code/ProcessHelper.h @@ -67,6 +67,77 @@ inline float GetColorDifference( const aiColor4D& pColor1, const aiColor4D& pCol return c.r*c.r + c.g*c.g + c.b*c.b + c.a*c.a; } +// ------------------------------------------------------------------------------- +// Compute the AABB of a mesh +inline void FindAABB (const aiMesh* mesh, aiVector3D& min, aiVector3D& max) +{ + min = aiVector3D (10e10f, 10e10f, 10e10f); + max = aiVector3D (-10e10f,-10e10f,-10e10f); + for (unsigned int i = 0;i < mesh->mNumVertices;++i) + { + const aiVector3D& v = mesh->mVertices[i]; + min.x = ::std::min(v.x,min.x); + min.y = ::std::min(v.y,min.y); + min.z = ::std::min(v.z,min.z); + max.x = ::std::max(v.x,max.x); + max.y = ::std::max(v.y,max.y); + max.z = ::std::max(v.z,max.z); + } +} + +// ------------------------------------------------------------------------------- +// Compute the AABB of a mesh after applying a given transform +inline void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max, + const aiMatrix4x4& m) +{ + min = aiVector3D (10e10f, 10e10f, 10e10f); + max = aiVector3D (-10e10f,-10e10f,-10e10f); + for (unsigned int i = 0;i < mesh->mNumVertices;++i) + { + const aiVector3D v = m * mesh->mVertices[i]; + min.x = ::std::min(v.x,min.x); + min.y = ::std::min(v.y,min.y); + min.z = ::std::min(v.z,min.z); + max.x = ::std::max(v.x,max.x); + max.y = ::std::max(v.y,max.y); + max.z = ::std::max(v.z,max.z); + } +} + +// ------------------------------------------------------------------------------- +// Helper function to determine the 'real' center of a mesh +inline void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max) +{ + FindAABB(mesh,min,max); + out = min + (max-min)*0.5f; +} + +// ------------------------------------------------------------------------------- +// Helper function to determine the 'real' center of a mesh after applying a given transform +inline void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min, + aiVector3D& max, const aiMatrix4x4& m) +{ + FindAABBTransformed(mesh,min,max,m); + out = min + (max-min)*0.5f; +} + +// ------------------------------------------------------------------------------- +// Helper function to determine the 'real' center of a mesh +inline void FindMeshCenter (aiMesh* mesh, aiVector3D& out) +{ + aiVector3D min,max; + FindMeshCenter(mesh,out,min,max); +} + +// ------------------------------------------------------------------------------- +// Helper function to determine the 'real' center of a mesh after applying a given transform +inline void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, + const aiMatrix4x4& m) +{ + aiVector3D min,max; + FindMeshCenterTransformed(mesh,out,min,max,m); +} + // ------------------------------------------------------------------------------- // Compute a good epsilon value for position comparisons on a mesh inline float ComputePositionEpsilon(const aiMesh* pMesh) @@ -74,16 +145,8 @@ inline float ComputePositionEpsilon(const aiMesh* pMesh) const float epsilon = 1e-5f; // calculate the position bounds so we have a reliable epsilon to check position differences against - aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f); - for( unsigned int a = 0; a < pMesh->mNumVertices; a++) - { - minVec.x = std::min( minVec.x, pMesh->mVertices[a].x); - minVec.y = std::min( minVec.y, pMesh->mVertices[a].y); - minVec.z = std::min( minVec.z, pMesh->mVertices[a].z); - maxVec.x = std::max( maxVec.x, pMesh->mVertices[a].x); - maxVec.y = std::max( maxVec.y, pMesh->mVertices[a].y); - maxVec.z = std::max( maxVec.z, pMesh->mVertices[a].z); - } + aiVector3D minVec, maxVec; + FindAABB(pMesh,minVec,maxVec); return (maxVec - minVec).Length() * epsilon; } @@ -165,6 +228,14 @@ inline const char* TextureTypeToString(aiTextureType in) return "Height"; case aiTextureType_SHININESS: return "Shininess"; + case aiTextureType_DISPLACEMENT: + return "Displacement"; + case aiTextureType_LIGHTMAP: + return "Lightmap"; + case aiTextureType_REFLECTION: + return "Reflection"; + case aiTextureType_UNKNOWN: + return "Unknown"; default: return "HUGE ERROR, please leave the room immediately and call the police"; } diff --git a/code/fast_atof.h b/code/fast_atof.h index 19e9f3229..2511d229f 100644 --- a/code/fast_atof.h +++ b/code/fast_atof.h @@ -107,7 +107,8 @@ inline unsigned int strtol16( const char* in, const char** out=0) } // ------------------------------------------------------------------------------------ -// convert just one hex digit +// Convert just one hex digit +// Return value is 0xffffffff if the input is not hex // ------------------------------------------------------------------------------------ inline unsigned int HexDigitToDecimal(char in) { @@ -125,6 +126,16 @@ inline unsigned int HexDigitToDecimal(char in) return out; } +// ------------------------------------------------------------------------------------ +// Convert a hex-encoded octet (2 characters processed) +// Return value is 0xffffffff if the input is not hex +// ------------------------------------------------------------------------------------ +inline uint8_t HexOctetToDecimal(const char* in) +{ + return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]); +} + + // ------------------------------------------------------------------------------------ // signed variant of strtol10 // ------------------------------------------------------------------------------------ diff --git a/doc/lib_html/AssimpDoc.chm b/doc/lib_html/AssimpDoc.chm index d8a9830d0..4306657c8 100644 Binary files a/doc/lib_html/AssimpDoc.chm and b/doc/lib_html/AssimpDoc.chm differ diff --git a/include/aiAnim.h b/include/aiAnim.h index bb18ec5a6..a53710874 100644 --- a/include/aiAnim.h +++ b/include/aiAnim.h @@ -321,9 +321,7 @@ struct Interpolator } }; // ! Interpolator -// No need to have that in the doc, it is opaque. -// The compiler chooses the right variant and we're done. -#ifndef ASSIMP_DOXYGEN_BUILD +//! @cond Never template <> struct Interpolator { @@ -354,7 +352,7 @@ struct Interpolator { } }; // ! Interpolator -#endif // !! ASSIMP_DOXYGEN_BUILD +//! @endcond } // ! end namespace Assimp #endif // __cplusplus #endif // AI_ANIM_H_INC diff --git a/include/aiMaterial.h b/include/aiMaterial.h index 7f3a2ac0c..0baa69db4 100644 --- a/include/aiMaterial.h +++ b/include/aiMaterial.h @@ -116,61 +116,65 @@ enum aiPropertyTypeInfo */ enum aiTextureOp { - /** T = T1 * T2 */ - aiTextureOp_Multiply = 0x0, + /** T = T1 * T2 */ + aiTextureOp_Multiply = 0x0, - /** T = T1 + T2 */ - aiTextureOp_Add = 0x1, + /** T = T1 + T2 */ + aiTextureOp_Add = 0x1, - /** T = T1 - T2 */ - aiTextureOp_Subtract = 0x2, + /** T = T1 - T2 */ + aiTextureOp_Subtract = 0x2, - /** T = T1 / T2 */ - aiTextureOp_Divide = 0x3, + /** T = T1 / T2 */ + aiTextureOp_Divide = 0x3, - /** T = (T1 + T2) - (T1 * T2) */ - aiTextureOp_SmoothAdd = 0x4, + /** T = (T1 + T2) - (T1 * T2) */ + aiTextureOp_SmoothAdd = 0x4, - /** T = T1 + (T2-0.5) */ - aiTextureOp_SignedAdd = 0x5, + /** T = T1 + (T2-0.5) */ + aiTextureOp_SignedAdd = 0x5, - /** This value is not used. It is just there to force the - * compiler to map this enum to a 32 Bit integer. + /** @cond never + * This value is not used. It forces the compiler to use at least + * 32 Bit integers to represent this enum. */ _aiTextureOp_Force32Bit = 0x9fffffff + //! @endcond }; // --------------------------------------------------------------------------- /** @brief Defines how UV coordinates outside the [0...1] range are handled. * + * Commonly refered to as 'wrapping mode'. */ enum aiTextureMapMode { /** A texture coordinate u|v is translated to u%1|v%1 - */ + */ aiTextureMapMode_Wrap = 0x0, /** Texture coordinates outside [0...1] - * are clamped to the nearest valid value. - */ + * are clamped to the nearest valid value. + */ aiTextureMapMode_Clamp = 0x1, - /** If the texture coordinates for a pixel are outside [0...1] + /** If the texture coordinates for a pixel are outside [0...1] * the texture is not applied to that pixel - */ + */ aiTextureMapMode_Decal = 0x3, /** A texture coordinate u|v becomes u%1|v%1 if (u-(u%1))%2 is zero and - * 1-(u%1)|1-(v%1) otherwise - */ + * 1-(u%1)|1-(v%1) otherwise + */ aiTextureMapMode_Mirror = 0x2, - - /** This value is not used. It is just here to force the - * compiler to map this enum to a 32 Bit integer. - */ + /** @cond never + * This value is not used. It forces the compiler to use at least + * 32 Bit integers to represent this enum. + */ _aiTextureMapMode_Force32Bit = 0x9fffffff + //! @endcond }; // --------------------------------------------------------------------------- @@ -186,10 +190,11 @@ enum aiTextureMapping { /** The mapping coordinates are taken from an UV channel. * - * The #AI_MATKEY_UVWSRC key specifies from which (remember, + * The #AI_MATKEY_UVWSRC key specifies from which UV channel + * the texture coordinates are to be taken from (remember, * meshes can have more than one UV channel). */ - aiTextureMapping_UV = 0x0 , + aiTextureMapping_UV = 0x0, /** Spherical mapping */ aiTextureMapping_SPHERE = 0x1, @@ -207,177 +212,218 @@ enum aiTextureMapping aiTextureMapping_OTHER = 0x5, - /** This value is not used. It is just here to force the - * compiler to map this enum to a 32 Bit integer. - */ + /** @cond never + * This value is not used. It forces the compiler to use at least + * 32 Bit integers to represent this enum. + */ _aiTextureMapping_Force32Bit = 0x9fffffff + //! @endcond }; // --------------------------------------------------------------------------- -/** @brief Defines which mesh axes are used to construct the projection shape - * for non-UV mappings around the model. +/** @brief Defines the purpose of a texture * - * This corresponds to the #AI_MATKEY_TEXMAP_AXIS property. -*/ -enum aiAxis -{ - aiAxis_X = 0x0, - aiAxis_Y = 0x1, - aiAxis_Z = 0x2, - - - /** This value is not used. It is just here to force the - * compiler to map this enum to a 32 Bit integer. - */ - _aiAxis_Force32Bit = 0x9fffffff -}; - -// --------------------------------------------------------------------------- -/** Defines the purpose of a texture -*/ + * This is a very difficult topic. Different 3D packages support different + * kinds of textures. For very common texture types, such as bumpmaps, the + * rendering results depend on implementation details in the rendering + * pipelines of these applications. Assimp loads all texture references from + * the model file and tries to determine which of the predefined texture + * types below is the best choice to match the original use of the texture + * as closely as possible.
+ * + * In content pipelines you'll usually define how textures have to be handled, + * and the artists working on models have to conform to this specification, + * regardless which 3D tool they're using. + */ enum aiTextureType { - // Set as texture semantic for material properties not related to textures + /** Dummy value. + * + * No texture, but the value to be used as 'texture semantic' + * (#aiMaterialProperty::mSemantic) for all material properties + * *not* related to textures. + */ aiTextureType_NONE = 0x0, + /** The texture is combined with the result of the diffuse * lighting equation. - */ + */ aiTextureType_DIFFUSE = 0x1, - /** The texture is combined with the result of the specular + /** The texture is combined with the result of the specular * lighting equation. - */ + */ aiTextureType_SPECULAR = 0x2, - /** The texture is combined with the result of the ambient + /** The texture is combined with the result of the ambient * lighting equation. - */ + */ aiTextureType_AMBIENT = 0x3, - /** The texture is added to the result of the lighting - * calculation. It isn't influenced by lights. - */ + /** The texture is added to the result of the lighting + * calculation. It isn't influenced by incoming light. + */ aiTextureType_EMISSIVE = 0x4, - /** The texture is a height map and serves as input for - * a normal map generator. - */ + /** The texture is a height map. + * + * By convention, higher grey-scale values stand for + * higher elevations from the base height. + */ aiTextureType_HEIGHT = 0x5, - /** The texture is a (tangent space) normal-map. + /** The texture is a (tangent space) normal-map. * - * If the normal map does also contain a height channel - * for use with techniques such as Parallax Occlusion Mapping - * it is registered once as a normalmap. - */ + * Again, there are several conventions for tangent-space + * normal maps. Assimp does (intentionally) not + * differenciate here. + */ aiTextureType_NORMALS = 0x6, - /** The texture defines the glossiness of the material. + /** The texture defines the glossiness of the material. * * The glossiness is in fact the exponent of the specular - * lighting equation. Normally there is a conversion - * function define to map the linear color values in the + * (phong) lighting equation. Usually there is a conversion + * function defined to map the linear color values in the * texture to a suitable exponent. Have fun. */ aiTextureType_SHININESS = 0x7, - /** The texture defines a per-pixel opacity. + /** The texture defines per-pixel opacity. * - * Normally 'white' means opaque and 'black' means + * Usually 'white' means opaque and 'black' means * 'transparency'. Or quite the opposite. Have fun. */ aiTextureType_OPACITY = 0x8, + /** Displacement texture + * + * The exact purpose and format is application-dependent. + * Higher color values stand for higher vertex displacements. + */ + aiTextureType_DISPLACEMENT = 0x9, - /** This value is not used. It is just here to force the - * compiler to map this enum to a 32 Bit integer. + /** Lightmap texture (aka Ambient Occlusion) + * + * Both 'Lightmaps' and dedicated 'ambient occlusion maps' are + * covered by this material property. The texture contains a + * scaling value for the final color value of a pixel. It's + * intensity is not affected by incoming light. + */ + aiTextureType_LIGHTMAP = 0xA, + + /** Reflection texture + * + * Contains the color of a perfect mirror reflection. + * Rarely used, almost nevery for real-time applications. + */ + aiTextureType_REFLECTION = 0xB, + + /** Unknown texture + * + * A texture reference that does not match any of the definitions + * above is considered to be 'unknown'. It is still imported, + * but is excluded from any further postprocessing. + */ + aiTextureType_UNKNOWN = 0xC, + + + /** @cond never + * This value is not used. It forces the compiler to use at least + * 32 Bit integers to represent this enum. */ _aiTextureType_Force32Bit = 0x9fffffff + //! @endcond }; +#define AI_TEXTURE_TYPE_MAX aiTextureType_UNKNOWN + // --------------------------------------------------------------------------- /** @brief Defines all shading models supported by the library * - * @note The list of shading modes has been taken from Blender3D. - * See Blender3D documentation for more information. The API does + * The list of shading modes has been taken from Blender. + * See Blender documentation for more information. The API does * not distinguish between "specular" and "diffuse" shaders (thus the * specular term for diffuse shading models like Oren-Nayar remains - * undefined) + * undefined).
+ * Again, this value is just a hint. Assimp tries to select the shader whose + * most common implementation matches the original rendering results of the + * 3D modeller which wrote a particular model as closely as possible. */ enum aiShadingMode { /** Flat shading. Shading is done on per-face base, - * diffuse only. - */ + * diffuse only. Also known as 'faceted shading'. + */ aiShadingMode_Flat = 0x1, - /** Diffuse Gouraud shading. Shading on per-vertex base - */ + /** Simple Gouraud shading. + */ aiShadingMode_Gouraud = 0x2, - /** Diffuse/Specular Phong-Shading - * - * Shading is applied on per-pixel base. This is the - * slowest algorithm, but generates the best results. - */ + /** Phong-Shading - + */ aiShadingMode_Phong = 0x3, - /** Diffuse/Specular Phong-Blinn-Shading - * - * Shading is applied on per-pixel base. This is a little - * bit faster than Phong and in some cases even - * more realistic - */ + /** Phong-Blinn-Shading + */ aiShadingMode_Blinn = 0x4, /** Toon-Shading per pixel - * - * Shading is applied on per-pixel base. The output looks - * like a comic. Often combined with edge detection. - */ + * + * Also known as 'comic' shader. + */ aiShadingMode_Toon = 0x5, /** OrenNayar-Shading per pixel - * - * Extension to standard Lambertian shading, taking the - * roughness of the material into account - * - */ + * + * Extension to standard Lambertian shading, taking the + * roughness of the material into account + */ aiShadingMode_OrenNayar = 0x6, /** Minnaert-Shading per pixel - * - * Extension to standard Lambertian shading, taking the - * "darkness" of the material into account - */ + * + * Extension to standard Lambertian shading, taking the + * "darkness" of the material into account + */ aiShadingMode_Minnaert = 0x7, /** CookTorrance-Shading per pixel - */ + * + * Special shader for metallic surfaces. + */ aiShadingMode_CookTorrance = 0x8, - /** No shading at all + /** No shading at all. Constant light influence of 1.0. */ aiShadingMode_NoShading = 0x9, /** Fresnel shading - */ + */ aiShadingMode_Fresnel = 0xa, - /** This value is not used. It is just there to force the - * compiler to map this enum to a 32 Bit integer. - */ + /** @cond never + * This value is not used. It forces the compiler to use at least + * 32 Bit integers to represent this enum. + */ _aiShadingMode_Force32Bit = 0x9fffffff + //! @endcond }; // --------------------------------------------------------------------------- -/** @brief Defines flags for a texture. +/** @brief Defines some mixed flags for a particular texture. * - * See + * Usually you'll tell your artists how textures have to look like ... + * however, if you use Assimp for completely generic loadeing purposes you + * might also need to process these flags in order to display as many + * 'unknown' 3D models as possible correctly. + * + * This corresponds to the #AI_MATKEY_TEXFLAGS property. */ enum aiTextureFlags { @@ -386,10 +432,13 @@ enum aiTextureFlags aiTextureFlags_Invert = 0x1, - /** This value is not used. It is just there to force the - * compiler to map this enum to a 32 Bit integer. - */ + + /** @cond never + * This value is not used. It forces the compiler to use at least + * 32 Bit integers to represent this enum. + */ _aiTextureFlags_Force32Bit = 0x9fffffff + //! @endcond }; #include "./Compiler/pushpack1.h" @@ -406,17 +455,24 @@ enum aiTextureFlags */ struct aiUVTransform { - /** Translation on the u and v axes. */ + /** Translation on the u and v axes. + * + * The default value is (0|0). + */ C_STRUCT aiVector2D mTranslation; - /** Scaling on the u and v axes. */ + /** Scaling on the u and v axes. + * + * The default value is (1|1). + */ C_STRUCT aiVector2D mScaling; /** Rotation - in counter-clockwise direction. - * - * The rotation angle is specified in radians. The - * rotation center is 0.5f|0.5f. - */ + * + * The rotation angle is specified in radians. The + * rotation center is 0.5f|0.5f. The default value + * 0.f. + */ float mRotation; @@ -440,53 +496,53 @@ struct aiUVTransform struct aiMaterialProperty { /** Specifies the name of the property (key) - * - * Keys are case insensitive. - */ + * + * Keys are case insensitive. + */ C_STRUCT aiString mKey; - /** Textures: Specifies the exact usage semantic - */ + /** Textures: Specifies the exact usage semantic. + * + * For non-texture properties, this member is always 0 + * or #aiTextureType_NONE. + */ unsigned int mSemantic; /** Textures: Specifies the index of the texture - * - * Textures are counted per-type. - */ + * + * For non-texture properties, this member is always 0. + */ unsigned int mIndex; - /** Size of the buffer mData is pointing to, in bytes + /** Size of the buffer mData is pointing to, in bytes. + * * This value may not be 0. - */ + */ unsigned int mDataLength; /** Type information for the property. - * - * Defines the data layout inside the - * data buffer. This is used by the library - * internally to perform debug checks. - */ + * + * Defines the data layout inside the data buffer. This is used + * by the library internally to perform debug checks and to + * utilize proper type conversions. + * (It's probably a hacky solution, but it works.) + */ C_ENUM aiPropertyTypeInfo mType; /** Binary buffer to hold the property's value - * - * The buffer has no terminal character. However, - * if a string is stored inside it may use 0 as terminal, - * but it would be contained in mDataLength. This member - * is never 0 - */ + * + * The size of the buffer is always mDataLength. + */ char* mData; #ifdef __cplusplus - aiMaterialProperty() - { + aiMaterialProperty() { mData = NULL; mIndex = mSemantic = 0; } - ~aiMaterialProperty() - { + ~aiMaterialProperty() { delete[] mData; } @@ -602,138 +658,179 @@ extern "C" { // --------------------------------------------------------------------------- /** @def AI_MATKEY_NAME - * Defines the name of the material - *
+ * Defines the name of the material.
* Type: string (aiString)
- * Default value: none
+ * Default value: none
*/ #define AI_MATKEY_NAME "$mat.name",0,0 - +// --------------------------------------------------------------------------- /** @def AI_MATKEY_TWOSIDED - * Indicates that the material must be rendered two-sided - *
+ * Indicates that the material must be rendered two-sided (means: no + * backface culling).
* Type: int
- * Default value: 0
+ * Default value: 0
*/ #define AI_MATKEY_TWOSIDED "$mat.twosided",0,0 - +// --------------------------------------------------------------------------- /** @def AI_MATKEY_SHADING_MODEL - * Defines the shading model to use (aiShadingMode) + * Defines the shading model to be used for this material. See the doc for + * #aiShadingMode for a complete list of all predefined values. *
* Type: int (aiShadingMode)
- * Default value: aiShadingMode_Gouraud
+ * Default value: aiShadingMode_Gouraud */ #define AI_MATKEY_SHADING_MODEL "$mat.shadingm",0,0 - +// --------------------------------------------------------------------------- /** @def AI_MATKEY_ENABLE_WIREFRAME - * Integer property. 1 to enable wireframe for rendering + * Integer property. 1 to enable wireframe mode for rendering. + * A material with this property set to 1 should appear as wireframe, even + * if the scene is rendered solid. *
* Type: int
- * Default value: 0
+ * Default value: 0 */ #define AI_MATKEY_ENABLE_WIREFRAME "$mat.wireframe",0,0 - +// --------------------------------------------------------------------------- /** @def AI_MATKEY_OPACITY - * Defines the base opacity of the material + * Defines the base opacity of the material. This value defines how + * transparent the material actually is. However, in order to get absolutely + * correct results you'll also need to evaluate the + * #AI_MATKEY_COLOR_TRANSPARENT property. *
* Type: float
- * Default value: 1.0f
-*/ + * Default value: 1.0f
+ */ #define AI_MATKEY_OPACITY "$mat.opacity",0,0 - +// --------------------------------------------------------------------------- /** @def AI_MATKEY_BUMPSCALING * Defines the height scaling of a bump map (for stuff like Parallax - * Occlusion Mapping) - *
+ * Occlusion Mapping). The actual interpretation/range depends on the + * 3D applications which wrote a particular model.
+ * * Type: float
- * Default value: 1.0f
-*/ + * Default value: 1.0f + */ #define AI_MATKEY_BUMPSCALING "$mat.bumpscaling",0,0 - +// --------------------------------------------------------------------------- /** @def AI_MATKEY_SHININESS * Defines the base shininess of the material - * This is the exponent of the Phong shading equation. - *
+ * This is the exponent of the Phong and Phong-Blinn shading equations. + * The range is undefined and depends on the shader being used. The + * value will not be negative, though.
+ * * Type: float
- * Default value: 0.0f
-*/ + * Default value: 0.0f + */ #define AI_MATKEY_SHININESS "$mat.shininess",0,0 - +// --------------------------------------------------------------------------- /** @def AI_MATKEY_SHININESS_STRENGTH * Defines the strength of the specular highlight. - * This is simply a multiplier to the specular color of a material - *
- * Type: float
- * Default value: 1.0f
-*/ + * This simply scales the specular lighting coefficient.
+ * + * Type: float
+ * Default value: 1.0f + * @note The same effect could be achieved by scaling the specular material + * color. However, most 3D modelers keep this property separate and so + * do we. OK!? + */ #define AI_MATKEY_SHININESS_STRENGTH "$mat.shinpercent",0,0 +// --------------------------------------------------------------------------- /** @def AI_MATKEY_REFRACTI * Index of refraction of the material. This is used by some shading models, - * e.g. Cook-Torrance. The value is the ratio of the speed of light in a - * vacuum to the speed of light in the material (always >= 1.0 in the real world). - *
- * Type: float
- * Default value: 1.0f
-*/ + * e.g. Cook-Torrance. The value is the ratio of the speed of light in a + * vacuum to the speed of light in the material.
+ * + * Type: float
+ * Default value: 1.0f + */ #define AI_MATKEY_REFRACTI "$mat.refracti",0,0 // --------------------------------------------------------------------------- /** @def AI_MATKEY_COLOR_DIFFUSE - * Defines the diffuse base color of the material - *
- * Type: color (aiColor4D or aiColor3D)
- * Default value: 0.0f|0.0f|0.0f|1.0f
+ * Defines the diffuse base color of the material.
+ * Type: color (#aiColor4D or #aiColor3D)
+ * Default value: 0.0f|0.0f|0.0f|1.0f */ #define AI_MATKEY_COLOR_DIFFUSE "$clr.diffuse",0,0 /** @def AI_MATKEY_COLOR_AMBIENT - * Defines the ambient base color of the material - *
- * Type: color (aiColor4D or aiColor3D)
- * Default value: 0.0f|0.0f|0.0f|1.0f
+ * Declares the amount of ambient light emitted from + * the surface of this object.
+ * Type: color (#aiColor4D or #aiColor3D)
+ * Default value: 0.0f|0.0f|0.0f|1.0f */ #define AI_MATKEY_COLOR_AMBIENT "$clr.ambient",0,0 /** @def AI_MATKEY_COLOR_SPECULAR - * Defines the specular base color of the material - *
- * Type: color (aiColor4D or aiColor3D)
- * Default value: 0.0f|0.0f|0.0f|1.0f
+ * Declares the color of light specularly reflected from + * the surface of this object.
+ * Type: color (#aiColor4D or #aiColor3D)
+ * Default value: 0.0f|0.0f|0.0f|1.0f */ #define AI_MATKEY_COLOR_SPECULAR "$clr.specular",0,0 /** @def AI_MATKEY_COLOR_EMISSIVE - * Defines the emissive base color of the material - *
- * Type: color (aiColor4D or aiColor3D)
- * Default value: 0.0f|0.0f|0.0f|1.0f
+ * Declares the amount of light emitted from the + * surface of this object.
+ * Type: color (#aiColor4D or #aiColor3D)
+ * Default value: 0.0f|0.0f|0.0f|1.0f */ #define AI_MATKEY_COLOR_EMISSIVE "$clr.emissive",0,0 +/** @def AI_MATKEY_COLOR_TRANSPARENT + * Defines the transparent base color of the material.
+ * Type: color (#aiColor4D or #aiColor3D)
+ * Default value: 0.0f|0.0f|0.0f|1.0f +*/ +#define AI_MATKEY_COLOR_TRANSPARENT "$clr.transparent",0,0 + +/** @def AI_MATKEY_COLOR_REFLECTIVE + * Declares the color of a perfect mirror reflection.
+ * Type: color (#aiColor4D or #aiColor3D)
+ * Default value: 0.0f|0.0f|0.0f|1.0f +*/ +#define AI_MATKEY_COLOR_REFLECTIVE "$clr.reflective",0,0 + + // --------------------------------------------------------------------------- -/** @def AI_MATKEY_TEXTURE - * Parameters: type, N
+// Pure key names for all texture-related properties +//! @cond MATS_DOC_FULL +#define _AI_MATKEY_TEXTURE_BASE "$tex.file" +#define _AI_MATKEY_UVWSRC_BASE "$tex.uvwsrc" +#define _AI_MATKEY_TEXOP_BASE "$tex.op" +#define _AI_MATKEY_MAPPING_BASE "$tex.mapping" +#define _AI_MATKEY_TEXBLEND_BASE "$tex.blend" +#define _AI_MATKEY_MAPPINGMODE_U_BASE "$tex.mapmodeu" +#define _AI_MATKEY_MAPPINGMODE_V_BASE "$tex.mapmodev" +#define _AI_MATKEY_TEXMAP_AXIS_BASE "$tex.mapaxis" +#define _AI_MATKEY_UVTRANSFORM_BASE "$tex.uvtrafo" +#define _AI_MATKEY_TEXFLAGS_BASE "$tex.flags" +//! @endcond + +// --------------------------------------------------------------------------- +/** + * @def AI_MATKEY_TEXTURE * Specifies the path to the Nth texture of type "type". - * This can either be a path to the texture or a string of the form '*<i>' + * This can either be a path to the texture or a string of the form '*i' * where i is an index into the array of embedded textures that has been - * imported along with the scene. See aiTexture for more details. + * imported along with the scene. See #aiTexture for more details. *
- * Type: String
- * Default value to be assumed if this key isn't there: n/a
+ * Type: #aiString
+ * Default value if key is not defined: n/a
*/ // --------------------------------------------------------------------------- -#define _AI_MATKEY_TEXTURE_BASE "$tex.file" #define AI_MATKEY_TEXTURE(type, N) _AI_MATKEY_TEXTURE_BASE,type,N -// for backward compatibility +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL #define AI_MATKEY_TEXTURE_DIFFUSE(N) \ AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE,N) @@ -758,23 +855,39 @@ extern "C" { #define AI_MATKEY_TEXTURE_OPACITY(N) \ AI_MATKEY_TEXTURE(aiTextureType_OPACITY,N) +#define AI_MATKEY_TEXTURE_DISPLACEMENT(N) \ + AI_MATKEY_TEXTURE(aiTextureType_DISPLACEMENT,N) + +#define AI_MATKEY_TEXTURE_LIGHTMAP(N) \ + AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_TEXTURE_REFLECTION(N) \ + AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_TEXTURE_UNKNOWN(N) \ + AI_MATKEY_TEXTURE(aiTextureType_UNKNOWN,N) + +//! @endcond // --------------------------------------------------------------------------- -/** @def AI_MATKEY_UVWSRC - * Parameters: type, N
+/** + * @def AI_MATKEY_UVWSRC * Specifies which UV channel is used as source for the mapping coordinates - * of the Nth texture of type "type". + * of the Nth texture of type "type". If the requested mapping channel does + * not exist in a mesh associated with the material, decrement the index by + * one until you find a working UV channel. Please note that this property + * is mutually exlusive with AI_MATKEY_MAPPING(type,N) set to 'UV'. *
* Type: int
- * Default value to be assumed if this key isn't there: 0
+ * Default value if key is not defined:0
* Requires: AI_MATKEY_TEXTURE(type,N) * and AI_MATKEY_MAPPING(type,N) == UV
*/ // --------------------------------------------------------------------------- -#define _AI_MATKEY_UVWSRC_BASE "$tex.uvwsrc" #define AI_MATKEY_UVWSRC(type, N) _AI_MATKEY_UVWSRC_BASE,type,N -// for backward compatibility +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL #define AI_MATKEY_UVWSRC_DIFFUSE(N) \ AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE,N) @@ -799,22 +912,34 @@ extern "C" { #define AI_MATKEY_UVWSRC_OPACITY(N) \ AI_MATKEY_UVWSRC(aiTextureType_OPACITY,N) +#define AI_MATKEY_UVWSRC_DISPLACEMENT(N) \ + AI_MATKEY_UVWSRC(aiTextureType_DISPLACEMENT,N) +#define AI_MATKEY_UVWSRC_LIGHTMAP(N) \ + AI_MATKEY_UVWSRC(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_UVWSRC_REFLECTION(N) \ + AI_MATKEY_UVWSRC(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_UVWSRC_UNKNOWN(N) \ + AI_MATKEY_UVWSRC(aiTextureType_UNKNOWN,N) + +//! @endcond // --------------------------------------------------------------------------- -/** @def AI_MATKEY_TEXOP - * Parameters: type, N
+/** + * @def AI_MATKEY_TEXOP * Specifies how the Nth texture of type "type" is combined with - * the result of all color values from all previous textures combined. + * the result of all color values from all previous texture layers combined. *
- * Type: int (aiTextureOp)
- * Default value to be assumed if this key isn't there: multiply
+ * Type: int (#aiTextureOp)
+ * Default value if key is not defined: #aiTextureOp_Multiply
* Requires: AI_MATKEY_TEXTURE(type,N)
*/ // --------------------------------------------------------------------------- -#define _AI_MATKEY_TEXOP_BASE "$tex.op" #define AI_MATKEY_TEXOP(type, N) _AI_MATKEY_TEXOP_BASE,type,N -// for backward compatibility +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL #define AI_MATKEY_TEXOP_DIFFUSE(N) \ AI_MATKEY_TEXOP(aiTextureType_DIFFUSE,N) @@ -839,21 +964,33 @@ extern "C" { #define AI_MATKEY_TEXOP_OPACITY(N) \ AI_MATKEY_TEXOP(aiTextureType_OPACITY,N) +#define AI_MATKEY_TEXOP_DISPLACEMENT(N) \ + AI_MATKEY_TEXOP(aiTextureType_DISPLACEMENT,N) +#define AI_MATKEY_TEXOP_LIGHTMAP(N) \ + AI_MATKEY_TEXOP(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_TEXOP_REFLECTION(N) \ + AI_MATKEY_TEXOP(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_TEXOP_UNKNOWN(N) \ + AI_MATKEY_TEXOP(aiTextureType_UNKNOWN,N) + +//! @endcond // --------------------------------------------------------------------------- -/** @def AI_MATKEY_MAPPING - * Parameters: type, N
+/** + * @def AI_MATKEY_MAPPING * Specifies how the Nth texture of type "type" is mapped. *
- * Type: int (aiTextureMapping)
- * Default value to be assumed if this key isn't there: UV
- * Requires: AI_MATKEY_TEXTURE(type,N)
+ * Type: int (#aiTextureMapping)
+ * Default value if key is not defined: #aiTextureMapping_UV
+ * Requires:#AI_MATKEY_TEXTURE(type,N)
*/ // --------------------------------------------------------------------------- -#define _AI_MATKEY_MAPPING_BASE "$tex.mapping" #define AI_MATKEY_MAPPING(type, N) _AI_MATKEY_MAPPING_BASE,type,N -// for backward compatibility +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL #define AI_MATKEY_MAPPING_DIFFUSE(N) \ AI_MATKEY_MAPPING(aiTextureType_DIFFUSE,N) @@ -878,22 +1015,35 @@ extern "C" { #define AI_MATKEY_MAPPING_OPACITY(N) \ AI_MATKEY_MAPPING(aiTextureType_OPACITY,N) +#define AI_MATKEY_MAPPING_DISPLACEMENT(N) \ + AI_MATKEY_MAPPING(aiTextureType_DISPLACEMENT,N) + +#define AI_MATKEY_MAPPING_LIGHTMAP(N) \ + AI_MATKEY_MAPPING(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_MAPPING_REFLECTION(N) \ + AI_MATKEY_MAPPING(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_MAPPING_UNKNOWN(N) \ + AI_MATKEY_MAPPING(aiTextureType_UNKNOWN,N) + +//! @endcond // --------------------------------------------------------------------------- -/** @def AI_MATKEY_TEXBLEND ( - * Parameters: type, N
+/** + * @def AI_MATKEY_TEXBLEND * Specifies the strength of the th texture of type . This is just * a multiplier for the texture's color values. It may have any value, even - * outside [0..1] + * outside [0..1]. *
* Type: float
- * Default value to be assumed if this key isn't there: 1.f
- * Requires: AI_MATKEY_TEXTURE(type,N)
+ * Default value if this key is not defined:1.f
+ * Requires: #AI_MATKEY_TEXTURE(type,N)
*/ // --------------------------------------------------------------------------- -#define _AI_MATKEY_TEXBLEND_BASE "$tex.blend" #define AI_MATKEY_TEXBLEND(type, N) _AI_MATKEY_TEXBLEND_BASE,type,N -// for backward compatibility +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL #define AI_MATKEY_TEXBLEND_DIFFUSE(N) \ AI_MATKEY_TEXBLEND(aiTextureType_DIFFUSE,N) @@ -918,21 +1068,36 @@ extern "C" { #define AI_MATKEY_TEXBLEND_OPACITY(N) \ AI_MATKEY_TEXBLEND(aiTextureType_OPACITY,N) +#define AI_MATKEY_TEXBLEND_DISPLACEMENT(N) \ + AI_MATKEY_TEXBLEND(aiTextureType_DISPLACEMENT,N) + +#define AI_MATKEY_TEXBLEND_LIGHTMAP(N) \ + AI_MATKEY_TEXBLEND(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_TEXBLEND_REFLECTION(N) \ + AI_MATKEY_TEXBLEND(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_TEXBLEND_UNKNOWN(N) \ + AI_MATKEY_TEXBLEND(aiTextureType_UNKNOWN,N) + +//! @endcond // --------------------------------------------------------------------------- -/** @def AI_MATKEY_MAPPINGMODE_U - * Parameters: type, N
+/** + * @def AI_MATKEY_MAPPINGMODE_U * Specifies the texture mapping mode for the th texture of type in - * the u (x) direction + * the u (x) direction. *
- * Type: int (aiTextureMapMode)
- * Default value: aiTextureMapMode_Wrap
+ * Type: int (#aiTextureMapMode)
+ * Default value if key is not defined:#aiTextureMapMode_Wrap
* Requires: AI_MATKEY_TEXTURE(type,N)
+ * @note There's no equivalent property for the 'w' axis of volume textures, + * just because no formats exports this information. */ // --------------------------------------------------------------------------- -#define _AI_MATKEY_MAPPINGMODE_U_BASE "$tex.mapmodeu" #define AI_MATKEY_MAPPINGMODE_U(type, N) _AI_MATKEY_MAPPINGMODE_U_BASE,type,N -// for backward compatibility +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL #define AI_MATKEY_MAPPINGMODE_U_DIFFUSE(N) \ AI_MATKEY_MAPPINGMODE_U(aiTextureType_DIFFUSE,N) @@ -957,21 +1122,36 @@ extern "C" { #define AI_MATKEY_MAPPINGMODE_U_OPACITY(N) \ AI_MATKEY_MAPPINGMODE_U(aiTextureType_OPACITY,N) +#define AI_MATKEY_MAPPINGMODE_U_DISPLACEMENT(N) \ + AI_MATKEY_MAPPINGMODE_U(aiTextureType_DISPLACEMENT,N) + +#define AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(N) \ + AI_MATKEY_MAPPINGMODE_U(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_MAPPINGMODE_U_REFLECTION(N) \ + AI_MATKEY_MAPPINGMODE_U(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_MAPPINGMODE_U_UNKNOWN(N) \ + AI_MATKEY_MAPPINGMODE_U(aiTextureType_UNKNOWN,N) + +//! @endcond // --------------------------------------------------------------------------- -/** @def AI_MATKEY_MAPPINGMODE_V - * Parameters: type, N
+/** + * @def AI_MATKEY_MAPPINGMODE_V * Specifies the texture mapping mode for the th texture of type in - * the w (z) direction + * the w (z) direction. *
- * Type: int (aiTextureMapMode)
- * Default value: aiTextureMapMode_Wrap
+ * Type: int (#aiTextureMapMode)
+ * Default value if key is not defined:#aiTextureMapMode_Wrap
* Requires: AI_MATKEY_TEXTURE(type,N)
+ * @note There's no equivalent property for the 'w' axis of volume textures, + * just because no formats exports this information. */ // --------------------------------------------------------------------------- -#define _AI_MATKEY_MAPPINGMODE_V_BASE "$tex.mapmodev" #define AI_MATKEY_MAPPINGMODE_V(type, N) _AI_MATKEY_MAPPINGMODE_V_BASE,type,N -// for backward compatibility +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL #define AI_MATKEY_MAPPINGMODE_V_DIFFUSE(N) \ AI_MATKEY_MAPPINGMODE_V(aiTextureType_DIFFUSE,N) @@ -996,80 +1176,92 @@ extern "C" { #define AI_MATKEY_MAPPINGMODE_V_OPACITY(N) \ AI_MATKEY_MAPPINGMODE_V(aiTextureType_OPACITY,N) +#define AI_MATKEY_MAPPINGMODE_V_DISPLACEMENT(N) \ + AI_MATKEY_MAPPINGMODE_V(aiTextureType_DISPLACEMENT,N) + +#define AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(N) \ + AI_MATKEY_MAPPINGMODE_V(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_MAPPINGMODE_V_REFLECTION(N) \ + AI_MATKEY_MAPPINGMODE_V(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_MAPPINGMODE_V_UNKNOWN(N) \ + AI_MATKEY_MAPPINGMODE_V(aiTextureType_UNKNOWN,N) + +//! @endcond // --------------------------------------------------------------------------- -/** @def AI_MATKEY_MAPPINGMODE_W - * Parameters: type, N
- * Specifies the texture mapping mode for the th texture of type in - * the w (z) direction - *
- * Type: int (aiTextureMapMode)
- * Default value: aiTextureMapMode_Wrap
- * Requires: AI_MATKEY_TEXTURE(type,N)
- */ -// --------------------------------------------------------------------------- -#define _AI_MATKEY_MAPPINGMODE_W_BASE "$tex.mapmodew" -#define AI_MATKEY_MAPPINGMODE_W(type, N) _AI_MATKEY_MAPPINGMODE_W_BASE,type,N - -// for backward compatibility -#define AI_MATKEY_MAPPINGMODE_W_DIFFUSE(N) \ - AI_MATKEY_MAPPINGMODE_W(aiTextureType_DIFFUSE,N) - -#define AI_MATKEY_MAPPINGMODE_W_SPECULAR(N) \ - AI_MATKEY_MAPPINGMODE_W(aiTextureType_SPECULAR,N) - -#define AI_MATKEY_MAPPINGMODE_W_AMBIENT(N) \ - AI_MATKEY_MAPPINGMODE_W(aiTextureType_AMBIENT,N) - -#define AI_MATKEY_MAPPINGMODE_W_EMISSIVE(N) \ - AI_MATKEY_MAPPINGMODE_W(aiTextureType_EMISSIVE,N) - -#define AI_MATKEY_MAPPINGMODE_W_NORMALS(N) \ - AI_MATKEY_MAPPINGMODE_W(aiTextureType_NORMALS,N) - -#define AI_MATKEY_MAPPINGMODE_W_HEIGHT(N) \ - AI_MATKEY_MAPPINGMODE_W(aiTextureType_HEIGHT,N) - -#define AI_MATKEY_MAPPINGMODE_W_SHININESS(N) \ - AI_MATKEY_MAPPINGMODE_W(aiTextureType_SHININESS,N) - -#define AI_MATKEY_MAPPINGMODE_W_OPACITY(N) \ - AI_MATKEY_MAPPINGMODE_W(aiTextureType_OPACITY,N) - - -// --------------------------------------------------------------------------- -/** @def AI_MATKEY_TEXMAP_AXIS - * Parameters: type, N
+/** + * @def AI_MATKEY_TEXMAP_AXIS * Specifies the main mapping axis of the Nth texture of type "type". * This applies to non-UV mapped textures. For spherical, cylindrical and * planar this is the main axis of the corresponding geometric shape. *
- * Type: int (aiAxis)
- * Default value: aiAxis_Z
+ * Type: float[3] (#aiVector3D)
+ * Default value if key is not defined: aiVector3D(0.f,1.f,0.f)
* Requires: AI_MATKEY_TEXTURE(type,N) and * AI_MATKEY_MAPPING(type,N) != UV
*/ // --------------------------------------------------------------------------- -#define _AI_MATKEY_TEXMAP_AXIS_BASE "$tex.mapaxis" #define AI_MATKEY_TEXMAP_AXIS(type, N) _AI_MATKEY_TEXMAP_AXIS_BASE,type,N +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL +#define AI_MATKEY_TEXMAP_AXIS_DIFFUSE(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_DIFFUSE,N) + +#define AI_MATKEY_TEXMAP_AXIS_SPECULAR(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_SPECULAR,N) + +#define AI_MATKEY_TEXMAP_AXIS_AMBIENT(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_AMBIENT,N) + +#define AI_MATKEY_TEXMAP_AXIS_EMISSIVE(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_EMISSIVE,N) + +#define AI_MATKEY_TEXMAP_AXIS_NORMALS(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_NORMALS,N) + +#define AI_MATKEY_TEXMAP_AXIS_HEIGHT(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_HEIGHT,N) + +#define AI_MATKEY_TEXMAP_AXIS_SHININESS(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_SHININESS,N) + +#define AI_MATKEY_TEXMAP_AXIS_OPACITY(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_OPACITY,N) + +#define AI_MATKEY_TEXMAP_AXIS_DISPLACEMENT(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_DISPLACEMENT,N) + +#define AI_MATKEY_TEXMAP_AXIS_LIGHTMAP(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_TEXMAP_AXIS_REFLECTION(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_TEXMAP_AXIS_UNKNOWN(N) \ + AI_MATKEY_TEXMAP_AXIS(aiTextureType_UNKNOWN,N) + +//! @endcond // --------------------------------------------------------------------------- -/** @def AI_MATKEY_UVTRANSFORM - * Parameters: type, N
+/** + * @def AI_MATKEY_UVTRANSFORM * Specifies how the UV mapping coordinates for the Nth texture of type * "type" are transformed before they're used for mapping. This is an array * of five floats - use the aiUVTransform structure for simplicity. *
* Type: Array of 5 floats
- * Default value: 0.f,0.f,1.f,1.f,0.f
+ * Default value if key is not defined:0.f,0.f,1.f,1.f,0.f
* Requires: AI_MATKEY_TEXTURE(type,N) and * AI_MATKEY_MAPPING(type,N) == UV
- * Note:Transformed 3D texture coordinates are not supported + * Note:Transformed 3D texture coordinates are not *yet* supported. + * And they'll probably never be, no format exports such rubbish. */ // --------------------------------------------------------------------------- -#define _AI_MATKEY_UVTRANSFORM_BASE "$tex.uvtrafo" #define AI_MATKEY_UVTRANSFORM(type, N) _AI_MATKEY_UVTRANSFORM_BASE,type,N -// for backward compatibility +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL #define AI_MATKEY_UVTRANSFORM_DIFFUSE(N) \ AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,N) @@ -1094,7 +1286,69 @@ extern "C" { #define AI_MATKEY_UVTRANSFORM_OPACITY(N) \ AI_MATKEY_UVTRANSFORM(aiTextureType_OPACITY,N) +#define AI_MATKEY_UVTRANSFORM_DISPLACEMENT(N) \ + AI_MATKEY_UVTRANSFORM(aiTextureType_DISPLACEMENT,N) +#define AI_MATKEY_UVTRANSFORM_LIGHTMAP(N) \ + AI_MATKEY_UVTRANSFORM(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_UVTRANSFORM_REFLECTION(N) \ + AI_MATKEY_UVTRANSFORM(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_UVTRANSFORM_UNKNOWN(N) \ + AI_MATKEY_UVTRANSFORM(aiTextureType_UNKNOWN,N) + +//! @endcond +// --------------------------------------------------------------------------- +/** + * @def AI_MATKEY_TEXFLAGS + * Specifies flags for the Nth texture of type 'type'. The key is a bitwise + * combination of the #aiTextureFlags enumerated values. + *
+ * Type: int (#aiTextureFlags)
+ * Default value if key is not defined: 0
+ * Requires:#AI_MATKEY_TEXTURE(type,N)
+ */ +// --------------------------------------------------------------------------- +#define AI_MATKEY_TEXFLAGS(type, N) _AI_MATKEY_TEXFLAGS_BASE,type,N + +// For backward compatibility and simplicity +//! @cond MATS_DOC_FULL +#define AI_MATKEY_TEXFLAGS_DIFFUSE(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_DIFFUSE,N) + +#define AI_MATKEY_TEXFLAGS_SPECULAR(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_SPECULAR,N) + +#define AI_MATKEY_TEXFLAGS_AMBIENT(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_AMBIENT,N) + +#define AI_MATKEY_TEXFLAGS_EMISSIVE(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_EMISSIVE,N) + +#define AI_MATKEY_TEXFLAGS_NORMALS(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_NORMALS,N) + +#define AI_MATKEY_TEXFLAGS_HEIGHT(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_HEIGHT,N) + +#define AI_MATKEY_TEXFLAGS_SHININESS(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_SHININESS,N) + +#define AI_MATKEY_TEXFLAGS_OPACITY(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_OPACITY,N) + +#define AI_MATKEY_TEXFLAGS_DISPLACEMENT(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_DISPLACEMENT,N) + +#define AI_MATKEY_TEXFLAGS_LIGHTMAP(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_LIGHTMAP,N) + +#define AI_MATKEY_TEXFLAGS_REFLECTION(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_REFLECTION,N) + +#define AI_MATKEY_TEXFLAGS_UNKNOWN(N) \ + AI_MATKEY_TEXFLAGS(aiTextureType_UNKNOWN,N) #define AI_MATKEY_ORENNAYAR_ROUGHNESS "$shading.orennayar.roughness",0,0 @@ -1102,9 +1356,11 @@ extern "C" { #define AI_MATKEY_COOK_TORRANCE_PARAM "$shading.cookt.param",0,0 /** @def AI_MATKEY_GLOBAL_BACKGROUND_IMAGE -* Global property defined by some loaders. Contains the path to -* the image file to be used as background image. -*/ + * Global property defined by some loaders. Contains the path to + * the image file to be used as background image. + * + * @deprecated + */ #define AI_MATKEY_GLOBAL_BACKGROUND_IMAGE "$global.bg.image2d",0,0 @@ -1276,48 +1532,56 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat, // --------------------------------------------------------------------------- /** @brief Helper function to get a texture from a material structure. * - * This function is provided just for convenience. - * @param mat Pointer to the input material. May not be NULL - * @param index Index of the texture to retrieve. If the index is too - * large the function fails. - * @param type Specifies the type of the texture to retrieve (e.g. diffuse, - * specular, height map ...) - * @param path Receives the output path - * NULL is not allowed as value - * @param mapping The texture mapping. - * NULL is allowed as value. - * @param uvindex Receives the UV index of the texture. - * NULL is allowed as value. - * @param blend Receives the blend factor for the texture - * NULL is allowed as value. - * @param op Receives the texture operation to perform between - * this texture and the previous texture. NULL is allowed as value. - * @param mapmode Receives the mapping modes to be used for the texture. - * The parameter may be NULL but if it is a valid pointer it MUST - * point to an array of 3 aiTextureMapMode variables (one for each - * axis: UVW order (=XYZ)). + * This function is provided just for convenience. You could also read the + * texture by reading all of its properties manually. This function bundles + * all of them in a huge function-monster. + * + * @param[in] mat Pointer to the input material. May not be NULL + * @param[in] type Specifies the type of the texture to read (e.g. diffuse, + * specular, height map ...). + * @param[in] index Index of the texture layer to be read. The function + * fails if the requested layer is not available. + * @param[out] path Receives the output path + * This parameter mist be non-null. + * @param mapping The texture mapping mode to be used. + * Pass NULL if you'e not interested in this information. + * @param[out] uvindex For UV-mapped textures: receives the index of the UV + * source channel. Unmodified otherwise. + * Pass NULL if you'e not interested in this information. + * @param[out] blend Receives the blend factor for the texture + * Pass NULL if you'e not interested in this information. + * @param[out] op Receives the texture blend operation to be perform between + * this texture and the previous texture. + * Pass NULL if you'e not interested in this information. + * @param[out] mapmode Receives the mapping modes to be used for the texture. + * Pass NULL if you'e not interested in this information. Otherwise, + * pass a pointer to an array of two aiTextureMapMode's (one for each + * axis, UV order). + * @return AI_SUCCESS on success, something else otherwise. Have fun. */ // --------------------------------------------------------------------------- #ifdef __cplusplus ASSIMP_API aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat, - aiTextureType type, + aiTextureType type, unsigned int index, aiString* path, - aiTextureMapping* mapping = NULL, + aiTextureMapping* mapping = NULL, unsigned int* uvindex = NULL, float* blend = NULL, aiTextureOp* op = NULL, - aiTextureMapMode* mapmode = NULL); + aiTextureMapMode* mapmode = NULL, + unsigned int* flags = NULL); #else C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat, C_ENUM aiTextureType type, unsigned int index, C_STRUCT aiString* path, - C_ENUM aiTextureMapping* mapping /*= NULL*/, + C_ENUM aiTextureMapping* mapping /*= NULL*/, unsigned int* uvindex /*= NULL*/, float* blend /*= NULL*/, C_ENUM aiTextureOp* op /*= NULL*/, - C_ENUM aiTextureMapMode* mapmode /*= NULL*/); + C_ENUM aiTextureMapMode* mapmode /*= NULL*/, + unsigned int* flags /*= NULL*/); #endif // !#ifdef __cplusplus #ifdef __cplusplus diff --git a/include/aiMaterial.inl b/include/aiMaterial.inl index 3e36bb685..5bc49e4eb 100644 --- a/include/aiMaterial.inl +++ b/include/aiMaterial.inl @@ -40,12 +40,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file aiMaterial.inl - * @brief Defines the material system of the library + * @brief Defines the C++ getters for the material system */ #ifndef AI_MATERIAL_INL_INC #define AI_MATERIAL_INL_INC +//! @cond never + // --------------------------------------------------------------------------- inline aiReturn aiMaterial::GetTexture( aiTextureType type, unsigned int index, @@ -74,8 +76,8 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, if (prop->mDataLength < sizeof(Type)*iNum) return AI_FAILURE; - if (::strcmp(prop->mData,(char*)aiPTI_Buffer)!=0) - return AI_FAILURE; + // if (::strcmp(prop->mData,(char*)aiPTI_Buffer)!=0) + // return AI_FAILURE; iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type)); ::memcpy(pOut,prop->mData,iNum * sizeof(Type)); @@ -149,4 +151,6 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, return aiGetMaterialString(this,pKey,type,idx,&pOut); } +//! @endcond + #endif //! AI_MATERIAL_INL_INC diff --git a/include/aiScene.h b/include/aiScene.h index b2505e406..ee6196f21 100644 --- a/include/aiScene.h +++ b/include/aiScene.h @@ -57,23 +57,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. extern "C" { #endif - -// --------------------------------------------------------------------------- +// ------------------------------------------------------------------------------- /** A node in the imported hierarchy. -* -* Each node has name, a parent node (except for the root node), -* a transformation relative to its parent and possibly several child nodes. -* Simple file formats don't support hierarchical structures - for these formats -* the imported scene does consist of only a single root node without children. -*/ -// --------------------------------------------------------------------------- + * + * Each node has name, a parent node (except for the root node), + * a transformation relative to its parent and possibly several child nodes. + * Simple file formats don't support hierarchical structures - for these formats + * the imported scene does consist of only a single root node without children. + */ +// ------------------------------------------------------------------------------- struct aiNode { /** The name of the node. - * - * The name might be empty (length of zero) but all nodes which - * need to be accessed afterwards by bones or anims are usually named. - */ + * + * The name might be empty (length of zero) but all nodes which + * need to be accessed afterwards by bones or anims are usually named. + * Multiple nodes may have the same name, but nodes which are accessed + * by bones (see #aiBone and #aiMesh::mBones) *must* be unique. + * + * Cameras and lights are assigned to a specific node name - if there + * are multiple nodes with this name, they're assigned to each of them. + */ C_STRUCT aiString mName; /** The transformation relative to the node's parent. */ @@ -137,7 +141,14 @@ struct aiNode */ inline aiNode* FindNode(const aiString& name) { - if (mName == name)return this; + return FindNode(name.data); + } + + /** @override + */ + inline aiNode* FindNode(const char* name) + { + if (!::strcmp( mName.data,name))return this; for (unsigned int i = 0; i < mNumChildren;++i) { aiNode* p = mChildren[i]->FindNode(name); @@ -151,7 +162,7 @@ struct aiNode }; -// --------------------------------------------------------------------------- +// ------------------------------------------------------------------------------- /** @def AI_SCENE_FLAGS_INCOMPLETE * Specifies that the scene data structure that was imported is not complete. * This flag bypasses some internal validations and allows the import @@ -203,12 +214,15 @@ struct aiNode */ #define AI_SCENE_FLAGS_TERRAIN 0x16 -// --------------------------------------------------------------------------- +// ------------------------------------------------------------------------------- /** The root structure of the imported data. -* -* Everything that was imported from the given file can be accessed from here. -*/ -// --------------------------------------------------------------------------- + * + * Everything that was imported from the given file can be accessed from here. + * Objects of this class are generally maintained and owned by Assimp, not + * by the caller. You shouldn't want to instance it, nor should you ever try to + * delete a given scene on your own. + */ +// ------------------------------------------------------------------------------- struct aiScene { diff --git a/include/aiVector3D.h b/include/aiVector3D.h index 598be9d8e..751f56e2a 100644 --- a/include/aiVector3D.h +++ b/include/aiVector3D.h @@ -92,7 +92,7 @@ public: * @param pY Y component * @param pZ Z component */ - void Set( float pX, float pY, float pZ); + void Set( float pX, float pY, float pZ = 0.f); /** @brief Get the squared length of the vector * @return Square length diff --git a/tools/assimp_view/AssetHelper.h b/tools/assimp_view/AssetHelper.h index 98047046d..37fa4593a 100644 --- a/tools/assimp_view/AssetHelper.h +++ b/tools/assimp_view/AssetHelper.h @@ -142,13 +142,13 @@ class AssetHelper piEffect (NULL), piVBNormals (NULL), piDiffuseTexture (NULL), - piDiffuseTexture2 (NULL), piSpecularTexture (NULL), piAmbientTexture (NULL), piNormalTexture (NULL), piEmissiveTexture (NULL), piOpacityTexture (NULL), piShininessTexture (NULL), + piLightmapTexture (NULL), pvOriginalNormals (NULL), bSharedFX(false) {} @@ -180,13 +180,13 @@ class AssetHelper // material textures IDirect3DTexture9* piDiffuseTexture; - IDirect3DTexture9* piDiffuseTexture2; IDirect3DTexture9* piSpecularTexture; IDirect3DTexture9* piAmbientTexture; IDirect3DTexture9* piEmissiveTexture; IDirect3DTexture9* piNormalTexture; IDirect3DTexture9* piOpacityTexture; IDirect3DTexture9* piShininessTexture; + IDirect3DTexture9* piLightmapTexture; // material colors D3DXVECTOR4 vDiffuseColor; diff --git a/tools/assimp_view/Background.cpp b/tools/assimp_view/Background.cpp index 07ee0afe4..f4f7a27b5 100644 --- a/tools/assimp_view/Background.cpp +++ b/tools/assimp_view/Background.cpp @@ -92,22 +92,23 @@ CBackgroundPainter CBackgroundPainter::s_cInstance; //------------------------------------------------------------------------------- void CBackgroundPainter::SetColor (D3DCOLOR p_clrNew) { - if (TEXTURE_CUBE == this->eMode)this->RemoveSBDeps(); + if (TEXTURE_CUBE == eMode) + RemoveSBDeps(); - this->clrColor = p_clrNew; - this->eMode = SIMPLE_COLOR; + clrColor = p_clrNew; + eMode = SIMPLE_COLOR; - if (this->pcTexture) + if (pcTexture) { - this->pcTexture->Release(); - this->pcTexture = NULL; + pcTexture->Release(); + pcTexture = NULL; } } //------------------------------------------------------------------------------- void CBackgroundPainter::RemoveSBDeps() { - MODE e = this->eMode; - this->eMode = SIMPLE_COLOR; + MODE e = eMode; + eMode = SIMPLE_COLOR; if (g_pcAsset && g_pcAsset->pcScene) { for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) @@ -120,36 +121,36 @@ void CBackgroundPainter::RemoveSBDeps() } } } - this->eMode = e; + eMode = e; } //------------------------------------------------------------------------------- void CBackgroundPainter::ResetSB() { - this->mMatrix = aiMatrix4x4(); + mMatrix = aiMatrix4x4(); } //------------------------------------------------------------------------------- void CBackgroundPainter::SetCubeMapBG (const char* p_szPath) { bool bHad = false; - if (this->pcTexture) + if (pcTexture) { - this->pcTexture->Release(); - this->pcTexture = NULL; - if(TEXTURE_CUBE ==this->eMode)bHad = true; + pcTexture->Release(); + pcTexture = NULL; + if(TEXTURE_CUBE ==eMode)bHad = true; } - this->eMode = TEXTURE_CUBE; + eMode = TEXTURE_CUBE; - this->szPath = std::string( p_szPath ); + szPath = std::string( p_szPath ); // ARRRGHH... ugly. TODO: Rewrite this! aiString sz; - sz.Set(this->szPath); + sz.Set(szPath); CMaterialManager::Instance().FindValidPath(&sz); - this->szPath = std::string( sz.data ); + szPath = std::string( sz.data ); // now recreate all native resources - this->RecreateNativeResource(); + RecreateNativeResource(); if (SIMPLE_COLOR != this->eMode) { @@ -188,35 +189,35 @@ void CBackgroundPainter::SetCubeMapBG (const char* p_szPath) //------------------------------------------------------------------------------- void CBackgroundPainter::RotateSB(const aiMatrix4x4* pm) { - this->mMatrix = this->mMatrix * (*pm); + this->mMatrix = mMatrix * (*pm); } //------------------------------------------------------------------------------- void CBackgroundPainter::SetTextureBG (const char* p_szPath) { if (TEXTURE_CUBE == this->eMode)this->RemoveSBDeps(); - if (this->pcTexture) + if (pcTexture) { - this->pcTexture->Release(); - this->pcTexture = NULL; + pcTexture->Release(); + pcTexture = NULL; } - this->eMode = TEXTURE_2D; - this->szPath = std::string( p_szPath ); + eMode = TEXTURE_2D; + szPath = std::string( p_szPath ); // ARRRGHH... ugly. TODO: Rewrite this! aiString sz; - sz.Set(this->szPath); + sz.Set(szPath); CMaterialManager::Instance().FindValidPath(&sz); - this->szPath = std::string( sz.data ); + szPath = std::string( sz.data ); // now recreate all native resources - this->RecreateNativeResource(); + RecreateNativeResource(); } //------------------------------------------------------------------------------- void CBackgroundPainter::OnPreRender() { - if (SIMPLE_COLOR != this->eMode) + if (SIMPLE_COLOR != eMode) { // clear the z-buffer only (in wireframe mode we must also clear // the color buffer ) @@ -230,7 +231,7 @@ void CBackgroundPainter::OnPreRender() g_piDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER,0,1.0f,0); } - if (TEXTURE_2D == this->eMode) + if (TEXTURE_2D == eMode) { RECT sRect; GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect); @@ -284,8 +285,8 @@ void CBackgroundPainter::OnPreRender() g_piDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2, &as,sizeof(SVertex)); - this->piSkyBoxEffect->EndPass(); - this->piSkyBoxEffect->End(); + piSkyBoxEffect->EndPass(); + piSkyBoxEffect->End(); g_piDevice->SetFVF(dw2); } @@ -293,12 +294,12 @@ void CBackgroundPainter::OnPreRender() } // clear both the render target and the z-buffer g_piDevice->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, - this->clrColor,1.0f,0); + clrColor,1.0f,0); } //------------------------------------------------------------------------------- void CBackgroundPainter::OnPostRender() { - if (TEXTURE_CUBE == this->eMode) + if (TEXTURE_CUBE == eMode) { aiMatrix4x4 pcProj; GetProjectionMatrix(pcProj); @@ -310,16 +311,16 @@ void CBackgroundPainter::OnPostRender() aiMe[3][0] = vPos.x; aiMe[3][1] = vPos.y; aiMe[3][2] = vPos.z; - aiMe = this->mMatrix * aiMe; + aiMe = mMatrix * aiMe; pcProj = (aiMe * pcCam) * pcProj; - this->piSkyBoxEffect->SetMatrix("WorldViewProjection", + piSkyBoxEffect->SetMatrix("WorldViewProjection", (const D3DXMATRIX*)&pcProj); UINT dwPasses; - this->piSkyBoxEffect->Begin(&dwPasses,0); - this->piSkyBoxEffect->BeginPass(0); + piSkyBoxEffect->Begin(&dwPasses,0); + piSkyBoxEffect->BeginPass(0); DWORD dw2; g_piDevice->GetFVF(&dw2); @@ -331,29 +332,29 @@ void CBackgroundPainter::OnPostRender() g_piDevice->SetFVF(dw2); - this->piSkyBoxEffect->EndPass(); - this->piSkyBoxEffect->End(); + piSkyBoxEffect->EndPass(); + piSkyBoxEffect->End(); } } //------------------------------------------------------------------------------- void CBackgroundPainter::ReleaseNativeResource() { - if (this->piSkyBoxEffect) + if ( piSkyBoxEffect) { - this->piSkyBoxEffect->Release(); - this->piSkyBoxEffect = NULL; + piSkyBoxEffect->Release(); + piSkyBoxEffect = NULL; } - if (this->pcTexture) + if (pcTexture) { - this->pcTexture->Release(); - this->pcTexture = NULL; + pcTexture->Release(); + pcTexture = NULL; } } //------------------------------------------------------------------------------- void CBackgroundPainter::RecreateNativeResource() { - if (SIMPLE_COLOR == this->eMode)return; - if (TEXTURE_CUBE == this->eMode) + if (SIMPLE_COLOR == eMode)return; + if (TEXTURE_CUBE == eMode) { // many skyboxes are 16bit FP format which isn't supported @@ -367,7 +368,7 @@ void CBackgroundPainter::RecreateNativeResource() if (FAILED(D3DXCreateCubeTextureFromFileEx( g_piDevice, - this->szPath.c_str(), + szPath.c_str(), D3DX_DEFAULT, 0, 0, @@ -378,11 +379,11 @@ void CBackgroundPainter::RecreateNativeResource() 0, NULL, NULL, - (IDirect3DCubeTexture9**)&this->pcTexture))) + (IDirect3DCubeTexture9**)&pcTexture))) { - const char* szEnd = strrchr(this->szPath.c_str(),'\\'); - if (!szEnd)szEnd = strrchr(this->szPath.c_str(),'/'); - if (!szEnd)szEnd = this->szPath.c_str()-1; + const char* szEnd = strrchr(szPath.c_str(),'\\'); + if (!szEnd)szEnd = strrchr(szPath.c_str(),'/'); + if (!szEnd)szEnd = szPath.c_str()-1; char szTemp[1024]; sprintf(szTemp,"[ERROR] Unable to load background cubemap %s",szEnd+1); @@ -390,7 +391,7 @@ void CBackgroundPainter::RecreateNativeResource() CLogDisplay::Instance().AddEntry(szTemp, D3DCOLOR_ARGB(0xFF,0xFF,0,0)); - this->eMode = SIMPLE_COLOR; + eMode = SIMPLE_COLOR; return; } else CLogDisplay::Instance().AddEntry("[OK] The skybox has been imported successfully", @@ -400,7 +401,7 @@ void CBackgroundPainter::RecreateNativeResource() { if (FAILED(D3DXCreateTextureFromFileEx( g_piDevice, - this->szPath.c_str(), + szPath.c_str(), D3DX_DEFAULT, D3DX_DEFAULT, 0, @@ -412,11 +413,11 @@ void CBackgroundPainter::RecreateNativeResource() 0, NULL, NULL, - (IDirect3DTexture9**)&this->pcTexture))) + (IDirect3DTexture9**)&pcTexture))) { - const char* szEnd = strrchr(this->szPath.c_str(),'\\'); - if (!szEnd)szEnd = strrchr(this->szPath.c_str(),'/'); - if (!szEnd)szEnd = this->szPath.c_str()-1; + const char* szEnd = strrchr(szPath.c_str(),'\\'); + if (!szEnd)szEnd = strrchr(szPath.c_str(),'/'); + if (!szEnd)szEnd = szPath.c_str()-1; char szTemp[1024]; sprintf(szTemp,"[ERROR] Unable to load background texture %s",szEnd+1); @@ -424,7 +425,7 @@ void CBackgroundPainter::RecreateNativeResource() CLogDisplay::Instance().AddEntry(szTemp, D3DCOLOR_ARGB(0xFF,0xFF,0,0)); - this->eMode = SIMPLE_COLOR; + eMode = SIMPLE_COLOR; return; } else CLogDisplay::Instance().AddEntry("[OK] The background texture has been imported successfully", @@ -440,7 +441,7 @@ void CBackgroundPainter::RecreateNativeResource() NULL, D3DXSHADER_USE_LEGACY_D3DX9_31_DLL, NULL, - &this->piSkyBoxEffect,NULL))) + &piSkyBoxEffect,NULL))) { CLogDisplay::Instance().AddEntry("[ERROR] Unable to compile skybox shader", D3DCOLOR_ARGB(0xFF,0xFF,0,0)); @@ -449,15 +450,15 @@ void CBackgroundPainter::RecreateNativeResource() } } // commit the correct textures to the shader - if (TEXTURE_CUBE == this->eMode) + if (TEXTURE_CUBE == eMode) { - this->piSkyBoxEffect->SetTexture("lw_tex_envmap",this->pcTexture); - this->piSkyBoxEffect->SetTechnique("RenderSkyBox"); + piSkyBoxEffect->SetTexture("lw_tex_envmap",pcTexture); + piSkyBoxEffect->SetTechnique("RenderSkyBox"); } - else if (TEXTURE_2D == this->eMode) + else if (TEXTURE_2D == eMode) { - this->piSkyBoxEffect->SetTexture("TEXTURE_2D",this->pcTexture); - this->piSkyBoxEffect->SetTechnique("RenderImage2D"); + piSkyBoxEffect->SetTexture("TEXTURE_2D",pcTexture); + piSkyBoxEffect->SetTechnique("RenderImage2D"); } } }; \ No newline at end of file diff --git a/tools/assimp_view/Display.cpp b/tools/assimp_view/Display.cpp index 2860c62eb..b91699839 100644 --- a/tools/assimp_view/Display.cpp +++ b/tools/assimp_view/Display.cpp @@ -447,16 +447,32 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType, break; case aiTextureType_HEIGHT: piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture; - szType = "HeightMap"; + szType = "Heightmap"; break; case aiTextureType_NORMALS: piTexture = &g_pcAsset->apcMeshes[iMesh]->piNormalTexture; - szType = "NormalMap"; + szType = "Normalmap"; break; case aiTextureType_SHININESS: piTexture = &g_pcAsset->apcMeshes[iMesh]->piShininessTexture; szType = "Shininess"; break; + case aiTextureType_LIGHTMAP: + piTexture = &g_pcAsset->apcMeshes[iMesh]->piLightmapTexture; + szType = "Lightmap"; + break; + case aiTextureType_DISPLACEMENT: + piTexture = NULL; + szType = "Displacement"; + break; + case aiTextureType_REFLECTION: + piTexture = NULL; + szType = "Reflection"; + break; + case aiTextureType_UNKNOWN: + piTexture = NULL; + szType = "Unknown"; + break; default: // opacity + opacity | mask piTexture = &g_pcAsset->apcMeshes[iMesh]->piOpacityTexture; szType = "Opacity"; @@ -491,19 +507,19 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType, if (0xFFFFFFFF == iData) { - tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; - tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; + tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; + tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; } else { - tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE]; - tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE]; + tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE]; + tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE]; } } else { - tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; - tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; + tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; + tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID]; } sNew.itemex = tvi; @@ -526,7 +542,7 @@ int CDisplay::AddTextureToDisplayList(unsigned int iType, sInfo.piTexture = piTexture; sInfo.iType = iType; sInfo.iMatIndex = g_pcAsset->pcScene->mMeshes[iMesh]->mMaterialIndex; - this->AddTexture(sInfo); + AddTexture(sInfo); return 1; } //------------------------------------------------------------------------------- @@ -565,8 +581,8 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot, tvi.pszText = chTemp; tvi.cchTextMax = (int)strlen(chTemp); tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_PARAM ; - tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_MATERIAL]; - tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_MATERIAL]; + tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL]; + tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL]; tvi.lParam = (LPARAM)10; //tvi.state = TVIS_EXPANDED | TVIS_EXPANDEDONCE ; @@ -581,14 +597,12 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot, (LPARAM)(LPTVINSERTSTRUCT)&sNew); // for each texture in the list ... add it - // NOTE: This expects that aiTextureType_DIFFUSE is 7 - ai_assert(7 == aiTextureType_DIFFUSE); unsigned int iUV; float fBlend; aiTextureOp eOp; aiString szPath; bool bNoOpacity = true; - for (unsigned int i = 0; i < 8;++i) + for (unsigned int i = 0; i <= AI_TEXTURE_TYPE_MAX;++i) { unsigned int iNum = 0; while (true) @@ -641,25 +655,25 @@ int CDisplay::ExpandTree() { // expand all materials for (std::vector< MaterialInfo >::iterator - i = this->m_asMaterials.begin(); - i != this->m_asMaterials.end();++i) + i = m_asMaterials.begin(); + i != m_asMaterials.end();++i) { TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),(*i).hTreeItem,TVE_EXPAND); } // expand all nodes for (std::vector< NodeInfo >::iterator - i = this->m_asNodes.begin(); - i != this->m_asNodes.end();++i) + i = m_asNodes.begin(); + i != m_asNodes.end();++i) { TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),(*i).hTreeItem,TVE_EXPAND); } - TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),this->m_hRoot,TVE_EXPAND); + TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),m_hRoot,TVE_EXPAND); return 1; } //------------------------------------------------------------------------------- int CDisplay::LoadImageList(void) { - if (!this->m_hImageList) + if (!m_hImageList) { // First, create the image list we will need. // FIX: Need RGB888 color space to display all colors correctly @@ -667,36 +681,36 @@ int CDisplay::LoadImageList(void) // Load the bitmaps and add them to the image lists. HBITMAP hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BFX)); - this->m_aiImageList[AI_VIEW_IMGLIST_MATERIAL] = ImageList_Add(hIml, hBmp, NULL); + m_aiImageList[AI_VIEW_IMGLIST_MATERIAL] = ImageList_Add(hIml, hBmp, NULL); DeleteObject(hBmp); hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BNODE)); - this->m_aiImageList[AI_VIEW_IMGLIST_NODE] = ImageList_Add(hIml, hBmp, NULL); + m_aiImageList[AI_VIEW_IMGLIST_NODE] = ImageList_Add(hIml, hBmp, NULL); DeleteObject(hBmp); hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BTX)); - this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE] = ImageList_Add(hIml, hBmp, NULL); + m_aiImageList[AI_VIEW_IMGLIST_TEXTURE] = ImageList_Add(hIml, hBmp, NULL); DeleteObject(hBmp); hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BTXI)); - this->m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID] = ImageList_Add(hIml, hBmp, NULL); + m_aiImageList[AI_VIEW_IMGLIST_TEXTURE_INVALID] = ImageList_Add(hIml, hBmp, NULL); DeleteObject(hBmp); hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BROOT)); - this->m_aiImageList[AI_VIEW_IMGLIST_MODEL] = ImageList_Add(hIml, hBmp, NULL); + m_aiImageList[AI_VIEW_IMGLIST_MODEL] = ImageList_Add(hIml, hBmp, NULL); DeleteObject(hBmp); // Associate the image list with the tree. TreeView_SetImageList(GetDlgItem(g_hDlg,IDC_TREE1), hIml, TVSIL_NORMAL); - this->m_hImageList = hIml; + m_hImageList = hIml; } return 1; } //------------------------------------------------------------------------------- int CDisplay::FillDisplayList(void) { - this->LoadImageList(); + LoadImageList(); // Initialize the tree view window. // fill in the first entry @@ -706,8 +720,8 @@ int CDisplay::FillDisplayList(void) tvi.cchTextMax = (int)strlen(tvi.pszText); tvi.mask = TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_HANDLE | TVIF_STATE; tvi.state = TVIS_EXPANDED; - tvi.iImage = this->m_aiImageList[AI_VIEW_IMGLIST_MODEL]; - tvi.iSelectedImage = this->m_aiImageList[AI_VIEW_IMGLIST_MODEL]; + tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_MODEL]; + tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_MODEL]; tvi.lParam = (LPARAM)0; sNew.itemex = tvi; @@ -715,22 +729,20 @@ int CDisplay::FillDisplayList(void) sNew.hParent = 0; // add the root item to the tree - this->m_hRoot = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1), + m_hRoot = (HTREEITEM)SendMessage(GetDlgItem(g_hDlg,IDC_TREE1), TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&sNew); // add each loaded material to the tree for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMaterials;++i) - { - AddMaterialToDisplayList(this->m_hRoot,i); - } + AddMaterialToDisplayList(m_hRoot,i); // now add all loaded nodes recursively - AddNodeToDisplayList(0,0,g_pcAsset->pcScene->mRootNode,this->m_hRoot); + AddNodeToDisplayList(0,0,g_pcAsset->pcScene->mRootNode,m_hRoot); // now expand all parent nodes in the tree - this->ExpandTree(); + ExpandTree(); // everything reacts a little bit slowly if D3D is rendering, // so give GDI a small hint to leave the couch and work ;-) @@ -743,23 +755,31 @@ int CDisplay::OnRender() // update possible animation if( g_pcAsset) { + static double lastPlaying = 0.; + ai_assert( g_pcAsset->mAnimator); - g_pcAsset->mAnimator->Calculate( double( clock()) / double( CLOCKS_PER_SEC)); + if (g_bPlay) { + + + g_dCurrent += clock()/ double( CLOCKS_PER_SEC) -lastPlaying; + g_pcAsset->mAnimator->Calculate( g_dCurrent ); + lastPlaying = g_dCurrent; + } } // begin the frame g_piDevice->BeginScene(); - switch (this->m_iViewMode) + switch (m_iViewMode) { case VIEWMODE_FULL: case VIEWMODE_NODE: - this->RenderFullScene(); + RenderFullScene(); break; case VIEWMODE_MATERIAL: - this->RenderMaterialView(); + RenderMaterialView(); break; case VIEWMODE_TEXTURE: - this->RenderTextureView(); + RenderTextureView(); break; }; @@ -841,13 +861,13 @@ int CDisplay::FillDefaultStatistics(void) int CDisplay::Reset(void) { // clear all lists - this->m_asMaterials.clear(); - this->m_asTextures.clear(); - this->m_asNodes.clear(); + m_asMaterials.clear(); + m_asTextures.clear(); + m_asNodes.clear(); - this->m_hRoot = NULL; + m_hRoot = NULL; - return this->OnSetupNormalView(); + return OnSetupNormalView(); } //------------------------------------------------------------------------------- void ShowNormalUIComponents() @@ -863,7 +883,7 @@ void ShowNormalUIComponents() //------------------------------------------------------------------------------- int CDisplay::OnSetupNormalView() { - if (VIEWMODE_NODE == this->m_iViewMode) + if (VIEWMODE_NODE == m_iViewMode) { ShowNormalUIComponents(); } @@ -877,13 +897,13 @@ int CDisplay::OnSetupNormalView() SetWindowText(GetDlgItem(g_hDlg,IDC_NUMMESHES),"Mesh:"); SetWindowText(GetDlgItem(g_hDlg,IDC_LOADTIME),"Time:"); - this->FillDefaultStatistics(); - this->SetViewMode(VIEWMODE_FULL); + FillDefaultStatistics(); + SetViewMode(VIEWMODE_FULL); // for debugging - this->m_pcCurrentMaterial = NULL; - this->m_pcCurrentTexture = NULL; - this->m_pcCurrentNode = NULL; + m_pcCurrentMaterial = NULL; + m_pcCurrentTexture = NULL; + m_pcCurrentNode = NULL; // redraw the color fields in the UI --- their purpose has possibly changed UpdateColorFieldsInUI(); @@ -895,7 +915,7 @@ int CDisplay::OnSetupNodeView(NodeInfo* pcNew) { ai_assert(NULL != pcNew); - if (this->m_pcCurrentNode == pcNew)return 2; + if (m_pcCurrentNode == pcNew)return 2; // now ... change the meaning of the statistics fields back SetWindowText(GetDlgItem(g_hDlg,IDC_NUMVERTS),"Verts:"); @@ -932,8 +952,8 @@ int CDisplay::OnSetupNodeView(NodeInfo* pcNew) SetWindowText(GetDlgItem(g_hDlg,IDC_VIEWMATRIX),szTemp); - this->m_pcCurrentNode = pcNew; - this->SetViewMode(VIEWMODE_NODE); + m_pcCurrentNode = pcNew; + SetViewMode(VIEWMODE_NODE); return 1; } @@ -942,16 +962,13 @@ int CDisplay::OnSetupMaterialView(MaterialInfo* pcNew) { ai_assert(NULL != pcNew); - if (this->m_pcCurrentMaterial == pcNew)return 2; + if (m_pcCurrentMaterial == pcNew)return 2; - if (VIEWMODE_NODE == this->m_iViewMode) - { + if (VIEWMODE_NODE == m_iViewMode) ShowNormalUIComponents(); - } - - this->m_pcCurrentMaterial = pcNew; - this->SetViewMode(VIEWMODE_MATERIAL); + m_pcCurrentMaterial = pcNew; + SetViewMode(VIEWMODE_MATERIAL); // redraw the color fields in the UI --- their purpose has possibly changed UpdateColorFieldsInUI(); @@ -1137,11 +1154,10 @@ int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem) // search in our list for the item TextureInfo* pcNew = NULL; for (std::vector::iterator - i = this->m_asTextures.begin(); - i != this->m_asTextures.end();++i) + i = m_asTextures.begin(); + i != m_asTextures.end();++i) { - if (hItem == (*i).hTreeItem) - { + if (hItem == (*i).hTreeItem) { pcNew = &(*i); break; } @@ -1150,18 +1166,15 @@ int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem) { HMENU hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_TXPOPUP)); hDisplay = GetSubMenu(hMenu,0); - - //this->OnSetupTextureView(pcNew); } // search in the material list for the item MaterialInfo* pcNew2 = NULL; for (std::vector::iterator - i = this->m_asMaterials.begin(); - i != this->m_asMaterials.end();++i) + i = m_asMaterials.begin(); + i != m_asMaterials.end();++i) { - if (hItem == (*i).hTreeItem) - { + if (hItem == (*i).hTreeItem) { pcNew2 = &(*i); break; } @@ -1170,8 +1183,6 @@ int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem) { HMENU hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MATPOPUP)); hDisplay = GetSubMenu(hMenu,0); - - //this->OnSetupMaterialView(pcNew2); } if (NULL != hDisplay) { @@ -1180,7 +1191,7 @@ int CDisplay::ShowTreeViewContextMenu(HTREEITEM hItem) // FIX: Render the scene once that the correct texture/material // is displayed while the context menu is active - this->OnRender(); + OnRender(); POINT sPoint; GetCursorPos(&sPoint); @@ -1245,7 +1256,7 @@ int CDisplay::HandleTreeViewPopup(WPARAM wParam,LPARAM lParam) default: // let the next function do this ... no spaghetti code ;-) - this->HandleTreeViewPopup2(wParam,lParam); + HandleTreeViewPopup2(wParam,lParam); }; if (!apclrOut.empty()) { @@ -1413,75 +1424,51 @@ int CDisplay::HandleTreeViewPopup2(WPARAM wParam,LPARAM lParam) { if(IDYES != MessageBox(g_hDlg,"To recover the texture you need to reload the model. Do you wish to continue?", - "Remove texture",MB_YESNO)) - { + "Remove texture",MB_YESNO)) { return 1; } Assimp::MaterialHelper* pcMat = (Assimp::MaterialHelper*)g_pcAsset->pcScene->mMaterials[ - this->m_pcCurrentTexture->iMatIndex]; + m_pcCurrentTexture->iMatIndex]; - switch (this->m_pcCurrentTexture->iType) + unsigned int s; + if (m_pcCurrentTexture->iType == (aiTextureType_OPACITY | 0x40000000)) { - case aiTextureType_DIFFUSE: - pcMat->RemoveProperty(AI_MATKEY_TEXTURE_DIFFUSE(0)); - break; - case aiTextureType_SPECULAR: - pcMat->RemoveProperty(AI_MATKEY_TEXTURE_SPECULAR(0)); - break; - case aiTextureType_AMBIENT: - pcMat->RemoveProperty(AI_MATKEY_TEXTURE_AMBIENT(0)); - break; - case aiTextureType_EMISSIVE: - pcMat->RemoveProperty(AI_MATKEY_TEXTURE_EMISSIVE(0)); - break; - case aiTextureType_NORMALS: - pcMat->RemoveProperty(AI_MATKEY_TEXTURE_NORMALS(0)); - break; - case aiTextureType_HEIGHT: - pcMat->RemoveProperty(AI_MATKEY_TEXTURE_HEIGHT(0)); - break; - case aiTextureType_SHININESS: - pcMat->RemoveProperty(AI_MATKEY_TEXTURE_SHININESS(0)); - break; - case (aiTextureType_OPACITY | 0x40000000): - // set a special property to indicate that no alpha channel is required - {int iVal = 1; - pcMat->AddProperty(&iVal,1,"no_a_from_d",0,0);} - - break; - default: //case aiTextureType_OPACITY - pcMat->RemoveProperty(AI_MATKEY_TEXTURE_OPACITY(0)); - }; + int iVal = 1; + pcMat->AddProperty(&iVal,1,"no_a_from_d",0,0); + s = aiTextureType_OPACITY; + } + else s = m_pcCurrentTexture->iType; + pcMat->RemoveProperty(AI_MATKEY_TEXTURE(m_pcCurrentTexture->iType,0)); // need to update all meshes associated with this material for (unsigned int i = 0;i < g_pcAsset->pcScene->mNumMeshes;++i) { - if (this->m_pcCurrentTexture->iMatIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) + if (m_pcCurrentTexture->iMatIndex == g_pcAsset->pcScene->mMeshes[i]->mMaterialIndex) { CMaterialManager::Instance().DeleteMaterial(g_pcAsset->apcMeshes[i]); CMaterialManager::Instance().CreateMaterial(g_pcAsset->apcMeshes[i],g_pcAsset->pcScene->mMeshes[i]); } } // find the corresponding MaterialInfo structure - const unsigned int iMatIndex = this->m_pcCurrentTexture->iMatIndex; + const unsigned int iMatIndex = m_pcCurrentTexture->iMatIndex; for (std::vector::iterator - a = this->m_asMaterials.begin(); - a != this->m_asMaterials.end();++a) + a = m_asMaterials.begin(); + a != m_asMaterials.end();++a) { if (iMatIndex == (*a).iIndex) { // good news. we will also need to find all other textures // associated with this item ... for (std::vector::iterator - n = this->m_asTextures.begin(); - n != this->m_asTextures.end();++n) + n = m_asTextures.begin(); + n != m_asTextures.end();++n) { if ((*n).iMatIndex == iMatIndex) { - n = this->m_asTextures.erase(n); - if (this->m_asTextures.end() == n)break; + n = m_asTextures.erase(n); + if (m_asTextures.end() == n)break; } } // delete this material from all lists ... @@ -1492,58 +1479,22 @@ int CDisplay::HandleTreeViewPopup2(WPARAM wParam,LPARAM lParam) } // add the new material to the list and make sure it will be fully expanded - AddMaterialToDisplayList(this->m_hRoot,iMatIndex); - HTREEITEM hNewItem = this->m_asMaterials.back().hTreeItem; + AddMaterialToDisplayList(m_hRoot,iMatIndex); + HTREEITEM hNewItem = m_asMaterials.back().hTreeItem; TreeView_Expand(GetDlgItem(g_hDlg,IDC_TREE1),hNewItem,TVE_EXPAND); // we need to sort the list, materials come first, then nodes TVSORTCB sSort; - sSort.hParent = this->m_hRoot; + sSort.hParent = m_hRoot; sSort.lParam = 10; sSort.lpfnCompare = &TreeViewCompareFunc; TreeView_SortChildrenCB(GetDlgItem(g_hDlg,IDC_TREE1),&sSort,0); // the texture was selected, but the silly user has just deleted it // ... go back to normal viewing mode - TreeView_Select(GetDlgItem(g_hDlg,IDC_TREE1),this->m_hRoot,TVGN_CARET); + TreeView_Select(GetDlgItem(g_hDlg,IDC_TREE1),m_hRoot,TVGN_CARET); return 1; } -#if 0 - case ID_HEY_RESETTEXTURE: - { - aiString szOld; - aiMaterial* pcMat = g_pcAsset->pcScene->mMaterials[this->m_pcCurrentTexture->iMatIndex]; - switch (this->m_pcCurrentTexture->iType) - { - case aiTextureType_DIFFUSE: - aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_DIFFUSE(0) "_old",&szOld); - break; - case aiTextureType_SPECULAR: - aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SPECULAR(0) "_old",&szOld); - break; - case aiTextureType_AMBIENT: - aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_AMBIENT(0) "_old",&szOld); - break; - case aiTextureType_EMISSIVE: - aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_EMISSIVE(0) "_old",&szOld); - break; - case aiTextureType_NORMALS: - aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_NORMALS(0) "_old",&szOld); - break; - case aiTextureType_HEIGHT: - aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_HEIGHT(0) "_old",&szOld); - break; - case aiTextureType_SHININESS: - aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_SHININESS(0) "_old",&szOld); - break; - default : //case aiTextureType_OPACITY && case aiTextureType_OPACITY | 0x40000000: - aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_OPACITY(0) "_old",&szOld); - break; - }; - if (0 != szOld.length)this->ReplaceCurrentTexture(szOld.data); - return 1; - } -#endif } return 0; } @@ -1767,37 +1718,35 @@ int CDisplay::RenderFullScene() // reset the color index used for drawing normals g_iCurrentColor = 0; - // reset frame counter and rotation tracker - CMeshRenderer::Instance().OnBeginFrame(); - // setup wireframe/solid rendering mode if (g_sOptions.eDrawMode == RenderOptions::WIREFRAME) - { g_piDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); - } else g_piDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID); + if (g_sOptions.bCulling) + g_piDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW); + else g_piDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); + // draw the scene background (clear and texture 2d) CBackgroundPainter::Instance().OnPreRender(); // setup the stereo view if necessary if (g_sOptions.bStereoView) - { - this->SetupStereoView(); - } + SetupStereoView(); + // draw all opaque objects in the scene aiMatrix4x4 m; if (NULL != g_pcAsset && NULL != g_pcAsset->pcScene->mRootNode) { - this->HandleInput(); + HandleInput(); m = g_mWorld * g_mWorldRotate; RenderNode(g_pcAsset->pcScene->mRootNode,m,false); } // if a cube texture is loaded as background image, the user // should be able to rotate it even if no asset is loaded - this->HandleInputEmptyScene(); + HandleInputEmptyScene(); // draw the scene background CBackgroundPainter::Instance().OnPostRender(); @@ -1813,16 +1762,14 @@ int CDisplay::RenderFullScene() // setup the stereo view if necessary if (g_sOptions.bStereoView) - { - this->RenderStereoView(m); - } + RenderStereoView(m); + // draw the HUD texture on top of the rendered scene using // pre-projected vertices if (!g_bFPSView && g_pcAsset && g_pcTexture) - { - this->DrawHUD(); - } + DrawHUD(); + return 1; } //------------------------------------------------------------------------------- @@ -1832,25 +1779,25 @@ int CDisplay::RenderMaterialView() } //------------------------------------------------------------------------------- int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix, - bool bAlpha /*= false*/) + bool bAlpha /*= false*/) { - aiMatrix4x4 aiMe = g_pcAsset->mAnimator->GetGlobalTransform( piNode->mName.data); + aiMatrix4x4 aiMe = g_pcAsset->mAnimator->GetGlobalTransform( piNode); + aiMe.Transpose(); aiMe *= piMatrix; bool bChangedVM = false; - if (VIEWMODE_NODE == this->m_iViewMode && this->m_pcCurrentNode) + if (VIEWMODE_NODE == m_iViewMode && m_pcCurrentNode) { - if (piNode != this->m_pcCurrentNode->psNode) + if (piNode != m_pcCurrentNode->psNode) { // directly call our children for (unsigned int i = 0; i < piNode->mNumChildren;++i) - { RenderNode(piNode->mChildren[i],piMatrix,bAlpha ); - } + return 1; } - this->m_iViewMode = VIEWMODE_FULL; + m_iViewMode = VIEWMODE_FULL; bChangedVM = true; } @@ -1957,19 +1904,20 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix, { g_iCurrentColor = 0; } - if (! (!g_sOptions.bRenderMats && bAlpha)) + if (! (!g_sOptions.bRenderMats && bAlpha )) { for (unsigned int i = 0; i < piNode->mNumMeshes;++i) { const aiMesh* mesh = g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]; AssetHelper::MeshHelper* helper = g_pcAsset->apcMeshes[piNode->mMeshes[i]]; + // fix: Render triangle meshes only if (mesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) continue; // don't render the mesh if the render pass is incorrect - if (g_sOptions.bRenderMats && (helper->piOpacityTexture || helper->fOpacity != 1.0f)) + if (g_sOptions.bRenderMats && (helper->piOpacityTexture || helper->fOpacity != 1.0f) && !mesh->HasBones()) { if (!bAlpha)continue; } @@ -2061,12 +2009,11 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix, } // render all child nodes for (unsigned int i = 0; i < piNode->mNumChildren;++i) - { RenderNode(piNode->mChildren[i],piMatrix,bAlpha ); - } + // need to reset the viewmode? if (bChangedVM) - this->m_iViewMode = VIEWMODE_NODE; + m_iViewMode = VIEWMODE_NODE; return 1; } //------------------------------------------------------------------------------- @@ -2118,8 +2065,8 @@ int CDisplay::RenderPatternBG() D3DCOLOR_ARGB(0xFF,0xFF,0,0xFF), 1.0f,0 ); // setup the colors to be used ... - g_piPatternEffect->SetVector("COLOR_ONE",&this->m_avCheckerColors[0]); - g_piPatternEffect->SetVector("COLOR_TWO",&this->m_avCheckerColors[1]); + g_piPatternEffect->SetVector("COLOR_ONE",&m_avCheckerColors[0]); + g_piPatternEffect->SetVector("COLOR_TWO",&m_avCheckerColors[1]); // setup the shader UINT dw; @@ -2179,10 +2126,10 @@ int CDisplay::RenderTextureView() this->HandleInputTextureView(); // render the background - this->RenderPatternBG(); + RenderPatternBG(); // it might be that there is no texture ... - if (!this->m_pcCurrentTexture->piTexture) + if (!m_pcCurrentTexture->piTexture) { // FIX: no such log message. it would be repeated to often //CLogDisplay::Instance().AddEntry("Unable to display texture. Image is unreachable.", @@ -2197,27 +2144,27 @@ int CDisplay::RenderTextureView() sRect.bottom -= sRect.top; // commit the texture to the shader - g_piPassThroughEffect->SetTexture("TEXTURE_2D",*this->m_pcCurrentTexture->piTexture); + g_piPassThroughEffect->SetTexture("TEXTURE_2D",*m_pcCurrentTexture->piTexture); - if (aiTextureType_OPACITY == this->m_pcCurrentTexture->iType) + if (aiTextureType_OPACITY == m_pcCurrentTexture->iType) { g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromR"); } - else if ((aiTextureType_OPACITY | 0x40000000) == this->m_pcCurrentTexture->iType) + else if ((aiTextureType_OPACITY | 0x40000000) == m_pcCurrentTexture->iType) { g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromA"); } else if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0)) - g_piPassThroughEffect->SetTechnique( "PassThrough_FF"); - else - g_piPassThroughEffect->SetTechnique("PassThrough"); + g_piPassThroughEffect->SetTechnique( "PassThrough_FF"); + else + g_piPassThroughEffect->SetTechnique("PassThrough"); UINT dw; g_piPassThroughEffect->Begin(&dw,0); g_piPassThroughEffect->BeginPass(0); - if (aiTextureType_HEIGHT == this->m_pcCurrentTexture->iType || - aiTextureType_NORMALS == this->m_pcCurrentTexture->iType) + if (aiTextureType_HEIGHT == m_pcCurrentTexture->iType || + aiTextureType_NORMALS == m_pcCurrentTexture->iType) { // manually disable alpha blending g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE); @@ -2235,30 +2182,30 @@ int CDisplay::RenderTextureView() const float ny = (float)sRect.bottom; const float x = (float)sDesc.Width; const float y = (float)sDesc.Height; - float f = std::min((nx-30) / x,(ny-30) / y) * (this->m_fTextureZoom/1000.0f); + float f = std::min((nx-30) / x,(ny-30) / y) * (m_fTextureZoom/1000.0f); float fHalfX = (nx - (f * x)) / 2.0f; float fHalfY = (ny - (f * y)) / 2.0f; - as[1].x = fHalfX + this->m_vTextureOffset.x; - as[1].y = fHalfY + this->m_vTextureOffset.y; + as[1].x = fHalfX + m_vTextureOffset.x; + as[1].y = fHalfY + m_vTextureOffset.y; as[1].z = 0.2f; as[1].w = 1.0f; as[1].u = 0.0f; as[1].v = 0.0f; - as[3].x = nx-fHalfX + this->m_vTextureOffset.x; - as[3].y = fHalfY + this->m_vTextureOffset.y; + as[3].x = nx-fHalfX + m_vTextureOffset.x; + as[3].y = fHalfY + m_vTextureOffset.y; as[3].z = 0.2f; as[3].w = 1.0f; as[3].u = 1.0f; as[3].v = 0.0f; - as[0].x = fHalfX + this->m_vTextureOffset.x; - as[0].y = ny-fHalfY + this->m_vTextureOffset.y; + as[0].x = fHalfX + m_vTextureOffset.x; + as[0].y = ny-fHalfY + m_vTextureOffset.y; as[0].z = 0.2f; as[0].w = 1.0f; as[0].u = 0.0f; as[0].v = 1.0f; - as[2].x = nx-fHalfX + this->m_vTextureOffset.x; - as[2].y = ny-fHalfY + this->m_vTextureOffset.y; + as[2].x = nx-fHalfX + m_vTextureOffset.x; + as[2].y = ny-fHalfY + m_vTextureOffset.y; as[2].z = 0.2f; as[2].w = 1.0f; as[2].u = 1.0f; diff --git a/tools/assimp_view/Input.cpp b/tools/assimp_view/Input.cpp index aa3b89298..92c04e1c2 100644 --- a/tools/assimp_view/Input.cpp +++ b/tools/assimp_view/Input.cpp @@ -71,8 +71,6 @@ void HandleMouseInputFPS( void ) D3DXMatrixRotationAxis( &matRotation, (D3DXVECTOR3*)& g_sCamera.vRight, D3DXToRadian((float)nYDiff / 6.0f)); D3DXVec3TransformCoord( (D3DXVECTOR3*)&g_sCamera.vLookAt, (D3DXVECTOR3*)& g_sCamera.vLookAt, &matRotation ); D3DXVec3TransformCoord( (D3DXVECTOR3*)&g_sCamera.vUp, (D3DXVECTOR3*)&g_sCamera.vUp, &matRotation ); - - CMeshRenderer::Instance().SetRotationChangedFlag(); } if( 0 != nXDiff ) @@ -81,8 +79,6 @@ void HandleMouseInputFPS( void ) D3DXMatrixRotationAxis( &matRotation, (D3DXVECTOR3*)&g_sCamera.vUp, D3DXToRadian((float)nXDiff / 6.0f) ); D3DXVec3TransformCoord( (D3DXVECTOR3*)&g_sCamera.vLookAt, (D3DXVECTOR3*)&g_sCamera.vLookAt, &matRotation ); D3DXVec3TransformCoord( (D3DXVECTOR3*)&g_sCamera.vRight,(D3DXVECTOR3*) &g_sCamera.vRight, &matRotation ); - - CMeshRenderer::Instance().SetRotationChangedFlag(); } } @@ -256,8 +252,6 @@ void HandleMouseInputLocal( void ) aiVector3D v = aiVector3D(1.0f,0.0f,0.0f); D3DXMatrixRotationAxis( (D3DXMATRIX*) &matWorld, (D3DXVECTOR3*)&v, D3DXToRadian((float)nYDiff / 2.0f)); g_mWorldRotate = g_mWorldRotate * matWorld; - - CMeshRenderer::Instance().SetRotationChangedFlag(); } if( 0 != nXDiff && g_eClick != EClickPos_CircleVert) @@ -265,8 +259,6 @@ void HandleMouseInputLocal( void ) aiVector3D v = aiVector3D(0.0f,1.0f,0.0f); D3DXMatrixRotationAxis( (D3DXMATRIX*)&matWorld, (D3DXVECTOR3*)&v, D3DXToRadian((float)nXDiff / 2.0f) ); g_mWorldRotate = g_mWorldRotate * matWorld; - - CMeshRenderer::Instance().SetRotationChangedFlag(); } } else @@ -353,9 +345,6 @@ void HandleKeyboardInputFPS( void ) // End Key - View elevates down if( keys[VK_END] & 0x80 ) g_sCamera.vPos.y -= MOVE_SPEED*g_fElpasedTime; - - if (vOldPos != g_sCamera.vPos) - CMeshRenderer::Instance().SetRotationChangedFlag(); } diff --git a/tools/assimp_view/Material.cpp b/tools/assimp_view/Material.cpp index efb30a855..d73a3ac20 100644 --- a/tools/assimp_view/Material.cpp +++ b/tools/assimp_view/Material.cpp @@ -455,6 +455,11 @@ void CMaterialManager::DeleteMaterial(AssetHelper::MeshHelper* pcIn) pcIn->piShininessTexture->Release(); pcIn->piShininessTexture = NULL; } + if (pcIn->piLightmapTexture) + { + pcIn->piLightmapTexture->Release(); + pcIn->piLightmapTexture = NULL; + } } //------------------------------------------------------------------------------- void CMaterialManager::HMtoNMIfNecessary( @@ -803,17 +808,6 @@ int CMaterialManager::CreateMaterial( aiGetMaterialInteger(pcMat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV); } - if (pcSource->mTextureCoords[1]) - { - // - // DIFFUSE TEXTURE2 ------------------------------------------------ - // - if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_DIFFUSE(1),&szPath)) - { - LoadTexture(&pcMesh->piDiffuseTexture2,&szPath); - } - } - // // SPECULAR TEXTURE ------------------------------------------------ // @@ -871,6 +865,15 @@ int CMaterialManager::CreateMaterial( LoadTexture(&pcMesh->piShininessTexture,&szPath); } + // + // Lightmap TEXTURE ------------------------------------------------ + // + if(AI_SUCCESS == aiGetMaterialString(pcMat,AI_MATKEY_TEXTURE_LIGHTMAP(0),&szPath)) + { + LoadTexture(&pcMesh->piLightmapTexture,&szPath); + } + + // // NORMAL/HEIGHT MAP ------------------------------------------------ // @@ -926,9 +929,6 @@ int CMaterialManager::CreateMaterial( if ((pcMesh->piDiffuseTexture != NULL ? true : false) != (pc->piDiffuseTexture != NULL ? true : false)) continue; - if ((pcMesh->piDiffuseTexture2 != NULL ? true : false) != - (pc->piDiffuseTexture2 != NULL ? true : false)) - continue; if ((pcMesh->piSpecularTexture != NULL ? true : false) != (pc->piSpecularTexture != NULL ? true : false)) continue; @@ -947,6 +947,9 @@ int CMaterialManager::CreateMaterial( if ((pcMesh->piShininessTexture != NULL ? true : false) != (pc->piShininessTexture != NULL ? true : false)) continue; + if ((pcMesh->piLightmapTexture != NULL ? true : false) != + (pc->piLightmapTexture != NULL ? true : false)) + continue; if ((pcMesh->eShadingMode != aiShadingMode_Gouraud ? true : false) != (pc->eShadingMode != aiShadingMode_Gouraud ? true : false)) continue; @@ -998,12 +1001,6 @@ int CMaterialManager::CreateMaterial( sMacro[iCurrent].Definition = "1"; ++iCurrent; } - if (pcMesh->piDiffuseTexture2) - { - sMacro[iCurrent].Name = "AV_DIFFUSE_TEXTURE2"; - sMacro[iCurrent].Definition = "1"; - ++iCurrent; - } if (pcMesh->piSpecularTexture) { sMacro[iCurrent].Name = "AV_SPECULAR_TEXTURE"; @@ -1022,6 +1019,16 @@ int CMaterialManager::CreateMaterial( sMacro[iCurrent].Definition = "1"; ++iCurrent; } + if (pcMesh->piLightmapTexture) + { + sMacro[iCurrent].Name = "AV_LIGHTMAP_TEXTURE"; + sMacro[iCurrent].Definition = "1"; + ++iCurrent; + + sMacro[iCurrent].Name = "AV_LIGHTMAP_TEXTURE_UV_COORD"; + sMacro[iCurrent].Definition = "IN.TexCoord0"; + ++iCurrent; + } if (pcMesh->piNormalTexture && !bib) { sMacro[iCurrent].Name = "AV_NORMAL_TEXTURE"; @@ -1148,8 +1155,6 @@ int CMaterialManager::CreateMaterial( if (pcMesh->piDiffuseTexture) pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE",pcMesh->piDiffuseTexture); - if (pcMesh->piDiffuseTexture2) - pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE2",pcMesh->piDiffuseTexture2); if (pcMesh->piOpacityTexture) pcMesh->piEffect->SetTexture("OPACITY_TEXTURE",pcMesh->piOpacityTexture); if (pcMesh->piSpecularTexture) @@ -1162,6 +1167,8 @@ int CMaterialManager::CreateMaterial( pcMesh->piEffect->SetTexture("NORMAL_TEXTURE",pcMesh->piNormalTexture); if (pcMesh->piShininessTexture) pcMesh->piEffect->SetTexture("SHININESS_TEXTURE",pcMesh->piShininessTexture); + if (pcMesh->piLightmapTexture) + pcMesh->piEffect->SetTexture("LIGHTMAP_TEXTURE",pcMesh->piLightmapTexture); if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) { @@ -1270,8 +1277,6 @@ int CMaterialManager::SetupMaterial ( pcMesh->piEffect->SetTexture("OPACITY_TEXTURE",pcMesh->piOpacityTexture); if (pcMesh->piDiffuseTexture) pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE",pcMesh->piDiffuseTexture); - if (pcMesh->piDiffuseTexture2) - pcMesh->piEffect->SetTexture("DIFFUSE_TEXTURE2",pcMesh->piDiffuseTexture2); if (pcMesh->piSpecularTexture) pcMesh->piEffect->SetTexture("SPECULAR_TEXTURE",pcMesh->piSpecularTexture); if (pcMesh->piAmbientTexture) @@ -1282,6 +1287,8 @@ int CMaterialManager::SetupMaterial ( pcMesh->piEffect->SetTexture("NORMAL_TEXTURE",pcMesh->piNormalTexture); if (pcMesh->piShininessTexture) pcMesh->piEffect->SetTexture("SHININESS_TEXTURE",pcMesh->piShininessTexture); + if (pcMesh->piLightmapTexture) + pcMesh->piEffect->SetTexture("LIGHTMAP_TEXTURE",pcMesh->piLightmapTexture); if (CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode()) { diff --git a/tools/assimp_view/MeshRenderer.cpp b/tools/assimp_view/MeshRenderer.cpp index 64575da07..f3730dc11 100644 --- a/tools/assimp_view/MeshRenderer.cpp +++ b/tools/assimp_view/MeshRenderer.cpp @@ -76,75 +76,69 @@ int CMeshRenderer::DrawSorted(unsigned int iIndex,const aiMatrix4x4& mWorld) AssetHelper::MeshHelper* pcHelper = g_pcAsset->apcMeshes[iIndex]; const aiMesh* pcMesh = g_pcAsset->pcScene->mMeshes[iIndex]; - // only resort the tree of the rotation/position of the object - // or camera have been changed - if (this->m_bRotationChanged) + if (pcMesh->HasBones()) + return DrawUnsorted(iIndex); + + // compute the position of the camera in worldspace + aiMatrix4x4 mWorldInverse = mWorld; + mWorldInverse.Inverse(); + mWorldInverse.Transpose(); + const aiVector3D vLocalCamera = mWorldInverse * g_sCamera.vPos; + + // well ... this is really funny now. We must compute their distance + // from the camera. We take the average distance of a face and add it + // to a map which sorts it + std::map > smap; + + for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) { - if (AI_VIEW_ALPHA_SORT_DELTA == ++this->m_iFrameCount) + const aiFace* pcFace = &pcMesh->mFaces[iFace]; + float fDist = 0.0f; + for (unsigned int c = 0; c < 3;++c) { - this->m_iFrameCount = 0; + aiVector3D vPos = pcMesh->mVertices[pcFace->mIndices[c]]; + vPos -= vLocalCamera; + fDist += vPos.SquareLength(); + } + smap.insert(std::pair(fDist,iFace)); + } - // compute the position of the camera in worldspace - aiMatrix4x4 mWorldInverse = mWorld; - mWorldInverse.Inverse(); - mWorldInverse.Transpose(); - const aiVector3D vLocalCamera = mWorldInverse * g_sCamera.vPos; + // now we can lock the index buffer and rebuild it + D3DINDEXBUFFER_DESC sDesc; + pcHelper->piIB->GetDesc(&sDesc); - // well ... this is really funny now. We must compute their distance - // from the camera. We take the average distance of a face and add it - // to a map which sorts it - std::map > smap; + if (D3DFMT_INDEX16 == sDesc.Format) + { + uint16_t* aiIndices; + pcHelper->piIB->Lock(0,0,(void**)&aiIndices,D3DLOCK_DISCARD); - for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) - { - const aiFace* pcFace = &pcMesh->mFaces[iFace]; - float fDist = 0.0f; - for (unsigned int c = 0; c < 3;++c) - { - aiVector3D vPos = pcMesh->mVertices[pcFace->mIndices[c]]; - vPos -= vLocalCamera; - fDist += vPos.SquareLength(); - } - smap.insert(std::pair(fDist,iFace)); - } - - // now we can lock the index buffer and rebuild it - D3DINDEXBUFFER_DESC sDesc; - pcHelper->piIB->GetDesc(&sDesc); - - if (D3DFMT_INDEX16 == sDesc.Format) - { - uint16_t* aiIndices; - pcHelper->piIB->Lock(0,0,(void**)&aiIndices,D3DLOCK_DISCARD); - - for (std::map >::const_iterator - i = smap.begin(); - i != smap.end();++i) - { - const aiFace* pcFace = &pcMesh->mFaces[(*i).second]; - *aiIndices++ = (uint16_t)pcFace->mIndices[0]; - *aiIndices++ = (uint16_t)pcFace->mIndices[1]; - *aiIndices++ = (uint16_t)pcFace->mIndices[2]; - } - } - else if (D3DFMT_INDEX32 == sDesc.Format) - { - uint32_t* aiIndices; - pcHelper->piIB->Lock(0,0,(void**)&aiIndices,D3DLOCK_DISCARD); - - for (std::map >::const_iterator - i = smap.begin(); - i != smap.end();++i) - { - const aiFace* pcFace = &pcMesh->mFaces[(*i).second]; - *aiIndices++ = (uint32_t)pcFace->mIndices[0]; - *aiIndices++ = (uint32_t)pcFace->mIndices[1]; - *aiIndices++ = (uint32_t)pcFace->mIndices[2]; - } - } - pcHelper->piIB->Unlock(); + for (std::map >::const_iterator + i = smap.begin(); + i != smap.end();++i) + { + const aiFace* pcFace = &pcMesh->mFaces[(*i).second]; + *aiIndices++ = (uint16_t)pcFace->mIndices[0]; + *aiIndices++ = (uint16_t)pcFace->mIndices[1]; + *aiIndices++ = (uint16_t)pcFace->mIndices[2]; } } + else if (D3DFMT_INDEX32 == sDesc.Format) + { + uint32_t* aiIndices; + pcHelper->piIB->Lock(0,0,(void**)&aiIndices,D3DLOCK_DISCARD); + + for (std::map >::const_iterator + i = smap.begin(); + i != smap.end();++i) + { + const aiFace* pcFace = &pcMesh->mFaces[(*i).second]; + *aiIndices++ = (uint32_t)pcFace->mIndices[0]; + *aiIndices++ = (uint32_t)pcFace->mIndices[1]; + *aiIndices++ = (uint32_t)pcFace->mIndices[2]; + } + } + pcHelper->piIB->Unlock(); + // set vertex and index buffer g_piDevice->SetStreamSource(0,pcHelper->piVB,0,sizeof(AssetHelper::Vertex)); diff --git a/tools/assimp_view/MeshRenderer.h b/tools/assimp_view/MeshRenderer.h index b4617627f..bc074974e 100644 --- a/tools/assimp_view/MeshRenderer.h +++ b/tools/assimp_view/MeshRenderer.h @@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AV_MESH_RENDERER_H_INCLUDED -#define AI_VIEW_ALPHA_SORT_DELTA 3 //------------------------------------------------------------------------------- /* Helper class tp render meshes @@ -55,8 +54,7 @@ private: // default constructor CMeshRenderer() - : m_bRotationChanged(true), - m_iFrameCount(AI_VIEW_ALPHA_SORT_DELTA-1) + { // no other members to initialize } @@ -90,43 +88,10 @@ public: const aiMatrix4x4& mWorld); - //------------------------------------------------------------------ - // Indicate that the rotation of the object or the camera has - // been changed, thus the alpha order tree must be updated - inline void SetRotationChangedFlag() - { - this->m_bRotationChanged = true; - } - - //------------------------------------------------------------------ - // Reset the state of the class - // Called whenever a new asset is loaded - inline void Reset() - { - this->m_bRotationChanged = true; - this->m_iFrameCount = 2; - } - - //------------------------------------------------------------------ - // Called at the beginning of the frame. Reset the state - // of the instance - inline void OnBeginFrame() - { - if (0 == this->m_iFrameCount) - { - this->m_bRotationChanged = false; - } - } private: - // true if the rotation of the object or camera has changed - // in the last frame. If there were no changes it should - // not be necessary to update the alpha ordering tree - bool m_bRotationChanged; - - // only update the alpha order each AI_VIEW_ALPHA_SORT_DELTA frames - unsigned int m_iFrameCount; + }; #endif //!! include guard \ No newline at end of file diff --git a/tools/assimp_view/MessageProc.cpp b/tools/assimp_view/MessageProc.cpp index b1a92f743..534b312f5 100644 --- a/tools/assimp_view/MessageProc.cpp +++ b/tools/assimp_view/MessageProc.cpp @@ -80,102 +80,15 @@ void MakeFileAssociations() HKEY g_hRegistry; - // ------------------------------------------------- - // .3ds - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.3ds",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); + aiString list; + aiGetExtensionList(&list); - // ------------------------------------------------- - // .x - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.x",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - // ------------------------------------------------- - // .obj - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.obj",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - // ------------------------------------------------- - // .ms3d - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ms3d",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - // ------------------------------------------------- - // .md3 - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md3",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - // ------------------------------------------------- - // .md2 - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md2",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - // ------------------------------------------------- - // .md4/mdr - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md4",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.mdr",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - // ------------------------------------------------- - // .md5 - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md5mesh",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.md5anim",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - // ------------------------------------------------- - // .mdl - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.mdl",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - // ------------------------------------------------- - // .lwo - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.lwo",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - - // ------------------------------------------------- - // .ply - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ply",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - - - // ------------------------------------------------- - // .ase/.ask - // ------------------------------------------------- - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ase",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); - RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.ask",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); - RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); - RegCloseKey(g_hRegistry); + while (1) + { + RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\.3ds",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); + RegSetValueEx(g_hRegistry,"",0,REG_SZ,(const BYTE*)"ASSIMPVIEW_CLASS",(DWORD)strlen("ASSIMPVIEW_CLASS")+1); + RegCloseKey(g_hRegistry); + } RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Classes\\ASSIMPVIEW_CLASS",NULL,NULL,0,KEY_ALL_ACCESS, NULL, &g_hRegistry,NULL); RegCloseKey(g_hRegistry); @@ -398,6 +311,31 @@ void ToggleMats() UpdateWindow(g_hDlg); } +//------------------------------------------------------------------------------- +// Toggle the "Culling" state +//------------------------------------------------------------------------------- +void ToggleCulling() +{ + g_sOptions.bCulling = !g_sOptions.bCulling; + + // store this in the registry, too + DWORD dwValue = 0; + if (g_sOptions.bCulling)dwValue = 1; + RegSetValueExA(g_hRegistry,"Culling",0,REG_DWORD,(const BYTE*)&dwValue,4); +} + +//------------------------------------------------------------------------------- +// Toggle the "Skeleton" state +//------------------------------------------------------------------------------- +void ToggleSkeleton() +{ + g_sOptions.bSkeleton = !g_sOptions.bSkeleton; + + // store this in the registry, too + DWORD dwValue = 0; + if (g_sOptions.bCulling)dwValue = 1; + RegSetValueExA(g_hRegistry,"Skeleton",0,REG_DWORD,(const BYTE*)&dwValue,4); +} //------------------------------------------------------------------------------- // Toggle the "WireFrame" state @@ -1212,6 +1150,9 @@ void InitUI() CheckDlgButton(g_hDlg,IDC_TOGGLEWIRE,BST_CHECKED); } LoadCheckerPatternColors(); + + SendDlgItemMessage(g_hDlg,IDC_SLIDERANIM,TBM_SETRANGEMIN,TRUE,0); + SendDlgItemMessage(g_hDlg,IDC_SLIDERANIM,TBM_SETRANGEMAX,TRUE,10000); return; } @@ -1251,6 +1192,18 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg, LoadLightColors(); return TRUE; + case WM_HSCROLL: + + if (GetDlgItem(g_hDlg, IDC_SLIDERANIM) == (HWND)lParam) + { + double num = (double)SendDlgItemMessage(g_hDlg,IDC_SLIDERANIM,TBM_GETPOS,0,0); + const aiAnimation* anim = g_pcAsset->pcScene->mAnimations[ g_pcAsset->mAnimator->CurrentAnimIndex() ]; + + g_dCurrent = (anim->mDuration/anim->mTicksPerSecond) * num/10000; + g_pcAsset->mAnimator->Calculate(g_dCurrent); + } + break; + case WM_MOUSEWHEEL: if (CDisplay::VIEWMODE_TEXTURE == CDisplay::Instance().GetViewMode()) @@ -1931,6 +1884,19 @@ __DRUNKEN_ALIEN_FROM_MARS: { ToggleWireFrame(); } + else if (IDC_SHOWSKELETON == LOWORD(wParam)) + { + ToggleSkeleton(); + } + else if (IDC_BFCULL == LOWORD(wParam)) + { + ToggleCulling(); + } + else if (IDC_PLAY == LOWORD(wParam)) + { + g_bPlay = !g_bPlay; + SetDlgItemText(g_hDlg,IDC_PLAY,(g_bPlay ? "Stop" : "Play")); + } } // check the file history for (unsigned int i = 0; i < AI_VIEW_NUM_RECENT_FILES;++i) @@ -2102,11 +2068,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, "ASSIMP ModelViewer",MB_OK); return -4; } - // setup ASSIMP standard limits for the SplitLargeMeshes-process -// aiSetTriangleSplitLimit(g_sCaps.MaxPrimitiveCount-1); -// aiSetVertexSplitLimit(0xFFFFFFFF); - - CLogDisplay::Instance().AddEntry("[OK] The viewer has been initialized successfully"); + CLogDisplay::Instance().AddEntry("[OK] assimp_view has been initialized successfully"); // create the log window CLogWindow::Instance().Init(); @@ -2264,6 +2226,26 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, ToggleWireFrame(); break; + + case 'K': + case 'k': + + CheckDlgButton(g_hDlg,IDC_SHOWSKELETON, + IsDlgButtonChecked(g_hDlg,IDC_SHOWSKELETON) == BST_CHECKED + ? BST_UNCHECKED : BST_CHECKED); + + ToggleSkeleton(); + break; + + case 'C': + case 'c': + + CheckDlgButton(g_hDlg,IDC_BFCULL, + IsDlgButtonChecked(g_hDlg,IDC_BFCULL) == BST_CHECKED + ? BST_UNCHECKED : BST_CHECKED); + + ToggleCulling(); + break; } } } @@ -2273,6 +2255,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, CDisplay::Instance().OnRender(); + // measure FPS, average it out g_dCurTime = timeGetTime(); g_fElpasedTime = (float)((g_dCurTime - g_dLastTime) * 0.001); g_dLastTime = g_dCurTime; diff --git a/tools/assimp_view/RenderOptions.h b/tools/assimp_view/RenderOptions.h index 8b8d6aa3a..fea743d75 100644 --- a/tools/assimp_view/RenderOptions.h +++ b/tools/assimp_view/RenderOptions.h @@ -35,7 +35,9 @@ class RenderOptions bRotate (true), bLowQuality (false), bNoSpecular (false), - bStereoView (false) {} + bStereoView (false), + bCulling (false), + bSkeleton (false) {} bool bMultiSample; @@ -68,6 +70,8 @@ class RenderOptions // wireframe or solid rendering? DrawMode eDrawMode; + + bool bCulling,bSkeleton; }; #endif // !! IG \ No newline at end of file diff --git a/tools/assimp_view/SceneAnimator.cpp b/tools/assimp_view/SceneAnimator.cpp index 735f8d4e5..fb0c2ab89 100644 --- a/tools/assimp_view/SceneAnimator.cpp +++ b/tools/assimp_view/SceneAnimator.cpp @@ -39,6 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- */ +/** @file SceneAnimator.cpp + * @brief Implementation of the utility class SceneAnimator + */ + #include "stdafx.h" #include "assimp_view.h" @@ -53,6 +57,18 @@ SceneAnimator::SceneAnimator( const aiScene* pScene, size_t pAnimIndex) mAnimEvaluator = NULL; mRootNode = NULL; + // build the nodes-for-bones table + for (unsigned int i = 0; i < pScene->mNumMeshes;++i) + { + const aiMesh* mesh = pScene->mMeshes[i]; + for (unsigned int n = 0; n < mesh->mNumBones;++n) + { + const aiBone* bone = mesh->mBones[n]; + + mBoneNodesByName[bone->mName.data] = pScene->mRootNode->FindNode(bone->mName); + } + } + // changing the current animation also creates the node tree for this animation SetAnimIndex( pAnimIndex); } @@ -109,9 +125,9 @@ void SceneAnimator::Calculate( double pTime) // ------------------------------------------------------------------------------------------------ // Retrieves the most recent local transformation matrix for the given node. -const aiMatrix4x4& SceneAnimator::GetLocalTransform( const std::string& pNodeName) const +const aiMatrix4x4& SceneAnimator::GetLocalTransform( const aiNode* node) const { - NodeMap::const_iterator it = mNodesByName.find( pNodeName); + NodeMap::const_iterator it = mNodesByName.find( node); if( it == mNodesByName.end()) return mIdentityMatrix; @@ -120,9 +136,9 @@ const aiMatrix4x4& SceneAnimator::GetLocalTransform( const std::string& pNodeNam // ------------------------------------------------------------------------------------------------ // Retrieves the most recent global transformation matrix for the given node. -const aiMatrix4x4& SceneAnimator::GetGlobalTransform( const std::string& pNodeName) const +const aiMatrix4x4& SceneAnimator::GetGlobalTransform( const aiNode* node) const { - NodeMap::const_iterator it = mNodesByName.find( pNodeName); + NodeMap::const_iterator it = mNodesByName.find( node); if( it == mNodesByName.end()) return mIdentityMatrix; @@ -142,7 +158,7 @@ const std::vector& SceneAnimator::GetBoneMatrices( const aiNode* pN mTransforms.resize( mesh->mNumBones, aiMatrix4x4()); // calculate the mesh's inverse global transform - aiMatrix4x4 globalInverseMeshTransform = GetGlobalTransform( std::string( pNode->mName.data)); + aiMatrix4x4 globalInverseMeshTransform = GetGlobalTransform( pNode); globalInverseMeshTransform.Inverse(); // Bone matrices transform from mesh coordinates in bind pose to mesh coordinates in skinned pose @@ -150,7 +166,7 @@ const std::vector& SceneAnimator::GetBoneMatrices( const aiNode* pN for( size_t a = 0; a < mesh->mNumBones; ++a) { const aiBone* bone = mesh->mBones[a]; - const aiMatrix4x4& currentGlobalTransform = GetGlobalTransform( std::string( bone->mName.data)); + const aiMatrix4x4& currentGlobalTransform = GetGlobalTransform( mBoneNodesByName[ bone->mName.data ]); mTransforms[a] = globalInverseMeshTransform * currentGlobalTransform * bone->mOffsetMatrix; } @@ -165,7 +181,7 @@ SceneAnimNode* SceneAnimator::CreateNodeTree( aiNode* pNode, SceneAnimNode* pPar // create a node SceneAnimNode* internalNode = new SceneAnimNode( pNode->mName.data); internalNode->mParent = pParent; - mNodesByName[std::string( pNode->mName.data)] = internalNode; + mNodesByName[pNode] = internalNode; // copy its transformation internalNode->mLocalTransform = pNode->mTransformation; diff --git a/tools/assimp_view/SceneAnimator.h b/tools/assimp_view/SceneAnimator.h index 0d0129beb..6bb3e2a20 100644 --- a/tools/assimp_view/SceneAnimator.h +++ b/tools/assimp_view/SceneAnimator.h @@ -1,4 +1,3 @@ -/** Manages animations for a given scene and calculates present transformations for all nodes */ /* --------------------------------------------------------------------------- Open Asset Import Library (ASSIMP) @@ -40,98 +39,163 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- */ +/** @file SceneAnimator.h + * Manages animations for a given scene and calculates present + * transformations for all nodes + */ + #ifndef AV_SCENEANIMATOR_H_INCLUDED #define AV_SCENEANIMATOR_H_INCLUDED -namespace AssimpView -{ +namespace AssimpView { -/** A little tree structure to match the scene's node structure, but holding additional data. Needs to be public - * to allow using it in templates at certain compilers. +// --------------------------------------------------------------------------------- +/** A little tree structure to match the scene's node structure, but holding + * additional data. Needs to be public to allow using it in templates at + * certain compilers. */ struct SceneAnimNode { std::string mName; SceneAnimNode* mParent; std::vector mChildren; - aiMatrix4x4 mLocalTransform; // most recently calculated local transform - aiMatrix4x4 mGlobalTransform; // same, but in world space - size_t mChannelIndex; // index in the current animation's channel array. -1 if not animated. - SceneAnimNode() { mChannelIndex = -1; mParent = NULL; } - SceneAnimNode( const std::string& pName) : mName( pName) { mChannelIndex = -1; mParent = NULL; } - ~SceneAnimNode() { for( std::vector::iterator it = mChildren.begin(); it != mChildren.end(); ++it) delete *it; } + //! most recently calculated local transform + aiMatrix4x4 mLocalTransform; + + //! same, but in world space + aiMatrix4x4 mGlobalTransform; + + //! index in the current animation's channel array. -1 if not animated. + size_t mChannelIndex; + + //! Default construction + SceneAnimNode() { + mChannelIndex = -1; mParent = NULL; + } + + //! Construction from a given name + SceneAnimNode( const std::string& pName) + : mName( pName) { + mChannelIndex = -1; mParent = NULL; + } + + //! Destruct all children recursively + ~SceneAnimNode() { + for( std::vector::iterator it = mChildren.begin(); it != mChildren.end(); ++it) + delete *it; + } }; -/** Calculates the animated node transformations for a given scene and timestamp. Create an instance for a aiScene - * you want to animate and set the current animation to play. You can then have the instance calculate the current pose - * for all nodes by calling Calculate() for a given timestamp. After this you can retrieve the present transformation for a given - * node by calling GetLocalTransform() or GetGlobalTransform(). A full set of bone matrices can be retrieved by GetBoneMatrices() - * for a given mesh. +// --------------------------------------------------------------------------------- +/** Calculates the animated node transformations for a given scene and timestamp. + * + * Create an instance for a aiScene you want to animate and set the current animation + * to play. You can then have the instance calculate the current pose for all nodes + * by calling Calculate() for a given timestamp. After this you can retrieve the + * present transformation for a given node by calling GetLocalTransform() or + * GetGlobalTransform(). A full set of bone matrices can be retrieved by + * GetBoneMatrices() for a given mesh. */ class SceneAnimator { public: - /** Constructor for a given scene. The object keeps a reference to the scene during its lifetime, but ownership - * stays at the caller. + + // ---------------------------------------------------------------------------- + /** Constructor for a given scene. + * + * The object keeps a reference to the scene during its lifetime, but + * ownership stays at the caller. * @param pScene The scene to animate. - * @param pAnimIndex [optional] Index of the animation to play. Assumed to be 0 if not given. + * @param pAnimIndex [optional] Index of the animation to play. Assumed to + * be 0 if not given. */ SceneAnimator( const aiScene* pScene, size_t pAnimIndex = 0); /** Destructor */ ~SceneAnimator(); - /** Sets the animation to use for playback. This also recreates the internal mapping structures, - * which might take a few cycles. + // ---------------------------------------------------------------------------- + /** Sets the animation to use for playback. This also recreates the internal + * mapping structures, which might take a few cycles. * @param pAnimIndex Index of the animation in the scene's animation array */ void SetAnimIndex( size_t pAnimIndex); - /** Calculates the node transformations for the scene. Call this to get uptodate results - * before calling one of the getters. + // ---------------------------------------------------------------------------- + /** Calculates the node transformations for the scene. Call this to get + * uptodate results before calling one of the getters. * @param pTime Current time. Can be an arbitrary range. */ void Calculate( double pTime); - /** Retrieves the most recent local transformation matrix for the given node. The returned - * matrix is in the node's parent's local space, just like the original node's transformation - * matrix. If the node is not animated, the node's original transformation is returned so that - * you can safely use or assign it to the node itsself. If there is no node with the given name, - * the identity matrix is returned. All transformations are updated whenever Calculate() is called. - * @param pNodeName Name of the node - * @return A reference to the node's most recently calculated local transformation matrix. - */ - const aiMatrix4x4& GetLocalTransform( const std::string& pNodeName) const; - - /** Retrieves the most recent global transformation matrix for the given node. The returned - * matrix is in world space, which is the same coordinate space as the transformation of the - * scene's root node. If the node is not animated, the node's original transformation is - * returned so that you can safely use or assign it to the node itsself. If there is no node - * with the given name, the identity matrix is returned. All transformations are updated whenever + // ---------------------------------------------------------------------------- + /** Retrieves the most recent local transformation matrix for the given node. + * + * The returned matrix is in the node's parent's local space, just like the + * original node's transformation matrix. If the node is not animated, the + * node's original transformation is returned so that you can safely use or + * assign it to the node itsself. If there is no node with the given name, + * the identity matrix is returned. All transformations are updated whenever * Calculate() is called. * @param pNodeName Name of the node - * @return A reference to the node's most recently calculated global transformation matrix. + * @return A reference to the node's most recently calculated local + * transformation matrix. */ - const aiMatrix4x4& GetGlobalTransform( const std::string& pNodeName) const; + const aiMatrix4x4& GetLocalTransform( const aiNode* node) const; - /** Calculates the bone matrices for the given mesh. Each bone matrix transforms from - * mesh space in bind pose to mesh space in skinned pose, it does not contain the mesh's - * world matrix. Thus the usual matrix chain for using in the vertex shader is - * boneMatrix * worldMatrix * viewMatrix * projMatrix. - * @param pNode The node carrying the mesh. - * @param pMeshIndex Index of the mesh in the node's mesh array. The NODE's mesh array, not - * the scene's mesh array! Leave out to use the first mesh of the node, which is usually - * also the only one. - * @return A reference to a vector of bone matrices. Stays stable till the next call to GetBoneMatrices(); + // ---------------------------------------------------------------------------- + /** Retrieves the most recent global transformation matrix for the given node. + * + * The returned matrix is in world space, which is the same coordinate space + * as the transformation of the scene's root node. If the node is not animated, + * the node's original transformation is returned so that you can safely use or + * assign it to the node itsself. If there is no node with the given name, the + * identity matrix is returned. All transformations are updated whenever + * Calculate() is called. + * @param pNodeName Name of the node + * @return A reference to the node's most recently calculated global + * transformation matrix. */ - const std::vector& GetBoneMatrices( const aiNode* pNode, size_t pMeshIndex = 0); + const aiMatrix4x4& GetGlobalTransform( const aiNode* node) const; + + // ---------------------------------------------------------------------------- + /** Calculates the bone matrices for the given mesh. + * + * Each bone matrix transforms from mesh space in bind pose to mesh space in + * skinned pose, it does not contain the mesh's world matrix. Thus the usual + * matrix chain for using in the vertex shader is + * @code + * boneMatrix * worldMatrix * viewMatrix * projMatrix + * @endcode + * @param pNode The node carrying the mesh. + * @param pMeshIndex Index of the mesh in the node's mesh array. The NODE's + * mesh array, not the scene's mesh array! Leave out to use the first mesh + * of the node, which is usually also the only one. + * @return A reference to a vector of bone matrices. Stays stable till the + * next call to GetBoneMatrices(); + */ + const std::vector& GetBoneMatrices( const aiNode* pNode, + size_t pMeshIndex = 0); + + + // ---------------------------------------------------------------------------- + /** @brief Get the current animation index + */ + size_t CurrentAnimIndex() const { + return mCurrentAnimIndex; + } protected: - /** Recursively creates an internal node structure matching the current scene and animation. */ + + /** Recursively creates an internal node structure matching the + * current scene and animation. + */ SceneAnimNode* CreateNodeTree( aiNode* pNode, SceneAnimNode* pParent); - /** Recursively updates the internal node transformations from the given matrix array */ + /** Recursively updates the internal node transformations from the + * given matrix array + */ void UpdateTransforms( SceneAnimNode* pNode, const std::vector& pTransforms); /** Calculates the global transformation matrix for the given internal node */ @@ -151,9 +215,13 @@ protected: SceneAnimNode* mRootNode; /** Name to node map to quickly find nodes by their name */ - typedef std::map NodeMap; + typedef std::map NodeMap; NodeMap mNodesByName; + /** Name to node map to quickly find nodes for given bones by their name */ + typedef std::map BoneMap; + BoneMap mBoneNodesByName; + /** Array to return transformations results inside. */ std::vector mTransforms; diff --git a/tools/assimp_view/Shaders.cpp b/tools/assimp_view/Shaders.cpp index 2a61c0861..7db4cedac 100644 --- a/tools/assimp_view/Shaders.cpp +++ b/tools/assimp_view/Shaders.cpp @@ -587,6 +587,17 @@ std::string g_szMaterialShader = std::string( "};\n" "#endif // AV_AMBIENT_TEXTUR\n" + "#ifdef AV_LIGHTMAP_TEXTURE\n" + "texture LIGHTMAP_TEXTURE;\n" + "sampler LIGHTMAP_SAMPLER\n" + "{\n" + "Texture = ;\n" + "MinFilter=LINEAR;\n" + "MagFilter=LINEAR;\n" + "MipFilter=LINEAR;\n" + "};\n" + "#endif // AV_LIGHTMAP_TEXTURE\n" + "#ifdef AV_OPACITY_TEXTURE\n" "texture OPACITY_TEXTURE;\n" "sampler OPACITY_SAMPLER\n" @@ -643,7 +654,7 @@ std::string g_szMaterialShader = std::string( "float3 Tangent : TANGENT;\n" "float3 Bitangent : BINORMAL;\n" "float2 TexCoord0 : TEXCOORD0;\n" - "#ifdef AV_DIFFUSE_TEXTURE2 \n" + "#ifdef AV_TWO_UV \n" "float2 TexCoord1 : TEXCOORD1;\n" "#endif \n" "#ifdef AV_SKINNING \n" @@ -686,44 +697,7 @@ std::string g_szMaterialShader = std::string( // Selective SuperSampling in screenspace for reflection lookups - "#ifndef AV_SKYBOX_LOOKUP\n" - "#define AV_DISABLESSS\n" - "#endif\n" - "#ifndef AV_DISABLESSS\n" - "float3 GetSSSCubeMap(float3 Reflect)\n" - "{\n" - // compute the reflection vector in screen space\n" - "float3 ScreenReflect = mul(Reflect,ViewProj);\n" - - // compute the gradients of the reflection vector\n" - "float3 fDX = ddx(ScreenReflect);\n" - "float3 fDY = ddy(ScreenReflect);\n" - - // take the center step and calculate gradients for it\n" - "float3 fColor = texCUBE(EnvironmentMapSampler,Reflect).rgb;\n" - - // Take 10 samples around the center step \n" - "fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f * 2.0 / 3.5) * fDX + (0.4f * 2.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n" - "fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f * 3.0 / 3.5) * fDX + (0.4f *-1.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n" - "fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f * 1.0 / 3.5) * fDX + (0.4f *-3.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n" - "fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f *-2.0 / 3.5) * fDX + (0.4f *-2.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n" - "fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f *-3.0 / 3.5) * fDX + (0.4f * 1.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n" - "fColor += texCUBEgrad(EnvironmentMapSampler,mul( ScreenReflect + (0.4f *-1.0 / 3.5) * fDX + (0.4f * 3.0 / 3.5) * fDY, InvViewProj),fDX,fDY).rgb;\n" - "fColor /= 7;\n" - "return fColor;\n" - "}\n" - "#else\n" - "#define GetSSSCubeMap(_refl) (texCUBElod(EnvironmentMapSampler,float4(_refl,0.0f)).rgb) \n" - "#endif\n" - - // bugfix: if normal mapping is active we have the reflection - // vector in tangent, not in world space. Would need the inverse - // of the TSM matrix in the pixel shader (or world space tangent mapping) - // Simply disable realtime reflection for normal mapping. - "#ifdef AV_NORMAL_TEXTURE\n" - "#undef GetSSSCubeMap\n" - "#define GetSSSCubeMap(_refl) (float3(1.0f,1.0f,1.0f))\n" - "#endif\n" + "#define GetSSSCubeMap(_refl) (texCUBElod(EnvironmentMapSampler,float4(_refl,0.0f)).rgb) \n" // Vertex shader for pixel shader usage and one light @@ -747,7 +721,7 @@ std::string g_szMaterialShader = std::string( "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n" "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n" "Out.TexCoord0 = IN.TexCoord0;\n" - "#ifdef AV_DIFFUSE_TEXTURE2 \n" + "#ifdef AV_TWO_UV \n" "Out.TexCoord1 = IN.TexCoord1;\n" "#endif\n" "Out.Color = IN.Color;\n" @@ -787,7 +761,7 @@ std::string g_szMaterialShader = std::string( "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n" "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n" "Out.TexCoord0 = IN.TexCoord0;\n" - "#ifdef AV_DIFFUSE_TEXTURE2 \n" + "#ifdef AV_TWO_UV \n" "Out.TexCoord1 = IN.TexCoord1;\n" "#endif\n" "Out.Color = IN.Color;\n" @@ -893,7 +867,6 @@ std::string g_szMaterialShader = std::string( "#endif // !AV_DIFFUSE_TEXTURE\n" - "#ifdef AV_SPECULAR_COMPONENT\n" "#ifndef AV_SKYBOX_LOOKUP\n" "#ifdef AV_SPECULAR_TEXTURE\n" @@ -920,14 +893,13 @@ std::string g_szMaterialShader = std::string( "#else \n" "EMISSIVE_COLOR.rgb;\n" "#endif // !AV_EMISSIVE_TEXTURE\n" - - "#ifdef AV_DIFFUSE_TEXTURE2\n" - "OUT.rgb *= tex2D(DIFFUSE_SAMPLER2,IN.TexCoord1).rgb*4.0f;\n" - "#endif \n" "}\n" "#ifdef AV_OPACITY\n" "OUT.a = TRANSPARENCY;\n" "#endif\n" + "#ifdef AV_LIGHTMAP_TEXTURE\n" + "OUT.rgb *= tex2D(LIGHTMAP_SAMPLER,AV_LIGHTMAP_TEXTURE_UV_COORD).rgb;\n" + "#endif\n" "#ifdef AV_OPACITY_TEXTURE\n" "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n" "#endif\n" @@ -1040,6 +1012,9 @@ std::string g_szMaterialShader = std::string( "#ifdef AV_OPACITY\n" "OUT.a = TRANSPARENCY;\n" "#endif\n" + "#ifdef AV_LIGHTMAP_TEXTURE\n" + "OUT.rgb *= tex2D(LIGHTMAP_SAMPLER,AV_LIGHTMAP_TEXTURE_UV_COORD).rgb;\n" + "#endif\n" "#ifdef AV_OPACITY_TEXTURE\n" "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n" "#endif\n" @@ -1198,8 +1173,6 @@ std::string g_szMaterialShader = std::string( "{\n" "pass p0\n" "{\n" - "CullMode=none;\n" - "#ifdef AV_OPACITY_TEXTURE\n" "AlphaBlendEnable=TRUE;" "SrcBlend = srcalpha;\n" @@ -1220,8 +1193,6 @@ std::string g_szMaterialShader = std::string( "{\n" "pass p0\n" "{\n" - "CullMode=none;\n" - "#ifdef AV_OPACITY_TEXTURE\n" "AlphaBlendEnable=TRUE;" "SrcBlend = srcalpha;\n" @@ -1244,8 +1215,6 @@ std::string g_szMaterialShader = std::string( "{\n" "pass p0\n" "{\n" - "CullMode=none;\n" - "#ifdef AV_OPACITY_TEXTURE\n" "AlphaBlendEnable=TRUE;" "SrcBlend = srcalpha;\n" @@ -1267,7 +1236,7 @@ std::string g_szMaterialShader = std::string( "{\n" "pass p0\n" "{\n" - "CullMode=none;\n" + "//CullMode=none;\n" "#ifdef AV_OPACITY_TEXTURE\n" "AlphaBlendEnable=TRUE;" @@ -1291,7 +1260,7 @@ std::string g_szMaterialShader = std::string( "{\n" "pass p0\n" "{\n" - "CullMode=none;\n" + "//CullMode=none;\n" "SpecularEnable = true; \n" "VertexShader = compile vs_2_0 MaterialVShader_FF();\n" "ColorOp[0] = Modulate;\n" diff --git a/tools/assimp_view/assimp_view.aps b/tools/assimp_view/assimp_view.aps index 9631b78f5..452258e0b 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 52ec5cb5a..8d4b6c756 100644 --- a/tools/assimp_view/assimp_view.cpp +++ b/tools/assimp_view/assimp_view.cpp @@ -73,6 +73,8 @@ HANDLE g_hThreadHandle = NULL; float g_fWheelPos = -10.0f; bool g_bLoadingCanceled = false; IDirect3DTexture9* g_pcTexture = NULL; +bool g_bPlay = false; +double g_dCurrent = 0.; extern bool g_bWasFlipped /*= false*/; @@ -226,9 +228,8 @@ int LoadAsset(void) // for each mesh in the original asset g_pcAsset->apcMeshes = new AssetHelper::MeshHelper*[g_pcAsset->pcScene->mNumMeshes](); for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) - { g_pcAsset->apcMeshes[i] = new AssetHelper::MeshHelper(); - } + // create animator g_pcAsset->mAnimator = new SceneAnimator( g_pcAsset->pcScene); @@ -248,16 +249,27 @@ int LoadAsset(void) g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f); // build native D3D vertex/index buffers, textures, materials - if( 1 != CreateAssetData())return 0; + if( 1 != CreateAssetData()) + return 0; + + if (!g_pcAsset->pcScene->HasAnimations()) { + EnableWindow(GetDlgItem(g_hDlg,IDC_PLAY),FALSE); + EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),FALSE); + } + else { + EnableWindow(GetDlgItem(g_hDlg,IDC_PLAY),TRUE); + EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),TRUE); + } CLogDisplay::Instance().AddEntry("[OK] The asset has been loaded successfully"); CDisplay::Instance().FillDisplayList(); CDisplay::Instance().FillAnimList(); CDisplay::Instance().FillDefaultStatistics(); + + // render the scene once + CDisplay::Instance().OnRender(); - // just make sure the alpha blend ordering is done in the first frame - CMeshRenderer::Instance().Reset(); g_pcAsset->iNormalSet = AssetHelper::ORIGINAL; g_bWasFlipped = false; return 1; @@ -437,7 +449,6 @@ int CreateAssetData() // reset all subsystems CMaterialManager::Instance().Reset(); - CMeshRenderer::Instance().Reset(); CDisplay::Instance().Reset(); for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i) diff --git a/tools/assimp_view/assimp_view.h b/tools/assimp_view/assimp_view.h index 80cbed195..95d5095e4 100644 --- a/tools/assimp_view/assimp_view.h +++ b/tools/assimp_view/assimp_view.h @@ -198,7 +198,7 @@ enum EClickPos }; #if (!defined AI_VIEW_CAPTION_BASE) -# define AI_VIEW_CAPTION_BASE "AssimpView 1.0" +# define AI_VIEW_CAPTION_BASE "Open Asset Import Library : Viewer " #endif // !! AI_VIEW_CAPTION_BASE //------------------------------------------------------------------------------- @@ -268,6 +268,10 @@ enum EClickPos extern float g_fACMR /*= 3.0f*/; extern IDirect3DQuery9* g_piQuery; + + extern bool g_bPlay /*= false*/; + + extern double g_dCurrent; } #endif // !! AV_MAIN_H_INCLUDED \ No newline at end of file diff --git a/tools/assimp_view/assimp_view.rc b/tools/assimp_view/assimp_view.rc index 1eaa6e776..f4bfa4812 100644 --- a/tools/assimp_view/assimp_view.rc +++ b/tools/assimp_view/assimp_view.rc @@ -56,84 +56,84 @@ BEGIN CONTROL 130,IDC_STATIC,"Static",SS_BITMAP,0,149,514,20 END -IDD_DIALOGMAIN DIALOGEX 0, 0, 594, 384 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_DIALOGMAIN DIALOGEX 0, 0, 594, 380 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES CAPTION "Open Asset Import Library - ModelViewer " MENU IDR_MENU1 FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN CONTROL "",IDC_RT,"Static",SS_OWNERDRAW,3,5,462,351 - CONTROL "MultiSample image",IDC_TOGGLEMS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,173,80,10 - 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 + CONTROL "Multisampling",IDC_TOGGLEMS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,241,80,10 + CONTROL "Wireframe",IDC_TOGGLEWIRE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,251,49,10 + CONTROL "No materials",IDC_TOGGLEMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,261,55,10 LTEXT "Verts:",IDC_NUMVERTS,475,14,27,8 LTEXT "Faces:\t",IDC_NUMFACES,539,14,22,8 LTEXT "Mats:",IDC_NUMMATS,540,26,20,8 LTEXT "FPS:",IDC_FPS,540,51,20,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 + CONTROL "Display normals",IDC_TOGGLENORMALS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,271,65,10 + CONTROL "Toggle AutoRotate",IDC_AUTOROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,348,74,10 EDITTEXT IDC_EVERT,504,11,32,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 + CONTROL "Rotate light sources",IDC_LIGHTROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,368,74,10 + CONTROL "Two lights",IDC_3LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,281,48,10 LTEXT "Time:",IDC_LOADTIME,475,51,29,8 EDITTEXT IDC_ELOAD,504,50,32,12,ES_AUTOHSCROLL | ES_READONLY - CONTROL "Zoom/Rotate",IDC_ZOOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,267,58,10 - CONTROL "Low quality lighting",IDC_LOWQUALITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,223,74,10 - CONTROL "No specular lighting",IDC_NOSPECULAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,233,74,10 - CONTROL "Play [OK]",IDC_PLAYANIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,480,297,42,10 - CONTROL "",IDC_SPEED,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | TBS_TOOLTIPS | WS_TABSTOP,480,309,90,12 - LTEXT "Speed: [+/-]",IDC_SSPEED,526,297,42,8 + CONTROL "Zoom/Rotate",IDC_ZOOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,358,58,10 + CONTROL "Low quality",IDC_LOWQUALITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,291,74,10 + CONTROL "No specular ",IDC_NOSPECULAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,301,74,10 LTEXT "Shd:",IDC_NUMSHADERS,476,40,23,8 EDITTEXT IDC_ESHADER,504,37,32,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "[M]",IDC_STATIC,553,173,11,8 - LTEXT "[W]",IDC_STATIC,553,183,11,8 - LTEXT "[D]",IDC_STATIC,553,193,11,8 - LTEXT "[N]",IDC_STATIC,553,203,11,8 - LTEXT "[L]",IDC_STATIC,553,213,11,8 - LTEXT "[P]",IDC_STATIC,553,223,11,8 - LTEXT "[S]",IDC_STATIC,553,233,11,8 - LTEXT "[A]",IDC_STATIC,552,257,11,8 - LTEXT "[Z]",IDC_STATIC,552,267,11,8 - LTEXT "[R]",IDC_STATIC,552,276,11,8 - COMBOBOX IDC_COMBO1,480,331,90,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Anim: [Pg up/Pg down]",IDC_SANIM,483,320,74,8 + LTEXT "[M]",IDC_STATIC,553,241,11,8 + LTEXT "[W]",IDC_STATIC,553,251,11,8 + LTEXT "[D]",IDC_STATIC,553,261,11,8 + LTEXT "[N]",IDC_STATIC,553,271,11,8 + LTEXT "[L]",IDC_STATIC,553,281,11,8 + LTEXT "[P]",IDC_STATIC,553,291,11,8 + LTEXT "[S]",IDC_STATIC,553,301,11,8 + LTEXT "[A]",IDC_STATIC,552,348,11,8 + LTEXT "[Z]",IDC_STATIC,552,358,11,8 + LTEXT "[R]",IDC_STATIC,552,368,11,8 + COMBOBOX IDC_COMBO1,353,361,84,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP CONTROL 149,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,470,0,114,9 - CONTROL 148,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,470,161,114,9 - CONTROL 147,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,470,245,114,9 - CONTROL 145,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,470,287,114,9 + CONTROL 148,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,470,229,114,9 + CONTROL 147,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,470,336,114,9 CONTROL 146,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,470,65,114,9 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,469,0,1,360 - CONTROL "<<",IDC_BLUBB,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP,439,367,27,10 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,469,0,1,380 CONTROL 149,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,584,0,10,9 CONTROL 149,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,584,65,10,9 - 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 + CONTROL 149,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,583,229,10,9 + CONTROL 149,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,584,336,10,9 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 + CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,470,74,123,155 LTEXT "Mesh:",IDC_NUMMESHES,540,39,20,8 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 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,567,238,1,93 + CONTROL "Button1",IDC_LCOLOR1,"Button",BS_OWNERDRAW | WS_TABSTOP,570,242,21,17 + CONTROL "Button1",IDC_LCOLOR2,"Button",BS_OWNERDRAW | WS_TABSTOP,570,262,21,17 + CONTROL "Button1",IDC_LCOLOR3,"Button",BS_OWNERDRAW | WS_TABSTOP,570,282,21,17 + PUSHBUTTON "R",IDC_LRESET,576,300,15,11,BS_BOTTOM EDITTEXT IDC_VIEWMATRIX,475,24,61,38,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_VISIBLE + CONTROL "Show skeleton",IDC_SHOWSKELETON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,312,74,10 + LTEXT "[K]",IDC_STATIC,553,312,11,8 + CONTROL "<<",IDC_BLUBB,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP,439,361,27,15 + LTEXT "[C]",IDC_STATIC,553,323,11,8 + CONTROL "",IDC_SLIDERANIM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,0,362,322,15 + PUSHBUTTON "Play",IDC_PLAY,326,361,25,15 + CONTROL "Backface culling",IDC_BFCULL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,473,323,74,10 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,358,470,1 END -IDD_LOADDIALOG DIALOGEX 0, 0, 278, 99 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_BORDER | WS_SYSMENU -FONT 8, "MS Shell Dlg", 400, 0, 0x1 +IDD_LOADDIALOG DIALOGEX 0, 0, 143, 60 +STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_BORDER | WS_SYSMENU +FONT 12, "Tahoma", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "Cancel",IDOK,206,78,65,14 - CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,11,46,260,14 - LTEXT "Please wait while ASSIMP is loading the asset. This might take a few seconds\nSit down and drink a cup of coffee or similar. Relax.\nThe force is with you...",IDC_STATIC,15,15,246,27 + DEFPUSHBUTTON "Cancel",IDOK,104,41,33,13 + CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,6,30,130,8 + LTEXT "Loading ...\nMay the force be with you ...",IDC_STATIC,8,9,123,16 END IDD_AVHELP DIALOGEX 0, 0, 481, 346 @@ -241,9 +241,7 @@ BEGIN IDD_LOADDIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 271 TOPMARGIN, 7 - BOTTOMMARGIN, 92 END IDD_AVHELP, DIALOG diff --git a/tools/assimp_view/resource.h b/tools/assimp_view/resource.h index 33d69afca..0fe1963e4 100644 --- a/tools/assimp_view/resource.h +++ b/tools/assimp_view/resource.h @@ -80,6 +80,7 @@ #define IDC_SPEED 1026 #define IDC_COMBO1 1027 #define IDC_PINORDER 1028 +#define IDC_NOSPECULAR2 1028 #define IDC_SSPEED 1029 #define IDC_SANIM 1030 #define IDC_SANIMGB 1031 @@ -99,6 +100,10 @@ #define IDC_NUMMESHES 1047 #define IDC_VIEWMAT 1048 #define IDC_VIEWMATRIX 1048 +#define IDC_SLIDERANIM 1052 +#define IDC_PLAY 1053 +#define IDC_SHOWSKELETON 1054 +#define IDC_BFCULL 1055 #define ID_VIEWER_OPEN 32771 #define ID_VIEWER_CLOSETHIS 32772 #define ID_VIEWER_CLOSEASSET 32773 @@ -168,7 +173,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 159 #define _APS_NEXT_COMMAND_VALUE 32831 -#define _APS_NEXT_CONTROL_VALUE 1052 +#define _APS_NEXT_CONTROL_VALUE 1056 #define _APS_NEXT_SYMED_VALUE 110 #endif #endif diff --git a/workspaces/vc9/assimp.vcproj b/workspaces/vc9/assimp.vcproj index 43be68e09..6b7da22a6 100644 --- a/workspaces/vc9/assimp.vcproj +++ b/workspaces/vc9/assimp.vcproj @@ -47,6 +47,7 @@ SmallerTypeCheck="true" RuntimeLibrary="3" EnableFunctionLevelLinking="true" + FloatingPointModel="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="AssimpPCH.h" WarningLevel="3" @@ -107,7 +108,7 @@ Name="VCCLCompilerTool" InlineFunctionExpansion="2" EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" + FavorSizeOrSpeed="0" WholeProgramOptimization="false" AdditionalIncludeDirectories="" PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_SECURE_SCL=0;WIN32" @@ -115,6 +116,7 @@ RuntimeLibrary="2" BufferSecurityCheck="false" EnableEnhancedInstructionSet="2" + FloatingPointModel="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="AssimpPCH.h" WarningLevel="3" @@ -173,13 +175,14 @@ Name="VCCLCompilerTool" InlineFunctionExpansion="2" EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" + FavorSizeOrSpeed="0" AdditionalIncludeDirectories="" PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_BUILD_DLL_EXPORT" StringPooling="true" RuntimeLibrary="2" BufferSecurityCheck="false" EnableEnhancedInstructionSet="2" + FloatingPointModel="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="AssimpPCH.h" WarningLevel="3" @@ -254,6 +257,7 @@ SmallerTypeCheck="true" RuntimeLibrary="3" EnableFunctionLevelLinking="true" + FloatingPointModel="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="AssimpPCH.h" WarningLevel="3" @@ -325,13 +329,14 @@ Name="VCCLCompilerTool" InlineFunctionExpansion="2" EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" + FavorSizeOrSpeed="0" AdditionalIncludeDirectories="" PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;ASSIMP_BUILD_BOOST_WORKAROUND" StringPooling="true" RuntimeLibrary="2" BufferSecurityCheck="false" EnableEnhancedInstructionSet="2" + FloatingPointModel="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="AssimpPCH.h" WarningLevel="3" @@ -394,6 +399,7 @@ SmallerTypeCheck="true" RuntimeLibrary="3" EnableFunctionLevelLinking="true" + FloatingPointModel="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="AssimpPCH.h" WarningLevel="3" @@ -457,6 +463,7 @@ SmallerTypeCheck="true" RuntimeLibrary="3" EnableFunctionLevelLinking="true" + FloatingPointModel="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="AssimpPCH.h" WarningLevel="3" @@ -516,13 +523,14 @@ Name="VCCLCompilerTool" InlineFunctionExpansion="2" EnableIntrinsicFunctions="true" - FavorSizeOrSpeed="1" + FavorSizeOrSpeed="0" AdditionalIncludeDirectories="" PreprocessorDefinitions="NDEBUG;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32" StringPooling="true" RuntimeLibrary="2" BufferSecurityCheck="false" EnableEnhancedInstructionSet="2" + FloatingPointModel="2" UsePrecompiledHeader="2" PrecompiledHeaderThrough="AssimpPCH.h" WarningLevel="3"