From: <rob...@us...> - 2009-02-24 10:19:41
|
Revision: 371 http://colladamaya.svn.sourceforge.net/colladamaya/?rev=371&view=rev Author: robertwuerfel Date: 2009-02-24 10:19:30 +0000 (Tue, 24 Feb 2009) Log Message: ----------- optionally calculate and export textangents and texbinormals for triangle meshes Modified Paths: -------------- branches/nextgen/COLLADABaseUtils/include/Math/COLLADABUMathVector3.h branches/nextgen/COLLADAMax/include/COLLADAMaxGeometryExporter.h branches/nextgen/COLLADAMax/scripts/COLLADAMax.vcproj branches/nextgen/COLLADAMax/src/COLLADAMaxGeometryExporter.cpp branches/nextgen/COLLADAStreamWriter/include/COLLADASWConstants.h branches/nextgen/COLLADAStreamWriter/src/COLLADASWConstants.cpp branches/nextgen/COLLADAStreamWriter/src/COLLADASWInputList.cpp Added Paths: ----------- branches/nextgen/COLLADAMax/include/COLLADAMaxIMeshAccess.h branches/nextgen/COLLADAMax/include/COLLADAMaxMeshAccess.h branches/nextgen/COLLADAMax/include/COLLADAMaxTexTangentCalculator.h branches/nextgen/COLLADAMax/src/COLLADAMaxTexTangentCalculator.cpp Modified: branches/nextgen/COLLADABaseUtils/include/Math/COLLADABUMathVector3.h =================================================================== --- branches/nextgen/COLLADABaseUtils/include/Math/COLLADABUMathVector3.h 2009-02-20 15:55:04 UTC (rev 370) +++ branches/nextgen/COLLADABaseUtils/include/Math/COLLADABUMathVector3.h 2009-02-24 10:19:30 UTC (rev 371) @@ -25,7 +25,7 @@ /** Standard 3-dimensional vector. @remarks A direction in 3D space represented as distances along the 3 - orthoganal axes (x, y, z). Note that positions, directions and + orthogonal axes (x, y, z). Note that positions, directions and scaling factors can be represented by a vector, depending on how you interpret the values. */ @@ -73,6 +73,13 @@ : x( rkVector.x ), y( rkVector.y ), z( rkVector.z ) {} + inline void set( Real fX, Real fY, Real fZ ) + { + x = fX; + y = fY; + z = fZ; + } + inline Real operator [] ( size_t i ) const { assert( i < 3 ); Modified: branches/nextgen/COLLADAMax/include/COLLADAMaxGeometryExporter.h =================================================================== --- branches/nextgen/COLLADAMax/include/COLLADAMaxGeometryExporter.h 2009-02-20 15:55:04 UTC (rev 370) +++ branches/nextgen/COLLADAMax/include/COLLADAMaxGeometryExporter.h 2009-02-24 10:19:30 UTC (rev 371) @@ -30,6 +30,7 @@ namespace COLLADAMax { + class TexTangentCalculator; class ExportNode; struct MorphControllerHelperGeometry; @@ -52,8 +53,10 @@ /** List of indices.*/ typedef std::vector<int> IndicesList; + typedef std::map<int, TexTangentCalculator*> ChannelIndexTexTangentCalculatorMap; + public: /** Symbol used for simple color materials.*/ static const String COLOR_MATERIAL_SYMBOL; @@ -93,6 +96,8 @@ static const String SYMBOL_NAME_PREFIX; + ChannelIndexTexTangentCalculatorMap mChannelIndexTexTangentCalculatorMap; + public: /** Constructor @param exportNode The node which geometry should be exported @@ -180,12 +185,6 @@ /** Create list of materials used by this geometry.*/ void flattenMaterials ( Mtl* material, MaterialList& mtlMap, int materialIndex = -1 ); - /** Calculates the textangents and texbinormals of the current mesh and MeshMap @a meshMap and stores them in - @a texTangents and @a texBinormals. The are not reduces, i.e. no indices are needed since the are always the same.*/ - void calculateTriangleMeshTextangentsAndTexbinormals(int channelIndex, - Point3List& texTangents, - Point3List& texBinormals); - }; } Added: branches/nextgen/COLLADAMax/include/COLLADAMaxIMeshAccess.h =================================================================== --- branches/nextgen/COLLADAMax/include/COLLADAMaxIMeshAccess.h (rev 0) +++ branches/nextgen/COLLADAMax/include/COLLADAMaxIMeshAccess.h 2009-02-24 10:19:30 UTC (rev 371) @@ -0,0 +1,70 @@ +/* +Copyright (c) 2008 NetAllied Systems GmbH + +This file is part of COLLADAMax. + +Portions of the code are: +Copyright (c) 2005-2007 Feeling Software Inc. +Copyright (c) 2005-2007 Sony Computer Entertainment America + +Based on the 3dsMax COLLADASW Tools: +Copyright (c) 2005-2006 Autodesk Media Entertainment + +Licensed under the MIT Open Source License, +for details please see LICENSE file or the website +http://www.opensource.org/licenses/mit-license.php +*/ + +#ifndef __COLLADAMAX_IMESHACCESS_H__ +#define __COLLADAMAX_IMESHACCESS_H__ + +#include "COLLADAMaxPrerequisites.h" + +#include "Math/COLLADABUMathVector3.h" + +namespace COLLADAMax +{ + + /** Interface to access mesh data. Used by TexTangentCalculator */ + class IMeshAccess + { + private: + + public: + + /** Constructor. */ + IMeshAccess() {} + + /** Destructor. */ + virtual ~IMeshAccess(){} + + /** Returns the number of faces in the mesh.*/ + virtual int getFaceCount() = 0; + + /** Returns the number of vertices of the face with index @a faceIndex.*/ + virtual int getVertexCount( int faceIndex ) = 0; + + /** Returns the vertex index of the @a faceVertexIndex'th vertex of the @a faceIndex'th face.*/ + virtual int getPositionIndex( int faceIndex, int faceVertexIndex) = 0; + + /** Returns the position of the vertex with index @a vertexIndex.*/ + virtual COLLADABU::Math::Vector3 getVertex( int vertexIndex ) = 0; + + /** Returns the normal index of the @a faceVertexIndex'th vertex of the @a faceIndex'th face.*/ + virtual int getNormalIndex( int faceIndex, int faceVertexIndex) = 0; + + /** Returns the normal with index @a normalIndex.*/ + virtual COLLADABU::Math::Vector3 getNormal( int normalIndex ) = 0; + + /** Returns the texcoord index of the @a faceVertexIndex'th vertex of the @a faceIndex'th face.*/ + virtual int getTexcoordIndex( int faceIndex, int faceVertexIndex) = 0; + + /** Returns the texcoord with index @a textureIndex.*/ + virtual COLLADABU::Math::Vector3 getTexcoord( int textureIndex ) = 0; + + + }; + +} // namespace COLLADAMAX + +#endif // __COLLADAMAX_IMESHACCESS_H__ Added: branches/nextgen/COLLADAMax/include/COLLADAMaxMeshAccess.h =================================================================== --- branches/nextgen/COLLADAMax/include/COLLADAMaxMeshAccess.h (rev 0) +++ branches/nextgen/COLLADAMax/include/COLLADAMaxMeshAccess.h 2009-02-24 10:19:30 UTC (rev 371) @@ -0,0 +1,105 @@ +/* +Copyright (c) 2008 NetAllied Systems GmbH + +This file is part of COLLADAMax. + +Portions of the code are: +Copyright (c) 2005-2007 Feeling Software Inc. +Copyright (c) 2005-2007 Sony Computer Entertainment America + +Based on the 3dsMax COLLADASW Tools: +Copyright (c) 2005-2006 Autodesk Media Entertainment + +Licensed under the MIT Open Source License, +for details please see LICENSE file or the website +http://www.opensource.org/licenses/mit-license.php +*/ + +#ifndef __COLLADAMAX_MESHACCESS_H__ +#define __COLLADAMAX_MESHACCESS_H__ + +#include "COLLADAMaxPrerequisites.h" + +#include "COLLADAMaxIMeshAccess.h" + +#include <max.h> + + +namespace COLLADAMax +{ + + /** Implements IMeshAccess for a max mesh */ + class MeshAccess : public IMeshAccess + { + private: + Mesh& mMesh; + MeshNormalSpec *mNormalSpec; + MeshMap& mTextureMap; + + public: + + /** Constructor. */ + MeshAccess( Mesh& mesh, int mapChannel) + : mMesh(mesh) + , mNormalSpec(mesh.GetSpecifiedNormals()) + , mTextureMap(mesh.Map ( mapChannel )) + { + if ( !mNormalSpec ) + { + mesh.SpecifyNormals(); + mNormalSpec = mesh.GetSpecifiedNormals(); + } + } + + /** Destructor. */ + virtual ~MeshAccess(){} + + /** Returns the number of faces in the mesh.*/ + virtual int getFaceCount() { return mMesh.getNumFaces(); } + + /** Returns the number of vertices of the face with index @a faceIndex.*/ + virtual int getVertexCount( int faceIndex ) { return 3; } + + /** Returns the vertex index of the @a faceVertexIndex'th vertex of the @a faceIndex'th face.*/ + virtual int getPositionIndex( int faceIndex, int faceVertexIndex) { return mMesh.faces[faceIndex].v[faceVertexIndex]; } + + /** Returns the position of the vertex with index @a vertexIndex.*/ + virtual COLLADABU::Math::Vector3 getVertex( int vertexIndex ) + { + Point3& vertex = mMesh.verts[vertexIndex]; + return COLLADABU::Math::Vector3(vertex.x, vertex.y, vertex.z); + } + + /** Returns the normal index of the @a faceVertexIndex'th vertex of the @a faceIndex'th face.*/ + virtual int getNormalIndex( int faceIndex, int faceVertexIndex){ return mNormalSpec->GetNormalIndex ( faceIndex, faceVertexIndex ) ; } + + /** Returns the normal with index @a normalIndex.*/ + virtual COLLADABU::Math::Vector3 getNormal( int normalIndex ) + { + Point3 & normal = mNormalSpec->Normal ( normalIndex ); + return COLLADABU::Math::Vector3(normal.x, normal.y, normal.z); + } + + /** Returns the texcoord index of the @a faceVertexIndex'th vertex of the @a faceIndex'th face.*/ + virtual int getTexcoordIndex( int faceIndex, int faceVertexIndex) { return mTextureMap.tf[ faceIndex ].t[faceVertexIndex];} + + /** Returns the texcoord with index @a textureIndex.*/ + virtual COLLADABU::Math::Vector3 getTexcoord( int textureIndex ) + { + Point3& texCoord = mTextureMap.tv[ textureIndex ]; + return COLLADABU::Math::Vector3(texCoord.x, texCoord.y, texCoord.z); + } + + private: + + /** Disable default copy ctor. */ + MeshAccess( const MeshAccess& pre ); + + /** Disable default assignment operator. */ + const MeshAccess& operator= ( const MeshAccess& pre ); + + }; + +} // namespace COLLADAMAX + +#endif // __COLLADAMAX_MESHACCESS_H__ Added: branches/nextgen/COLLADAMax/include/COLLADAMaxTexTangentCalculator.h =================================================================== --- branches/nextgen/COLLADAMax/include/COLLADAMaxTexTangentCalculator.h (rev 0) +++ branches/nextgen/COLLADAMax/include/COLLADAMaxTexTangentCalculator.h 2009-02-24 10:19:30 UTC (rev 371) @@ -0,0 +1,111 @@ +/* +Copyright (c) 2008 NetAllied Systems GmbH + +This file is part of COLLADAMax. + +Portions of the code are: +Copyright (c) 2005-2007 Feeling Software Inc. +Copyright (c) 2005-2007 Sony Computer Entertainment America + +Based on the 3dsMax COLLADASW Tools: +Copyright (c) 2005-2006 Autodesk Media Entertainment + +Licensed under the MIT Open Source License, +for details please see LICENSE file or the website +http://www.opensource.org/licenses/mit-license.php +*/ + +#ifndef __COLLADAMAX_TEXTANGENTCALCULATOR_H__ +#define __COLLADAMAX_TEXTANGENTCALCULATOR_H__ + +#include "COLLADAMaxPrerequisites.h" +#include "math/COLLADABUMathVector3.h" + +#include "COLLADAMaxIMeshAccess.h" + +#include <vector> + +namespace COLLADAMax +{ + + /** Calculates textangents and texbinormals for a triangle mesh */ + class TexTangentCalculator + { + public: + typedef COLLADABU::Math::Vector3 Vector3; + typedef COLLADABU::Math::Real Real; + + struct VertexIdentifier + { + int positionIndex; + int normalIndex; + int textureIndex; + bool operator<(const VertexIdentifier& rhs) const; + }; + + struct VertexTexTangentInfo + { + Vector3 tangent; + Vector3 biTangent; + int count; + unsigned long index; + }; + + typedef std::map<VertexIdentifier, VertexTexTangentInfo*> VertexIdentifierVertexTexTangentInfoMap; + + + /** List of vector3.*/ + typedef std::vector<VertexTexTangentInfo*> VertexTexTangentInfoList; + + /** List of indices.*/ + typedef std::vector<unsigned long> IndicesList; + + private: + IMeshAccess* mMesh; + + VertexTexTangentInfoList mTexTangents; + + IndicesList mIndices; + + VertexIdentifierVertexTexTangentInfoMap mVertexIdentifierVertexTexTangentInfoMap; + + unsigned long mTexTangentsCount; + + public: + + /** Constructor. */ + TexTangentCalculator( IMeshAccess* mesh ); + + /** Destructor. */ + virtual ~TexTangentCalculator(); + + void calculateTriangleMeshTextangents(); + + const VertexTexTangentInfoList& getTexTangents() const { return mTexTangents; } + + void clearTexTangentData(); + + const IndicesList& getIndices() const { return mIndices; } + + private: + + /** Disable default copy ctor. */ + TexTangentCalculator( const TexTangentCalculator& pre ); + + /** Disable default assignment operator. */ + const TexTangentCalculator& operator= ( const TexTangentCalculator& pre ); + + void computeTangent( Vector3 textureVertex[3], Vector3 geometryVertex[3], Vector3& texTangent); + + unsigned long addTexTangent( int vertexIndex, int normalIndex, int textureIndex, const Vector3& texTangent ); + + void normalizeTangentsAndCalculateBiTangents(); + + void deleteTexTangentInfo(); + + + }; + +} // namespace COLLADAMAX + +#endif // __COLLADAMAX_TEXTANGENTCALCULATOR_H__ Modified: branches/nextgen/COLLADAMax/scripts/COLLADAMax.vcproj =================================================================== --- branches/nextgen/COLLADAMax/scripts/COLLADAMax.vcproj 2009-02-20 15:55:04 UTC (rev 370) +++ branches/nextgen/COLLADAMax/scripts/COLLADAMax.vcproj 2009-02-24 10:19:30 UTC (rev 371) @@ -1799,6 +1799,10 @@ > </File> <File + RelativePath="..\src\COLLADAMaxTexTangentCalculator.cpp" + > + </File> + <File RelativePath="..\src\COLLADAMaxVisualSceneExporter.cpp" > </File> @@ -2221,6 +2225,10 @@ > </File> <File + RelativePath="..\include\COLLADAMaxIMeshAccess.h" + > + </File> + <File RelativePath="..\include\COLLADAMaxLightExporter.h" > </File> @@ -2229,10 +2237,18 @@ > </File> <File + RelativePath="..\include\COLLADAMaxMeshAccess.h" + > + </File> + <File RelativePath="..\include\COLLADAMaxOptions.h" > </File> <File + RelativePath="..\include\COLLADAMaxTexTangentCalculator.h" + > + </File> + <File RelativePath="..\include\COLLADAMaxVisualSceneExporter.h" > </File> @@ -2334,6 +2350,10 @@ > </File> </Filter> + <File + RelativePath="..\res\error.fx" + > + </File> </Files> <Globals> </Globals> Modified: branches/nextgen/COLLADAMax/src/COLLADAMaxGeometryExporter.cpp =================================================================== --- branches/nextgen/COLLADAMax/src/COLLADAMaxGeometryExporter.cpp 2009-02-20 15:55:04 UTC (rev 370) +++ branches/nextgen/COLLADAMax/src/COLLADAMaxGeometryExporter.cpp 2009-02-24 10:19:30 UTC (rev 371) @@ -34,6 +34,9 @@ #include "COLLADAMaxXRefFunctions.h" +#include "COLLADAMaxMeshAccess.h" +#include "COLLADAMaxTexTangentCalculator.h" + #include <algorithm> #include <max.h> @@ -938,9 +941,16 @@ { continue; } + + MeshAccess mesh( mTriObject->GetMesh(), channelIndex); + TexTangentCalculator* texTangentCalculator = new TexTangentCalculator( &mesh ); + mChannelIndexTexTangentCalculatorMap.insert(std::make_pair(channelIndex, texTangentCalculator)); - calculateTriangleMeshTextangentsAndTexbinormals( channelIndex, texTangents, texBinormals); + texTangentCalculator->calculateTriangleMeshTextangents(); + // calculateTriangleMeshTextangents( channelIndex, texTangents, texBinormals); + + const TexTangentCalculator::VertexTexTangentInfoList& texTangents = texTangentCalculator->getTexTangents(); // textangents size_t texTangentsCount = texTangents.size(); COLLADASW::FloatSource texTangentSource ( mGeometriesExporter->mSW ); @@ -958,14 +968,14 @@ for ( size_t j = 0; j < texTangentsCount; ++j) { - Point3& texTangent = texTangents[j]; + COLLADABU::Math::Vector3& texTangent = texTangents[j]->tangent; texTangentSource.appendValues ( texTangent.x, texTangent.y, texTangent.z ); } texTangentSource.finish(); // texbinormals - size_t texBinormalsCount = texBinormals.size(); + size_t texBinormalsCount = texTangentsCount; COLLADASW::FloatSource texBinormalSource ( mGeometriesExporter->mSW ); String texBinormalSourceId = mId + getTexbinormalSourceIdSuffix( channelIndex ); texBinormalSource.setId ( texBinormalSourceId ); @@ -981,11 +991,12 @@ for ( size_t j = 0; j < texBinormalsCount; ++j) { - Point3& texBinormal = texBinormals[j]; + COLLADABU::Math::Vector3& texBinormal = texTangents[j]->biTangent; texBinormalSource.appendValues ( texBinormal.x, texBinormal.y, texBinormal.z ); } texBinormalSource.finish(); + texTangentCalculator->clearTexTangentData(); } } @@ -1018,10 +1029,12 @@ for ( ChannelList::const_iterator it = channelList.begin(); it != channelList.end(); ++it ) { - triangles.getInputList().push_back ( COLLADASW::Input ( ( *it <= 0 ) ? COLLADASW::COLOR : COLLADASW::TEXCOORD, "#" + mId + getTextureSourceIdSuffix ( *it ), offset++, *it ) ); - if ( mExportTextangentsAndNormals && ( *it > 0 ) ) + int channelIndex = *it; + triangles.getInputList().push_back ( COLLADASW::Input ( ( channelIndex <= 0 ) ? COLLADASW::COLOR : COLLADASW::TEXCOORD, "#" + mId + getTextureSourceIdSuffix ( channelIndex ), offset++, channelIndex ) ); + if ( mExportTextangentsAndNormals && ( channelIndex > 0 ) ) { - triangles.getInputList().push_back ( COLLADASW::Input ( COLLADASW::TEXTANGENT, "#" + mId + getTextureSourceIdSuffix ( *it ), offset++, *it ) ); + triangles.getInputList().push_back ( COLLADASW::Input ( COLLADASW::TEXTANGENT, "#" + mId + getTextangentSourceIdSuffix( channelIndex ), offset, channelIndex ) ); + triangles.getInputList().push_back ( COLLADASW::Input ( COLLADASW::TEXBINORMAL, "#" + mId + getTexbinormalSourceIdSuffix( channelIndex ), offset++, channelIndex ) ); } } @@ -1046,6 +1059,13 @@ MeshMap & tmap = mesh.Map ( channel ); TVFace& tvFace = tmap.tf[ faceIndex ]; triangles.appendValues ( tvFace.t[ vertexIndex ] ); + + if ( mExportTextangentsAndNormals && ( channel > 0 ) ) + { + const TexTangentCalculator* texTangentCalculator = mChannelIndexTexTangentCalculatorMap[channel]; + const TexTangentCalculator::IndicesList& indices = texTangentCalculator->getIndices(); + triangles.appendValues ( indices[ 3*faceIndex + vertexIndex ] ); + } } } } @@ -1166,57 +1186,11 @@ - //--------------------------------------------------------------- - void GeometryExporter::calculateTriangleMeshTextangentsAndTexbinormals(int channelIndex, - Point3List& texTangents, - Point3List& texBinormals) - { - Mesh mesh = mTriObject->GetMesh(); - int numFaces = mesh.getNumFaces(); - Point3 geometryVertex[3]; - Point3 textureVertex[3]; - Point3 basisVectors[2]; + - MeshMap& meshMap = mTriObject->GetMesh().Map ( channelIndex ); + - TVFace* mapFaces = meshMap.tf; - UVVert* mapVerts = meshMap.tv; - texTangents.clear(); - texTangents.reserve( 3*numFaces ); - texBinormals.clear(); - texBinormals.reserve( 3*numFaces ); - for ( int i = 0; i < numFaces; ++i) - { - - Face& geomFace = mesh.faces[i]; - geometryVertex[0] = mesh.verts[ geomFace.v[0] ]; - geometryVertex[1] = mesh.verts[ geomFace.v[1] ]; - geometryVertex[2] = mesh.verts[ geomFace.v[2] ]; - - - TVFace& mapFace = mapFaces[i]; - textureVertex[0] = mapVerts[ mapFace.t[0] ]; - textureVertex[1] = mapVerts[ mapFace.t[1] ]; - textureVertex[2] = mapVerts[ mapFace.t[2] ]; - - ComputeTangentAndBinormal( textureVertex, geometryVertex, basisVectors ); - - Point3 mapNormal = FNormalize( (textureVertex[1] - textureVertex[0]) ^ (textureVertex[2] - textureVertex[1]) ); - if( mapNormal.z<0 ) - { - basisVectors[1] = -basisVectors[1]; //is the UV face flipped? flip the binormal - } - - texTangents.push_back(basisVectors[0]); - texBinormals.push_back(basisVectors[1]); - } - - } - - - - } Added: branches/nextgen/COLLADAMax/src/COLLADAMaxTexTangentCalculator.cpp =================================================================== --- branches/nextgen/COLLADAMax/src/COLLADAMaxTexTangentCalculator.cpp (rev 0) +++ branches/nextgen/COLLADAMax/src/COLLADAMaxTexTangentCalculator.cpp 2009-02-24 10:19:30 UTC (rev 371) @@ -0,0 +1,241 @@ +/* +Copyright (c) 2008 NetAllied Systems GmbH + +This file is part of COLLADAMax. + +Portions of the code are: +Copyright (c) 2005-2007 Feeling Software Inc. +Copyright (c) 2005-2007 Sony Computer Entertainment America + +Based on the 3dsMax COLLADASW Tools: +Copyright (c) 2005-2006 Autodesk Media Entertainment + +Licensed under the MIT Open Source License, +for details please see LICENSE file or the website +http://www.opensource.org/licenses/mit-license.php +*/ + +#include "COLLADAMaxStableHeaders.h" +#include "COLLADAMaxTexTangentCalculator.h" + + + +namespace COLLADAMax +{ + + TexTangentCalculator::TexTangentCalculator( IMeshAccess* mesh ) + : mMesh(mesh) + , mTexTangentsCount(0) + { + } + + //------------------------------ + TexTangentCalculator::~TexTangentCalculator() + { + deleteTexTangentInfo(); + } + + + void TexTangentCalculator::computeTangent( Vector3 textureVertex[3], Vector3 geometryVertex[3], Vector3& texTangent ) + { + const Vector3& w1 = textureVertex[0]; + const Vector3& w2 = textureVertex[1]; + const Vector3& w3 = textureVertex[2]; + + const Vector3& v1 = geometryVertex[0]; + const Vector3& v2 = geometryVertex[1]; + const Vector3& v3 = geometryVertex[2]; + + Real x1 = v2.x - v1.x; + Real x2 = v3.x - v1.x; + Real y1 = v2.y - v1.y; + Real y2 = v3.y - v1.y; + Real z1 = v2.z - v1.z; + Real z2 = v3.z - v1.z; + + Real s1 = w2.x - w1.x; + Real s2 = w3.x - w1.x; + Real t1 = w2.y - w1.y; + Real t2 = w3.y - w1.y; + + Real r = (Real)1.0 / (s1 * t2 - s2 * t1); + texTangent.set( (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); + texTangent.normalise(); + // tDir.set( (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); + } + + + + //--------------------------------------------------------------- + void TexTangentCalculator::calculateTriangleMeshTextangents() + { + mTexTangents.clear(); + + //Mesh mesh = mTriObject->GetMesh(); + + int numFaces = mMesh->getFaceCount(); + + mIndices.reserve( numFaces * 3 ); + + Vector3 geometryVertex[3]; + Vector3 textureVertex[3]; + Vector3 normalVertex[3]; + Vector3 texTangent[3]; + Vector3 computetTexTangent; +/* Vector3 basisVectors[2]; + Vector3 basisVectors2[2]; + */ + +// MeshMap& meshMap = mTriObject->GetMesh().Map ( channelIndex ); + +// TVFace* mapFaces = meshMap.tf; +// UVVert* mapVerts = meshMap.tv; + + + for ( int i = 0; i < numFaces; ++i) + { +/* Face& geomFace = mesh.faces[i]; + int index1 = geomFace.v[0]; + int index2 = geomFace.v[1]; + int index3 = geomFace.v[2]; +*/ + int vertexIndex1 = mMesh->getPositionIndex(i, 0); + int vertexIndex2 = mMesh->getPositionIndex(i, 1); + int vertexIndex3 = mMesh->getPositionIndex(i, 2); + + geometryVertex[0] = mMesh->getVertex(vertexIndex1); + geometryVertex[1] = mMesh->getVertex(vertexIndex2); + geometryVertex[2] = mMesh->getVertex(vertexIndex3); + +/* TVFace& mapFace = mapFaces[i]; + textureVertex[0] = mapVerts[ mapFace.t[0] ]; + textureVertex[1] = mapVerts[ mapFace.t[1] ]; + textureVertex[2] = mapVerts[ mapFace.t[2] ]; +*/ + int textureIndex1 = mMesh->getTexcoordIndex(i, 0); + int textureIndex2 = mMesh->getTexcoordIndex(i, 1); + int textureIndex3 = mMesh->getTexcoordIndex(i, 2); + + textureVertex[0] = mMesh->getTexcoord( textureIndex1 ); + textureVertex[1] = mMesh->getTexcoord( textureIndex2 ); + textureVertex[2] = mMesh->getTexcoord( textureIndex3 ); + + computeTangent( textureVertex, geometryVertex, computetTexTangent ); + +/* Point3 mapNormal = FNormalize( (textureVertex[1] - textureVertex[0]) ^ (textureVertex[2] - textureVertex[1]) ); + if( mapNormal.z<0 ) + { + basisVectors[1] = -basisVectors[1]; //is the UV face flipped? flip the binormal + } +*/ + + int normalIndex1 = mMesh->getNormalIndex(i, 0); + int normalIndex2 = mMesh->getNormalIndex(i, 1); + int normalIndex3 = mMesh->getNormalIndex(i, 2); + + normalVertex[0] = mMesh->getNormal( normalIndex1 ); + normalVertex[1] = mMesh->getNormal( normalIndex2 ); + normalVertex[2] = mMesh->getNormal( normalIndex3 ); + + texTangent[0] = computetTexTangent - normalVertex[0] * (normalVertex[0].dotProduct(computetTexTangent)); + texTangent[1] = computetTexTangent - normalVertex[1] * (normalVertex[1].dotProduct(computetTexTangent)); + texTangent[2] = computetTexTangent - normalVertex[2] * (normalVertex[2].dotProduct(computetTexTangent)); + + mIndices.push_back(addTexTangent( vertexIndex1, normalIndex1, textureIndex1, texTangent[0] )); + mIndices.push_back(addTexTangent( vertexIndex2, normalIndex2, textureIndex2, texTangent[1] )); + mIndices.push_back(addTexTangent( vertexIndex3, normalIndex3, textureIndex3, texTangent[2] )); + + } + + normalizeTangentsAndCalculateBiTangents(); + } + + //--------------------------------------------------------------- + unsigned long TexTangentCalculator::addTexTangent( int vertexIndex, int normalIndex, int textureIndex, const Vector3& texTangent ) + { + VertexIdentifier vertexIdentifier; + vertexIdentifier.positionIndex = vertexIndex; + vertexIdentifier.normalIndex = normalIndex; + vertexIdentifier.textureIndex = textureIndex; + VertexIdentifierVertexTexTangentInfoMap::iterator it = mVertexIdentifierVertexTexTangentInfoMap.find(vertexIdentifier); + if ( it == mVertexIdentifierVertexTexTangentInfoMap.end() ) + { + VertexTexTangentInfo* vertexTexTangentInfo = new VertexTexTangentInfo; + vertexTexTangentInfo->tangent = texTangent; + vertexTexTangentInfo->count = 1; + vertexTexTangentInfo->index = mTexTangentsCount++; + mTexTangents.push_back(vertexTexTangentInfo); + mVertexIdentifierVertexTexTangentInfoMap.insert(std::make_pair(vertexIdentifier, vertexTexTangentInfo)); + return vertexTexTangentInfo->index; + } + else + { + VertexTexTangentInfo& vertexTexTangentInfo = *it->second; + vertexTexTangentInfo.tangent += texTangent; + vertexTexTangentInfo.count++; + return vertexTexTangentInfo.index; + } + } + + //--------------------------------------------------------------- + void TexTangentCalculator::normalizeTangentsAndCalculateBiTangents() + { + VertexIdentifierVertexTexTangentInfoMap::iterator it = mVertexIdentifierVertexTexTangentInfoMap.begin(); + VertexIdentifierVertexTexTangentInfoMap::iterator endIt = mVertexIdentifierVertexTexTangentInfoMap.end(); + for ( ; it != endIt; ++it) + { + VertexTexTangentInfo& vertexTexTangentInfo = *it->second; + vertexTexTangentInfo.tangent = vertexTexTangentInfo.tangent / (Real)(vertexTexTangentInfo.count); + + const VertexIdentifier& vertexIdentifier = it->first; + Vector3 normal = mMesh->getNormal( vertexIdentifier.normalIndex ); + + vertexTexTangentInfo.biTangent = vertexTexTangentInfo.tangent.crossProduct( normal ); + vertexTexTangentInfo.biTangent.normalise(); + } + } + + //--------------------------------------------------------------- + void TexTangentCalculator::clearTexTangentData() + { + mTexTangents.clear(); + deleteTexTangentInfo(); + mVertexIdentifierVertexTexTangentInfoMap.clear(); + } + + //--------------------------------------------------------------- + void TexTangentCalculator::deleteTexTangentInfo() + { + VertexIdentifierVertexTexTangentInfoMap::iterator it = mVertexIdentifierVertexTexTangentInfoMap.begin(); + VertexIdentifierVertexTexTangentInfoMap::iterator endIt = mVertexIdentifierVertexTexTangentInfoMap.end(); + for ( ; it != endIt; ++it) + { + delete it->second; + } + } + + //--------------------------------------------------------------- + bool TexTangentCalculator::VertexIdentifier::operator<( const VertexIdentifier& rhs ) const + { + if ( positionIndex < rhs.positionIndex ) + return true; + + if ( positionIndex > rhs.positionIndex ) + return false; + + if ( normalIndex < rhs.normalIndex ) + return true; + + if ( normalIndex > rhs.normalIndex ) + return false; + + if ( textureIndex < rhs.textureIndex ) + return true; + + if ( textureIndex > rhs.textureIndex ) + return false; + + return false; + } + +} // namespace COLLADAMax Modified: branches/nextgen/COLLADAStreamWriter/include/COLLADASWConstants.h =================================================================== --- branches/nextgen/COLLADAStreamWriter/include/COLLADASWConstants.h 2009-02-20 15:55:04 UTC (rev 370) +++ branches/nextgen/COLLADAStreamWriter/include/COLLADASWConstants.h 2009-02-24 10:19:30 UTC (rev 371) @@ -259,7 +259,9 @@ static const String CSW_SEMANTIC_OUTPUT; static const String CSW_SEMANTIC_OUT_TANGENT; static const String CSW_SEMANTIC_POSITION; - static const String CSW_SEMANTIC_TEXCOORD; + static const String CSW_SEMANTIC_TEXCOORD; + static const String CSW_SEMANTIC_TEXTANGENT; + static const String CSW_SEMANTIC_TEXBINORMAL; static const String CSW_SEMANTIC_VERTEX; static const String CSW_SEMANTIC_WEIGHT; Modified: branches/nextgen/COLLADAStreamWriter/src/COLLADASWConstants.cpp =================================================================== --- branches/nextgen/COLLADAStreamWriter/src/COLLADASWConstants.cpp 2009-02-20 15:55:04 UTC (rev 370) +++ branches/nextgen/COLLADAStreamWriter/src/COLLADASWConstants.cpp 2009-02-24 10:19:30 UTC (rev 371) @@ -249,7 +249,9 @@ const String CSWC::CSW_SEMANTIC_OUTPUT = "OUTPUT"; const String CSWC::CSW_SEMANTIC_OUT_TANGENT = "OUT_TANGENT"; const String CSWC::CSW_SEMANTIC_POSITION = "POSITION"; - const String CSWC::CSW_SEMANTIC_TEXCOORD = "TEXCOORD"; + const String CSWC::CSW_SEMANTIC_TEXCOORD = "TEXCOORD"; + const String CSWC::CSW_SEMANTIC_TEXTANGENT = "TEXTANGENT"; + const String CSWC::CSW_SEMANTIC_TEXBINORMAL = "TEXBINORMAL"; const String CSWC::CSW_SEMANTIC_VERTEX = "VERTEX"; const String CSWC::CSW_SEMANTIC_WEIGHT = "WEIGHT"; Modified: branches/nextgen/COLLADAStreamWriter/src/COLLADASWInputList.cpp =================================================================== --- branches/nextgen/COLLADAStreamWriter/src/COLLADASWInputList.cpp 2009-02-20 15:55:04 UTC (rev 370) +++ branches/nextgen/COLLADAStreamWriter/src/COLLADASWInputList.cpp 2009-02-24 10:19:30 UTC (rev 371) @@ -52,9 +52,15 @@ case NORMAL: return CSWC::CSW_SEMANTIC_NORMAL; - case TEXCOORD: - return CSWC::CSW_SEMANTIC_TEXCOORD; + case TEXCOORD: + return CSWC::CSW_SEMANTIC_TEXCOORD; + case TEXTANGENT: + return CSWC::CSW_SEMANTIC_TEXTANGENT; + + case TEXBINORMAL: + return CSWC::CSW_SEMANTIC_TEXBINORMAL; + case COLOR: return CSWC::CSW_SEMANTIC_COLOR; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |