Merge remote-tracking branch 'official/master' into contrib

pull/261/head
Léo Terziman 2014-03-10 17:21:26 +01:00
commit 8fad549649
7 changed files with 115 additions and 46 deletions

View File

@ -142,3 +142,6 @@ Rewrite of PyAssimp, distutils and Python3 support
- albert-wang - albert-wang
Bugfixes for the collada parser Bugfixes for the collada parser
- Ya ping Jin
Bugfixes for uv-tanget calculation.

View File

@ -467,34 +467,41 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
const unsigned int iIndex = iArray[i]; const unsigned int iIndex = iArray[i];
aiMesh* const mesh = pcSOut->mMeshes[iIndex]; aiMesh* const mesh = pcSOut->mMeshes[iIndex];
// Transform the vertices back into their local space if (mesh->mColors[1] == NULL)
// fixme: consider computing normals after this, so we don't need to transform them
const aiVector3D* const pvEnd = mesh->mVertices+mesh->mNumVertices;
aiVector3D* pvCurrent = mesh->mVertices, *t2 = mesh->mNormals;
for (;pvCurrent != pvEnd;++pvCurrent,++t2) {
*pvCurrent = mInv * (*pvCurrent);
*t2 = mInvTransposed * (*t2);
}
// Handle negative transformation matrix determinant -> invert vertex x
if (imesh->mMat.Determinant() < 0.0f)
{ {
/* we *must* have normals */ // Transform the vertices back into their local space
for (pvCurrent = mesh->mVertices,t2 = mesh->mNormals;pvCurrent != pvEnd;++pvCurrent,++t2) { // fixme: consider computing normals after this, so we don't need to transform them
pvCurrent->x *= -1.f; const aiVector3D* const pvEnd = mesh->mVertices + mesh->mNumVertices;
t2->x *= -1.f; aiVector3D* pvCurrent = mesh->mVertices, *t2 = mesh->mNormals;
}
DefaultLogger::get()->info("3DS: Flipping mesh X-Axis");
}
// Handle pivot point for (; pvCurrent != pvEnd; ++pvCurrent, ++t2) {
if(pivot.x || pivot.y || pivot.z) *pvCurrent = mInv * (*pvCurrent);
{ *t2 = mInvTransposed * (*t2);
for (pvCurrent = mesh->mVertices;pvCurrent != pvEnd;++pvCurrent) {
*pvCurrent -= pivot;
} }
// Handle negative transformation matrix determinant -> invert vertex x
if (imesh->mMat.Determinant() < 0.0f)
{
/* we *must* have normals */
for (pvCurrent = mesh->mVertices, t2 = mesh->mNormals; pvCurrent != pvEnd; ++pvCurrent, ++t2) {
pvCurrent->x *= -1.f;
t2->x *= -1.f;
}
DefaultLogger::get()->info("3DS: Flipping mesh X-Axis");
}
// Handle pivot point
if (pivot.x || pivot.y || pivot.z)
{
for (pvCurrent = mesh->mVertices; pvCurrent != pvEnd; ++pvCurrent) {
*pvCurrent -= pivot;
}
}
mesh->mColors[1] = (aiColor4D*)1;
} }
else
mesh->mColors[1] = (aiColor4D*)1;
// Setup the mesh index // Setup the mesh index
pcOut->mMeshes[i] = iIndex; pcOut->mMeshes[i] = iIndex;
@ -502,7 +509,17 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
} }
// Setup the name of the node // Setup the name of the node
pcOut->mName.Set(pcIn->mName); // First instance keeps its name otherwise something might break, all others will be postfixed with their instance number
if (pcIn->mInstanceNumber > 1)
{
char tmp[12];
ASSIMP_itoa10(tmp, pcIn->mInstanceNumber);
std::string tempStr = pcIn->mName + "_inst_";
tempStr += tmp;
pcOut->mName.Set(tempStr);
}
else
pcOut->mName.Set(pcIn->mName);
// Now build the transformation matrix of the node // Now build the transformation matrix of the node
// ROTATION // ROTATION
@ -784,9 +801,12 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m); AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m);
} }
// We used the first vertex color set to store some emporary values so we need to cleanup here // We used the first and second vertex color set to store some temporary values so we need to cleanup here
for (unsigned int a = 0; a < pcOut->mNumMeshes;++a) for (unsigned int a = 0; a < pcOut->mNumMeshes; ++a)
{
pcOut->mMeshes[a]->mColors[0] = NULL; pcOut->mMeshes[a]->mColors[0] = NULL;
pcOut->mMeshes[a]->mColors[1] = NULL;
}
pcOut->mRootNode->mTransformation = aiMatrix4x4( pcOut->mRootNode->mTransformation = aiMatrix4x4(
1.f,0.f,0.f,0.f, 1.f,0.f,0.f,0.f,

View File

@ -481,6 +481,7 @@ struct Node
: mHierarchyPos (0) : mHierarchyPos (0)
, mHierarchyIndex (0) , mHierarchyIndex (0)
, mInstanceCount (1)
{ {
static int iCnt = 0; static int iCnt = 0;
@ -510,6 +511,9 @@ struct Node
//! Name of the node //! Name of the node
std::string mName; std::string mName;
//! InstanceNumber of the node
int32_t mInstanceNumber;
//! Dummy nodes: real name to be combined with the $$$DUMMY //! Dummy nodes: real name to be combined with the $$$DUMMY
std::string mDummyName; std::string mDummyName;
@ -539,6 +543,9 @@ struct Node
//! Pivot position loaded from the file //! Pivot position loaded from the file
aiVector3D vPivot; aiVector3D vPivot;
//instance count, will be kept only for the first node
int32_t mInstanceCount;
//! Add a child node, setup the right parent node for it //! Add a child node, setup the right parent node for it
//! \param pc Node to be 'adopted' //! \param pc Node to be 'adopted'
inline Node& push_back(Node* pc) inline Node& push_back(Node* pc)

View File

@ -659,14 +659,22 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
// Now find out whether we have this node already (target animation channels // Now find out whether we have this node already (target animation channels
// are stored with a separate object ID) // are stored with a separate object ID)
D3DS::Node* pcNode = FindNode(mRootNode,name); D3DS::Node* pcNode = FindNode(mRootNode,name);
if (pcNode) int instanceNumber = 1;
if ( pcNode)
{ {
// Make this node the current node // if the source is not a CHUNK_TRACKINFO block it wont be an object instance
mCurrentNode = pcNode; if (parent != Discreet3DS::CHUNK_TRACKINFO)
break; {
mCurrentNode = pcNode;
break;
}
pcNode->mInstanceCount++;
instanceNumber = pcNode->mInstanceCount;
} }
pcNode = new D3DS::Node(); pcNode = new D3DS::Node();
pcNode->mName = name; pcNode->mName = name;
pcNode->mInstanceNumber = instanceNumber;
// There are two unknown values which we can safely ignore // There are two unknown values which we can safely ignore
stream->IncPtr(4); stream->IncPtr(4);

View File

@ -711,6 +711,11 @@ SET_TARGET_PROPERTIES( assimp PROPERTIES
SOVERSION ${ASSIMP_SOVERSION} # use full version SOVERSION ${ASSIMP_SOVERSION} # use full version
OUTPUT_NAME assimp${ASSIMP_LIBRARY_SUFFIX} OUTPUT_NAME assimp${ASSIMP_LIBRARY_SUFFIX}
) )
if (APPLE)
SET_TARGET_PROPERTIES( assimp PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}")
endif()
# Build against external unzip, or add ../contrib/unzip so # Build against external unzip, or add ../contrib/unzip so
# assimp can #include "unzip.h" # assimp can #include "unzip.h"
if (UNZIP_FOUND) if (UNZIP_FOUND)

View File

@ -55,8 +55,9 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
CalcTangentsProcess::CalcTangentsProcess() CalcTangentsProcess::CalcTangentsProcess()
{ : configMaxAngle( AI_DEG_TO_RAD(45.f) )
this->configMaxAngle = AI_DEG_TO_RAD(45.f); , configSourceUV( 0 ) {
// nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -77,6 +78,8 @@ bool CalcTangentsProcess::IsActive( unsigned int pFlags) const
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void CalcTangentsProcess::SetupProperties(const Importer* pImp) void CalcTangentsProcess::SetupProperties(const Importer* pImp)
{ {
ai_assert( NULL != pImp );
// get the current value of the property // get the current value of the property
configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f); configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f);
configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f); configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f);
@ -89,14 +92,20 @@ void CalcTangentsProcess::SetupProperties(const Importer* pImp)
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void CalcTangentsProcess::Execute( aiScene* pScene) void CalcTangentsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("CalcTangentsProcess begin"); ai_assert( NULL != pScene );
DefaultLogger::get()->debug("CalcTangentsProcess begin");
bool bHas = false; bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) {
if(ProcessMesh( pScene->mMeshes[a],a))bHas = true; if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
}
if (bHas)DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated"); if ( bHas ) {
else DefaultLogger::get()->debug("CalcTangentsProcess finished"); DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated");
} else {
DefaultLogger::get()->debug("CalcTangentsProcess finished");
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -179,9 +188,14 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y; float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y;
float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y; float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f; float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
// when t1, t2, t3 in same position in UV space, just use default UV direction.
if ( 0 == sx && 0 ==sy && 0 == tx && 0 == ty ) {
sx = 0.0; sy = 1.0;
tx = 1.0; ty = 0.0;
}
// tangent points in the direction where to positive X axis of the texture coords would point in model space // tangent points in the direction where to positive X axis of the texture coord's would point in model space
// bitangents points along the positive Y axis of the texture coords, respectively // bitangent's points along the positive Y axis of the texture coord's, respectively
aiVector3D tangent, bitangent; aiVector3D tangent, bitangent;
tangent.x = (w.x * sy - v.x * ty) * dirCorrection; tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
tangent.y = (w.y * sy - v.y * ty) * dirCorrection; tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
@ -191,8 +205,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
bitangent.z = (w.z * sx - v.z * tx) * dirCorrection; bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
// store for every vertex of that face // store for every vertex of that face
for( unsigned int b = 0; b < face.mNumIndices; b++) for( unsigned int b = 0; b < face.mNumIndices; ++b ) {
{
unsigned int p = face.mIndices[b]; unsigned int p = face.mIndices[b];
// project tangent and bitangent into the plane formed by the vertex' normal // project tangent and bitangent into the plane formed by the vertex' normal
@ -200,9 +213,22 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]); aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
localTangent.Normalize(); localBitangent.Normalize(); localTangent.Normalize(); localBitangent.Normalize();
// and write it into the mesh. // reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN.
meshTang[p] = localTangent; bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z);
meshBitang[p] = localBitangent; bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z);
if (invalid_tangent != invalid_bitangent) {
if (invalid_tangent) {
localTangent = meshNorm[p] ^ localBitangent;
localTangent.Normalize();
} else {
localBitangent = localTangent ^ meshNorm[p];
localBitangent.Normalize();
}
}
// and write it into the mesh.
meshTang[ p ] = localTangent;
meshBitang[ p ] = localBitangent;
} }
} }

View File

@ -380,7 +380,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ComputeUVMappingProcess::ComputeBoxMapping(aiMesh* /*mesh*/, aiVector3D* /*out*/) void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* )
{ {
DefaultLogger::get()->error("Mapping type currently not implemented"); DefaultLogger::get()->error("Mapping type currently not implemented");
} }