Minor changes to the logger (was necessary for the integration of jAssimp)
Fixed face winding bugs (cw now ...) jAssimp incremental Update 3DS hierarchy bug fixed Added "MakeVerboseFormat" postprocess step Viewer bugfixes git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@41 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
@@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
/** @file Implementation of the 3ds importer class */
|
||||
#include "3DSLoader.h"
|
||||
#include "MaterialSystem.h"
|
||||
#include "DefaultLogger.h"
|
||||
|
||||
#include "../include/IOStream.h"
|
||||
#include "../include/IOSystem.h"
|
||||
@@ -98,11 +99,18 @@ void Dot3DSImporter::ReplaceDefaultMaterial()
|
||||
{
|
||||
// NOTE: The additional check seems to be necessary,
|
||||
// some exporters seem to generate invalid data here
|
||||
if (0xcdcdcdcd == (*a) || (*a) >= this->mScene->mMaterials.size())
|
||||
if (0xcdcdcdcd == (*a))
|
||||
{
|
||||
(*a) = iIndex;
|
||||
++iCnt;
|
||||
}
|
||||
else if ( (*a) >= this->mScene->mMaterials.size())
|
||||
{
|
||||
(*a) = iIndex;
|
||||
++iCnt;
|
||||
DefaultLogger::get()->warn("Material index overflow in 3DS file. Assigning "
|
||||
"default material ...");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0 != iCnt && iIndex == this->mScene->mMaterials.size())
|
||||
@@ -125,14 +133,17 @@ void Dot3DSImporter::CheckIndices(Dot3DS::Mesh* sMesh)
|
||||
// check whether all indices are in range
|
||||
if ((*i).i1 >= sMesh->mPositions.size())
|
||||
{
|
||||
DefaultLogger::get()->warn("Face index overflow in 3DS file (#1)");
|
||||
(*i).i1 = sMesh->mPositions.size()-1;
|
||||
}
|
||||
if ((*i).i2 >= sMesh->mPositions.size())
|
||||
{
|
||||
DefaultLogger::get()->warn("Face index overflow in 3DS file (#2)");
|
||||
(*i).i2 = sMesh->mPositions.size()-1;
|
||||
}
|
||||
if ((*i).i3 >= sMesh->mPositions.size())
|
||||
{
|
||||
DefaultLogger::get()->warn("Face index overflow in 3DS file (#3)");
|
||||
(*i).i3 = sMesh->mPositions.size()-1;
|
||||
}
|
||||
}
|
||||
@@ -155,31 +166,55 @@ void Dot3DSImporter::MakeUnique(Dot3DS::Mesh* sMesh)
|
||||
vNew2.resize(sMesh->mFaces.size() * 3);
|
||||
for (unsigned int i = 0; i < sMesh->mFaces.size();++i)
|
||||
{
|
||||
uint32_t iTemp1,iTemp2;
|
||||
|
||||
// position and texture coordinates
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
|
||||
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i1];
|
||||
sMesh->mFaces[i].i1 = iBase++;
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i3];
|
||||
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i3];
|
||||
iTemp1 = iBase++;
|
||||
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i2];
|
||||
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i2];
|
||||
sMesh->mFaces[i].i2 = iBase++;
|
||||
iTemp2 = iBase++;
|
||||
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i3];
|
||||
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i3];
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
|
||||
vNew2[iBase] = sMesh->mTexCoords[sMesh->mFaces[i].i1];
|
||||
sMesh->mFaces[i].i3 = iBase++;
|
||||
|
||||
sMesh->mFaces[i].i1 = iTemp1;
|
||||
sMesh->mFaces[i].i2 = iTemp2;
|
||||
|
||||
// handle the face order ...
|
||||
/*if (iTemp1 > iTemp2)
|
||||
{
|
||||
sMesh->mFaces[i].bFlipped = true;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int i = 0; i < sMesh->mFaces.size();++i)
|
||||
{
|
||||
uint32_t iTemp1,iTemp2;
|
||||
|
||||
// position only
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
|
||||
sMesh->mFaces[i].i1 = iBase++;
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i2];
|
||||
sMesh->mFaces[i].i2 = iBase++;
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i3];
|
||||
iTemp1 = iBase++;
|
||||
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i2];
|
||||
iTemp2 = iBase++;
|
||||
|
||||
vNew[iBase] = sMesh->mPositions[sMesh->mFaces[i].i1];
|
||||
sMesh->mFaces[i].i3 = iBase++;
|
||||
|
||||
sMesh->mFaces[i].i1 = iTemp1;
|
||||
sMesh->mFaces[i].i2 = iTemp2;
|
||||
|
||||
// handle the face order ...
|
||||
/*if (iTemp1 > iTemp2)
|
||||
{
|
||||
sMesh->mFaces[i].bFlipped = true;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
sMesh->mPositions = vNew;
|
||||
@@ -216,9 +251,16 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
|
||||
mat.AddProperty( &oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||
mat.AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
mat.AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
|
||||
mat.AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
|
||||
mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
|
||||
|
||||
// phong shininess and shininess strength
|
||||
if (Dot3DS::Dot3DSFile::Phong == oldMat.mShading ||
|
||||
Dot3DS::Dot3DSFile::Metal == oldMat.mShading)
|
||||
{
|
||||
mat.AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
|
||||
mat.AddProperty( &oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
|
||||
}
|
||||
|
||||
// opacity
|
||||
mat.AddProperty<float>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
|
||||
|
||||
@@ -231,8 +273,6 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
|
||||
{
|
||||
case Dot3DS::Dot3DSFile::Flat:
|
||||
eShading = aiShadingMode_Flat; break;
|
||||
case Dot3DS::Dot3DSFile::Phong :
|
||||
eShading = aiShadingMode_Phong; break;
|
||||
|
||||
// I don't know what "Wire" shading should be,
|
||||
// assume it is simple lambertian diffuse (L dot N) shading
|
||||
@@ -243,6 +283,9 @@ void Dot3DSImporter::ConvertMaterial(Dot3DS::Material& oldMat,
|
||||
// assume cook-torrance shading for metals.
|
||||
// NOTE: I assume the real shader inside 3ds max is an anisotropic
|
||||
// Phong-Blinn shader, but this is a good approximation too
|
||||
case Dot3DS::Dot3DSFile::Phong :
|
||||
eShading = aiShadingMode_Phong; break;
|
||||
|
||||
case Dot3DS::Dot3DSFile::Metal :
|
||||
eShading = aiShadingMode_CookTorrance; break;
|
||||
}
|
||||
@@ -361,9 +404,8 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||
else aiSplit[*a].push_back(iNum);
|
||||
}
|
||||
// now generate submeshes
|
||||
#if 0
|
||||
|
||||
bool bFirst = true;
|
||||
#endif
|
||||
for (unsigned int p = 0; p < this->mScene->mMaterials.size();++p)
|
||||
{
|
||||
if (aiSplit[p].size() != 0)
|
||||
@@ -377,7 +419,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||
p_pcOut->mColors[0] = (aiColor4D*)new std::string((*i).mName);
|
||||
avOutMeshes.push_back(p_pcOut);
|
||||
|
||||
#if 0
|
||||
|
||||
if (bFirst)
|
||||
{
|
||||
p_pcOut->mColors[1] = (aiColor4D*)new aiMatrix4x4();
|
||||
@@ -385,7 +427,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||
*((aiMatrix4x4*)p_pcOut->mColors[1]) = (*i).mMat;
|
||||
bFirst = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// convert vertices
|
||||
p_pcOut->mNumVertices = aiSplit[p].size()*3;
|
||||
@@ -408,7 +450,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||
p_pcOut->mFaces[q].mIndices = new unsigned int[3];
|
||||
p_pcOut->mFaces[q].mNumIndices = 3;
|
||||
|
||||
p_pcOut->mFaces[q].mIndices[0] = iBase;
|
||||
p_pcOut->mFaces[q].mIndices[2] = iBase;
|
||||
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i1];
|
||||
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i1];
|
||||
|
||||
@@ -416,7 +458,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i2];
|
||||
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i2];
|
||||
|
||||
p_pcOut->mFaces[q].mIndices[2] = iBase;
|
||||
p_pcOut->mFaces[q].mIndices[0] = iBase;
|
||||
p_pcOut->mVertices[iBase] = (*i).mPositions[(*i).mFaces[iIndex].i3];
|
||||
p_pcOut->mNormals[iBase++] = (*i).mNormals[(*i).mFaces[iIndex].i3];
|
||||
}
|
||||
@@ -505,7 +547,7 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
|
||||
for (unsigned int i = 0;i < iArray.size();++i)
|
||||
{
|
||||
const unsigned int iIndex = iArray[i];
|
||||
#if 0
|
||||
|
||||
if (NULL != pcSOut->mMeshes[iIndex]->mColors[1])
|
||||
{
|
||||
pcOut->mTransformation = *((aiMatrix4x4*)
|
||||
@@ -514,13 +556,11 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
|
||||
delete (aiMatrix4x4*)pcSOut->mMeshes[iIndex]->mColors[1];
|
||||
pcSOut->mMeshes[iIndex]->mColors[1] = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
pcOut->mMeshes[i] = iIndex;
|
||||
}
|
||||
|
||||
// NOTE: Not necessary. We can use the given transformation matrix.
|
||||
// However, we'd need it if we wanted to implement keyframe animation
|
||||
|
||||
// (code for keyframe animation. however, this is currently not supported by Assimp)
|
||||
#if 0
|
||||
// build the scaling matrix. Toggle y and z axis
|
||||
aiMatrix4x4 mS;
|
||||
@@ -536,11 +576,34 @@ void Dot3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,Dot3DS::Node*
|
||||
|
||||
// build the pivot matrix. Toggle y and z axis
|
||||
aiMatrix4x4 mP;
|
||||
mP.a4 = pcIn->vPivot.x;
|
||||
mP.b4 = pcIn->vPivot.z;
|
||||
mP.c4 = pcIn->vPivot.y;
|
||||
mP.a4 = -pcIn->vPivot.x;
|
||||
mP.b4 = -pcIn->vPivot.z;
|
||||
mP.c4 = -pcIn->vPivot.y;
|
||||
|
||||
|
||||
#endif
|
||||
// build a matrix to flip the z coordinate of the vertices
|
||||
aiMatrix4x4 mF;
|
||||
mF.c3 = -1.0f;
|
||||
|
||||
|
||||
// build the final matrix
|
||||
// NOTE: This should be the identity. Theoretically. In reality
|
||||
// there are many models with very funny local matrices and
|
||||
// very different keyframe values ... this is the only reason
|
||||
// why we extract the data from the first keyframe.
|
||||
pcOut->mTransformation = mF; /* mF * mT * pcIn->mRotation * mS * mP *
|
||||
pcOut->mTransformation.Inverse(); */
|
||||
|
||||
// (code for keyframe animation. however, this is currently not supported by Assimp)
|
||||
#if 0
|
||||
if (pcOut->mTransformation != mF)
|
||||
{
|
||||
DefaultLogger::get()->warn("The local transformation matrix of the "
|
||||
"3ds file does not match the first keyframe. Using the "
|
||||
"information from the keyframe.");
|
||||
}
|
||||
#endif
|
||||
pcOut->mTransformation = aiMatrix4x4(); // mT * pcIn->mRotation * mS * mP * pcOut->mTransformation.Inverse();
|
||||
|
||||
pcOut->mNumChildren = pcIn->mChildren.size();
|
||||
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
|
||||
@@ -748,6 +811,10 @@ void Dot3DSImporter::BakeScaleNOffset(
|
||||
{
|
||||
(*a)->iUVSrc = 0;
|
||||
}
|
||||
DefaultLogger::get()->error("There are too many "
|
||||
"combinations of different UV scaling/offset/rotation operations "
|
||||
"to generate an UV channel for each (maximum is 4). Using the "
|
||||
"first UV channel ...");
|
||||
continue;
|
||||
}
|
||||
const aiVector3D* pvBase = _pvBase;
|
||||
@@ -815,6 +882,9 @@ void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||
//
|
||||
unsigned int iCnt = 0;
|
||||
|
||||
DefaultLogger::get()->warn("No hierarchy information has been "
|
||||
"found in the file. A flat hierarchy tree is built ...");
|
||||
|
||||
pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes;
|
||||
pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mNumMeshes ];
|
||||
|
||||
@@ -827,7 +897,12 @@ void Dot3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||
pcNode->mMeshes = new unsigned int[1];
|
||||
pcNode->mMeshes[0] = i;
|
||||
pcNode->mNumMeshes = 1;
|
||||
pcNode->mName.Set("UNNAMED");
|
||||
|
||||
std::string s;
|
||||
std::stringstream ss(s);
|
||||
ss << "UNNAMED[" << i << + "]";
|
||||
|
||||
pcNode->mName.Set(s);
|
||||
|
||||
// add the new child to the parent node
|
||||
pcOut->mRootNode->mChildren[i] = pcNode;
|
||||
@@ -860,6 +935,7 @@ void Dot3DSImporter::ConvertScene(aiScene* pcOut)
|
||||
this->ConvertMeshes(pcOut);
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Dot3DSImporter::GenTexCoord (Dot3DS::Texture* pcTexture,
|
||||
const std::vector<aiVector2D>& p_vIn,
|
||||
@@ -886,4 +962,5 @@ void Dot3DSImporter::GenTexCoord (Dot3DS::Texture* pcTexture,
|
||||
(*a).y += pcTexture->mOffsetV;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -59,7 +59,7 @@ void Dot3DSImporter::GenNormals(Dot3DS::Mesh* sMesh)
|
||||
sMesh->mNormals.resize(sMesh->mPositions.size(),aiVector3D());
|
||||
for( unsigned int a = 0; a < sMesh->mFaces.size(); a++)
|
||||
{
|
||||
const Dot3DS::Face& face = sMesh->mFaces[a];
|
||||
Dot3DS::Face& face = sMesh->mFaces[a];
|
||||
|
||||
// assume it is a triangle
|
||||
aiVector3D* pV1 = &sMesh->mPositions[face.i1];
|
||||
|
||||
@@ -199,6 +199,7 @@ public:
|
||||
// Specifies the shininess of the material
|
||||
// followed by percentage chunk
|
||||
CHUNK_MAT_SHININESS = 0xA040,
|
||||
CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
|
||||
|
||||
// Specifies the shading mode to be used
|
||||
// followed by a short
|
||||
@@ -304,7 +305,7 @@ public:
|
||||
/** Helper structure representing a 3ds mesh face */
|
||||
struct Face
|
||||
{
|
||||
Face() : iSmoothGroup(0), bDirection(true), i1(0), i2(0), i3(0)
|
||||
Face() : iSmoothGroup(0), i1(0), i2(0), i3(0), bFlipped(false)
|
||||
{
|
||||
// let the rest uninitialized for performance
|
||||
}
|
||||
@@ -327,9 +328,8 @@ struct Face
|
||||
//! specifies to which smoothing group the face belongs to
|
||||
uint32_t iSmoothGroup;
|
||||
|
||||
//! Direction the normal vector of the face
|
||||
//! will be pointing to
|
||||
bool bDirection;
|
||||
//! Specifies that the face normal must be flipped
|
||||
bool bFlipped;
|
||||
};
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Helper structure representing a texture */
|
||||
@@ -376,7 +376,8 @@ struct Material
|
||||
mTransparency (1.0f),
|
||||
mBumpHeight (1.0f),
|
||||
iBakeUVTransform (0),
|
||||
pcSingleTexture (NULL)
|
||||
pcSingleTexture (NULL),
|
||||
mShininessStrength (1.0f)
|
||||
{
|
||||
static int iCnt = 0;
|
||||
std::stringstream ss(mName);
|
||||
@@ -389,6 +390,8 @@ struct Material
|
||||
aiColor3D mDiffuse;
|
||||
//! Specular exponent
|
||||
float mSpecularExponent;
|
||||
//! Shininess strength, in percent
|
||||
float mShininessStrength;
|
||||
//! Specular color of the material
|
||||
aiColor3D mSpecular;
|
||||
//! Ambient color of the material
|
||||
@@ -462,9 +465,12 @@ struct Mesh
|
||||
struct Node
|
||||
{
|
||||
Node()
|
||||
|
||||
// (code for keyframe animation. however, this is currently not supported by Assimp)
|
||||
#if 0
|
||||
: vScaling(1.0f,1.0f,1.0f)
|
||||
#endif
|
||||
|
||||
{
|
||||
static int iCnt = 0;
|
||||
std::stringstream ss(mName);
|
||||
@@ -489,6 +495,7 @@ struct Node
|
||||
//! Index of the node
|
||||
int16_t mHierarchyIndex;
|
||||
|
||||
// (code for keyframe animation. however, this is currently not supported by Assimp)
|
||||
#if 0
|
||||
aiVector3D vPivot;
|
||||
aiVector3D vScaling;
|
||||
@@ -502,7 +509,7 @@ struct Node
|
||||
{
|
||||
mChildren.push_back(pc);
|
||||
pc->mParent = this;
|
||||
pc->mHierarchyPos = this->mHierarchyPos+1;
|
||||
//pc->mHierarchyPos = this->mHierarchyPos+1;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
/** @file Implementation of the 3ds importer class */
|
||||
#include "3DSLoader.h"
|
||||
#include "MaterialSystem.h"
|
||||
#include "DefaultLogger.h"
|
||||
|
||||
#include "../include/IOStream.h"
|
||||
#include "../include/IOSystem.h"
|
||||
@@ -59,7 +60,6 @@ using namespace Assimp;
|
||||
"specified in the higher-level chunk header." \
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
Dot3DSImporter::Dot3DSImporter()
|
||||
@@ -145,6 +145,7 @@ void Dot3DSImporter::InternReadFile(
|
||||
this->mMasterScale = 1.0f;
|
||||
this->mBackgroundImage = "";
|
||||
this->bHasBG = false;
|
||||
this->mErrorText = "";
|
||||
|
||||
int iRemaining = (unsigned int)fileSize;
|
||||
this->ParseMainChunk(&iRemaining);
|
||||
@@ -170,31 +171,10 @@ void Dot3DSImporter::InternReadFile(
|
||||
// Generate it if no material containing DEFAULT in its name has been
|
||||
// found in the file
|
||||
this->ReplaceDefaultMaterial();
|
||||
|
||||
try
|
||||
{
|
||||
// Convert the scene from our internal representation to an aiScene object
|
||||
this->ConvertScene(pScene);
|
||||
}
|
||||
catch (ImportErrorException ex)
|
||||
{
|
||||
// delete the scene itself
|
||||
if (pScene->mMeshes)
|
||||
{
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||
delete pScene->mMeshes[i];
|
||||
delete[] pScene->mMeshes;
|
||||
}
|
||||
if (pScene->mMaterials)
|
||||
{
|
||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
||||
delete pScene->mMaterials[i];
|
||||
delete[] pScene->mMaterials;
|
||||
}
|
||||
// there are no animations
|
||||
if (pScene->mRootNode)DeleteNodeRecursively(pScene->mRootNode);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// Convert the scene from our internal representation to an aiScene object
|
||||
this->ConvertScene(pScene);
|
||||
|
||||
|
||||
// Generate the node graph for the scene. This is a little bit
|
||||
// tricky since we'll need to split some meshes into submeshes
|
||||
@@ -205,6 +185,12 @@ void Dot3DSImporter::InternReadFile(
|
||||
|
||||
delete[] this->mBuffer;
|
||||
delete this->mScene;
|
||||
|
||||
// check whether an error occured during reading ... set it as warning
|
||||
if ("" != this->mErrorText)
|
||||
{
|
||||
DefaultLogger::get()->warn(this->mErrorText);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -532,7 +518,7 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
|
||||
const unsigned char* sz = (unsigned char*)this->mCurrent;
|
||||
unsigned int iCnt = 0;
|
||||
uint16_t iHierarchy;
|
||||
//uint16_t iTemp;
|
||||
// uint16_t iTemp;
|
||||
Dot3DS::Node* pcNode;
|
||||
switch (psChunk->Flag)
|
||||
{
|
||||
@@ -554,20 +540,28 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
|
||||
iHierarchy++;
|
||||
pcNode->mHierarchyPos = iHierarchy;
|
||||
pcNode->mHierarchyIndex = this->mLastNodeIndex;
|
||||
if (iHierarchy > this->mLastNodeIndex)
|
||||
if (this->mCurrentNode && this->mCurrentNode->mHierarchyPos == iHierarchy)
|
||||
{
|
||||
// add to the parent of the last touched node
|
||||
this->mCurrentNode->mParent->push_back(pcNode);
|
||||
this->mLastNodeIndex++;
|
||||
}
|
||||
else if(iHierarchy >= this->mLastNodeIndex)
|
||||
{
|
||||
// place it at the current position in the hierarchy
|
||||
this->mCurrentNode->push_back(pcNode);
|
||||
this->mLastNodeIndex = iHierarchy;
|
||||
}
|
||||
else
|
||||
{
|
||||
// need to go back to the specified position in the hierarchy.
|
||||
this->InverseNodeSearch(pcNode,this->mCurrentNode);
|
||||
this->mLastNodeIndex++;
|
||||
}
|
||||
this->mLastNodeIndex++;
|
||||
this->mCurrentNode = pcNode;
|
||||
break;
|
||||
|
||||
// (code for keyframe animation. however, this is currently not supported by Assimp)
|
||||
#if 0
|
||||
|
||||
case Dot3DSFile::CHUNK_TRACKPIVOT:
|
||||
@@ -651,42 +645,33 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
|
||||
if (0.0f != fRadians)
|
||||
{
|
||||
|
||||
// if the radians go beyond PI then the rotations
|
||||
// thereafter must be inversed
|
||||
#if 0
|
||||
if (neg)fRadians *= -1.0f;
|
||||
if ((fRadians >= 3.1415926f || fRadians <= -3.1415926f))
|
||||
{
|
||||
neg = !neg;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// get the rotation matrix around the axis
|
||||
const float fSin = sinf(-fRadians);
|
||||
const float fCos = cosf(-fRadians);
|
||||
const float fOneMinusCos = 1.0f - fCos;
|
||||
|
||||
std::swap(vAxis.z,vAxis.y);
|
||||
vAxis.Normalize();
|
||||
//vAxis.z *= -1.0f;
|
||||
//vAxis.Normalize();
|
||||
|
||||
aiMatrix4x4 mRot = aiMatrix4x4(
|
||||
(vAxis.x * vAxis.x) * fOneMinusCos + fCos,
|
||||
(vAxis.x * vAxis.y) * fOneMinusCos - (vAxis.z * fSin),
|
||||
(vAxis.x * vAxis.z) * fOneMinusCos + (vAxis.y * fSin),
|
||||
(vAxis.x * vAxis.y) * fOneMinusCos /*-*/- (vAxis.z * fSin),
|
||||
(vAxis.x * vAxis.z) * fOneMinusCos /*+*/+ (vAxis.y * fSin),
|
||||
0.0f,
|
||||
(vAxis.y * vAxis.x) * fOneMinusCos + (vAxis.z * fSin),
|
||||
(vAxis.y * vAxis.x) * fOneMinusCos /*+*/+ (vAxis.z * fSin),
|
||||
(vAxis.y * vAxis.y) * fOneMinusCos + fCos,
|
||||
(vAxis.y * vAxis.z) * fOneMinusCos - (vAxis.x * fSin),
|
||||
(vAxis.y * vAxis.z) * fOneMinusCos /*-*/- (vAxis.x * fSin),
|
||||
0.0f,
|
||||
(vAxis.z * vAxis.x) * fOneMinusCos - (vAxis.y * fSin),
|
||||
(vAxis.z * vAxis.y) * fOneMinusCos + (vAxis.x * fSin),
|
||||
(vAxis.z * vAxis.x) * fOneMinusCos /*-*/- (vAxis.y * fSin),
|
||||
(vAxis.z * vAxis.y) * fOneMinusCos /*+*/+ (vAxis.x * fSin),
|
||||
(vAxis.z * vAxis.z) * fOneMinusCos + fCos,
|
||||
0.0f,0.0f,0.0f,0.0f,1.0f);
|
||||
//mRot.Transpose();
|
||||
mRot.Transpose();
|
||||
|
||||
// build a chain of concatenated rotation matrix'
|
||||
// if there are multiple track chunks for the same frame
|
||||
// (there are some silly files usinf this ...)
|
||||
if (0 != iNum0)
|
||||
{
|
||||
this->mCurrentNode->mRotation = this->mCurrentNode->mRotation * mRot;
|
||||
@@ -739,14 +724,19 @@ void Dot3DSImporter::ParseHierarchyChunk(int* piRemaining)
|
||||
this->mCurrentNode->vScaling.y *= vMe.y;
|
||||
this->mCurrentNode->vScaling.z *= vMe.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultLogger::get()->warn("Found zero scaling factors. "
|
||||
"This will be ignored.");
|
||||
}
|
||||
this->mCurrent += sizeof(aiVector3D);
|
||||
}
|
||||
else this->mCurrent += sizeof(uint32_t) + sizeof(aiVector3D);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif // end keyframe animation code
|
||||
|
||||
#endif // 0
|
||||
};
|
||||
if ((unsigned int)pcCurNext < (unsigned int)this->mCurrent)
|
||||
{
|
||||
@@ -790,13 +780,6 @@ void Dot3DSImporter::ParseFaceChunk(int* piRemaining)
|
||||
{
|
||||
// nth bit is set for nth smoothing group
|
||||
(*i).iSmoothGroup = *((uint32_t*)this->mCurrent);
|
||||
#if 0
|
||||
for (unsigned int x = 0, a = 1; x < 32;++x,a <<= 1)
|
||||
{
|
||||
if ((*i).iSmoothGroup & a)
|
||||
mMesh.bSmoothGroupRequired[x] = true;
|
||||
}
|
||||
#endif
|
||||
this->mCurrent += sizeof(uint32_t);
|
||||
}
|
||||
break;
|
||||
@@ -955,10 +938,10 @@ void Dot3DSImporter::ParseMeshChunk(int* piRemaining)
|
||||
|
||||
aiMatrix4x4 mMe = mMesh.mMat;
|
||||
mMe.a1 *= -1.0f;
|
||||
mMe.a2 *= -1.0f;
|
||||
mMe.a3 *= -1.0f;
|
||||
mMe.a4 *= -1.0f;
|
||||
mInv = mMe * mInv;
|
||||
mMe.b1 *= -1.0f;
|
||||
mMe.c1 *= -1.0f;
|
||||
mMe.d1 *= -1.0f;
|
||||
mInv = mInv * mMe;
|
||||
for (register unsigned int i = 0; i < mMesh.mPositions.size();++i)
|
||||
{
|
||||
aiVector3D a,c;
|
||||
@@ -1007,8 +990,6 @@ void Dot3DSImporter::ParseMeshChunk(int* piRemaining)
|
||||
sFace.i3 = *((uint16_t*)this->mCurrent);
|
||||
this->mCurrent += 2*sizeof(uint16_t);
|
||||
mMesh.mFaces.push_back(sFace);
|
||||
|
||||
//if (sFace.i1 < sFace.i2)sFace.bDirection = false;
|
||||
}
|
||||
|
||||
// resize the material array (0xcdcdcdcd marks the
|
||||
@@ -1131,6 +1112,14 @@ void Dot3DSImporter::ParseMaterialChunk(int* piRemaining)
|
||||
else *pcf *= (float)0xFFFF;
|
||||
break;
|
||||
|
||||
case Dot3DSFile::CHUNK_MAT_SHININESS_PERCENT:
|
||||
pcf = &this->mScene->mMaterials.back().mShininessStrength;
|
||||
*pcf = this->ParsePercentageChunk();
|
||||
if (is_qnan(*pcf))
|
||||
*pcf = 0.0f;
|
||||
else *pcf *= (float)0xffff / 100.0f;
|
||||
break;
|
||||
|
||||
case Dot3DSFile::CHUNK_MAT_SELF_ILPCT:
|
||||
pcf = &this->mScene->mMaterials.back().sTexEmissive.mTextureBlend;
|
||||
*pcf = this->ParsePercentageChunk();
|
||||
|
||||
@@ -507,10 +507,12 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
|
||||
|
||||
for (unsigned int t = 0; t < 3;++t)
|
||||
{
|
||||
p_pcOut->mFaces[q].mIndices[t] = iBase;
|
||||
p_pcOut->mVertices[iBase] = mesh.mPositions[mesh.mFaces[iIndex].mIndices[t]];
|
||||
p_pcOut->mNormals[iBase++] = mesh.mNormals[mesh.mFaces[iIndex].mIndices[t]];
|
||||
}
|
||||
p_pcOut->mFaces[q].mIndices[0] = iBase-2;
|
||||
p_pcOut->mFaces[q].mIndices[1] = iBase-1;
|
||||
p_pcOut->mFaces[q].mIndices[2] = iBase;
|
||||
}
|
||||
}
|
||||
// convert texture coordinates
|
||||
|
||||
@@ -81,24 +81,39 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("CalcTangentsProcess begin");
|
||||
|
||||
bool bHas = false;
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
ProcessMesh( pScene->mMeshes[a]);
|
||||
if(ProcessMesh( pScene->mMeshes[a]))bHas = true;
|
||||
|
||||
DefaultLogger::get()->debug("CalcTangentsProcess finished");
|
||||
if (bHas)DefaultLogger::get()->debug("CalcTangentsProcess finished. There was much work to do ...");
|
||||
else DefaultLogger::get()->debug("CalcTangentsProcess finished");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Calculates tangents and bitangents for the given mesh
|
||||
void CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
|
||||
bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
|
||||
{
|
||||
// we assume that the mesh is still in the verbose vertex format where each face has its own set
|
||||
// of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
|
||||
// assert() it here.
|
||||
//assert( must be verbose, dammit);
|
||||
|
||||
// TODO (Aramis)
|
||||
// If we had a model format in the lib which has native support for
|
||||
// tangents and bitangents, it would be necessary to add a
|
||||
// "KillTangentsAndBitangents" flag ...
|
||||
if (pMesh->mTangents && pMesh->mBitangents)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// what we can check, though, is if the mesh has normals and texture coord. That's a requirement
|
||||
if( pMesh->mNormals == NULL || pMesh->mTextureCoords[0] == NULL)
|
||||
return;
|
||||
{
|
||||
DefaultLogger::get()->error("Normal vectors and at least one "
|
||||
"texture coordinate set are required to calculate tangents. ");
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate the position bounds so we have a reliable epsilon to check position differences against
|
||||
aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
|
||||
@@ -229,4 +244,5 @@ void CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
|
||||
meshBitang[ closeVertices[b] ] = smoothBitangent;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ protected:
|
||||
/** Calculates tangents and bitangents for the given mesh
|
||||
* @param pMesh The mesh to process.
|
||||
*/
|
||||
void ProcessMesh( aiMesh* pMesh);
|
||||
bool ProcessMesh( aiMesh* pMesh);
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
@@ -51,7 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
namespace Assimp
|
||||
{
|
||||
// ---------------------------------------------------------------------------
|
||||
DefaultLogger *DefaultLogger::m_pLogger = NULL;
|
||||
NullLogger DefaultLogger::s_pNullLogger;
|
||||
Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
@@ -72,17 +73,29 @@ struct LogStreamInfo
|
||||
// Creates the only singleton instance
|
||||
Logger *DefaultLogger::create(const std::string &name, LogSeverity severity)
|
||||
{
|
||||
ai_assert (NULL == m_pLogger);
|
||||
m_pLogger = new DefaultLogger( name, severity );
|
||||
|
||||
return m_pLogger;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
void DefaultLogger::set (Logger *logger)
|
||||
{
|
||||
if (!logger)
|
||||
{
|
||||
DefaultLogger::m_pLogger = &s_pNullLogger;
|
||||
return;
|
||||
}
|
||||
DefaultLogger::m_pLogger = logger;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
bool DefaultLogger::isNullLogger()
|
||||
{
|
||||
return m_pLogger == &s_pNullLogger;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Singleton getter
|
||||
Logger *DefaultLogger::get()
|
||||
{
|
||||
ai_assert (NULL != m_pLogger);
|
||||
return m_pLogger;
|
||||
}
|
||||
|
||||
@@ -92,7 +105,7 @@ void DefaultLogger::kill()
|
||||
{
|
||||
ai_assert (NULL != m_pLogger);
|
||||
delete m_pLogger;
|
||||
m_pLogger = NULL;
|
||||
m_pLogger = &s_pNullLogger;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -142,6 +155,22 @@ void DefaultLogger::setLogSeverity( LogSeverity log_severity )
|
||||
void DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
|
||||
{
|
||||
ai_assert ( NULL != pStream );
|
||||
|
||||
// fix (Aramis)
|
||||
if (0 == severity)
|
||||
{
|
||||
severity = Logger::INFO | Logger::ERR | Logger::WARN | Logger::DEBUGGING;
|
||||
}
|
||||
|
||||
for ( StreamIt it = m_StreamArray.begin();
|
||||
it != m_StreamArray.end();
|
||||
++it )
|
||||
{
|
||||
if ( (*it)->m_pStream == pStream )
|
||||
{
|
||||
(*it)->m_uiErrorSeverity |= severity;
|
||||
}
|
||||
}
|
||||
|
||||
LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
|
||||
m_StreamArray.push_back( pInfo );
|
||||
@@ -152,6 +181,12 @@ void DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
|
||||
void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
|
||||
{
|
||||
ai_assert ( NULL != pStream );
|
||||
|
||||
// fix (Aramis)
|
||||
if (0 == severity)
|
||||
{
|
||||
severity = Logger::INFO | Logger::ERR | Logger::WARN | Logger::DEBUGGING;
|
||||
}
|
||||
|
||||
for ( StreamIt it = m_StreamArray.begin();
|
||||
it != m_StreamArray.end();
|
||||
@@ -166,6 +201,9 @@ void DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
|
||||
uiSev &= ( ~Logger::WARN );
|
||||
if ( severity & Logger::ERR )
|
||||
uiSev &= ( ~Logger::ERR );
|
||||
// fix (Aramis)
|
||||
if ( severity & Logger::DEBUGGING )
|
||||
uiSev &= ( ~Logger::DEBUGGING );
|
||||
|
||||
(*it)->m_uiErrorSeverity = uiSev;
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if (!defined AI_DEFAULTLOGGER_H_INCLUDED)
|
||||
#define AI_DEFAULTLOGGER_H_INCLUDED
|
||||
|
||||
#include "../include/Logger.h"
|
||||
#include <vector>
|
||||
|
||||
@@ -47,6 +50,39 @@ namespace Assimp
|
||||
class IOStream;
|
||||
struct LogStreamInfo;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @class NullLogger
|
||||
* @brief Empty logging implementation. Does nothing. Used by default
|
||||
* if the application hasn't specified a custom logger (or DefaultLogger)
|
||||
* via DefaultLogger::set() or DefaultLogger::create();
|
||||
*/
|
||||
class NullLogger : public Logger
|
||||
{
|
||||
public:
|
||||
/** @brief Logs a debug message */
|
||||
void debug(const std::string &message) {}
|
||||
|
||||
/** @brief Logs an info message */
|
||||
void info(const std::string &message) {}
|
||||
|
||||
/** @brief Logs a warning message */
|
||||
void warn(const std::string &message) {}
|
||||
|
||||
/** @brief Logs an error message */
|
||||
void error(const std::string &message) {}
|
||||
|
||||
/** @brief Log severity setter */
|
||||
void setLogSeverity(LogSeverity log_severity) {}
|
||||
|
||||
/** @brief Detach a still attached stream from logger */
|
||||
void attachStream(LogStream *pStream, unsigned int severity) {}
|
||||
|
||||
/** @brief Detach a still attached stream from logger */
|
||||
void detatchStream(LogStream *pStream, unsigned int severity) {}
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @class DefaultLogger
|
||||
* @brief Default logging implementation. The logger writes into a file.
|
||||
@@ -57,18 +93,39 @@ class DefaultLogger :
|
||||
public Logger
|
||||
{
|
||||
public:
|
||||
/** @brief Creates the only logging instance
|
||||
/** @brief Creates a custom logging instance (DefaultLogger)
|
||||
* @param name Name for logfile
|
||||
* @param severity Log severity, VERBOSE will activate debug messages
|
||||
*
|
||||
* This replaces the default NullLogger with a DefaultLogger instance.
|
||||
*/
|
||||
static Logger *create(const std::string &name, LogSeverity severity);
|
||||
|
||||
/** @brief Setup a custom implementation of the Logger interface as
|
||||
* default logger.
|
||||
*
|
||||
* Use this if the provided DefaultLogger class doesn't fit into
|
||||
* your needs. If the provided message formatting is OK for you,
|
||||
* it is easier to use create() to create a DefaultLogger and to attach
|
||||
* your own custom output streams to it than using this method.
|
||||
* @param logger Pass NULL to setup a default NullLogger
|
||||
*/
|
||||
static void set (Logger *logger);
|
||||
|
||||
/** @brief Getter for singleton instance
|
||||
* @return Only instance
|
||||
* @return Only instance. This is never null, but it could be a
|
||||
* NullLogger. Use isNullLogger to check this.
|
||||
*/
|
||||
static Logger *get();
|
||||
|
||||
/** @brief Return whether a default NullLogger is currently active
|
||||
* @return true if the current logger id a NullLogger.
|
||||
* Use create() or set() to setup a custom logger.
|
||||
*/
|
||||
static bool isNullLogger();
|
||||
|
||||
/** @brief Will kill the singleton instance */
|
||||
/** @brief Will kill the singleton instance and setup a NullLogger as
|
||||
logger */
|
||||
static void kill();
|
||||
|
||||
/** @brief Logs debug infos, only been written when severity level VERBOSE is set */
|
||||
@@ -112,7 +169,9 @@ private:
|
||||
typedef std::vector<LogStreamInfo*>::const_iterator ConstStreamIt;
|
||||
|
||||
//! only logging instance
|
||||
static DefaultLogger *m_pLogger;
|
||||
static Logger *m_pLogger;
|
||||
static NullLogger s_pNullLogger;
|
||||
|
||||
//! Logger severity
|
||||
LogSeverity m_Severity;
|
||||
//! Attached streams
|
||||
@@ -123,3 +182,5 @@ private:
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // !! AI_DEFAULTLOGGER_H_INCLUDED
|
||||
|
||||
@@ -109,6 +109,9 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
|
||||
aiVector3D pDelta2 = *pV3 - *pV1;
|
||||
aiVector3D vNor = pDelta1 ^ pDelta2;
|
||||
|
||||
if (face.mIndices[1] > face.mIndices[2])
|
||||
vNor *= -1.0f;
|
||||
|
||||
for (unsigned int i = 0;i < face.mNumIndices;++i)
|
||||
{
|
||||
pMesh->mNormals[face.mIndices[i]] = vNor;
|
||||
|
||||
@@ -110,6 +110,9 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh)
|
||||
aiVector3D pDelta2 = *pV3 - *pV1;
|
||||
aiVector3D vNor = pDelta1 ^ pDelta2;
|
||||
|
||||
if (face.mIndices[1] > face.mIndices[2])
|
||||
vNor *= -1.0f;
|
||||
|
||||
for (unsigned int i = 0;i < face.mNumIndices;++i)
|
||||
{
|
||||
pMesh->mNormals[face.mIndices[i]] = vNor;
|
||||
|
||||
@@ -99,10 +99,6 @@ Importer::Importer() :
|
||||
mScene(NULL),
|
||||
mErrorString("")
|
||||
{
|
||||
// construct a new logger
|
||||
/*DefaultLogger::create( "test.log", DefaultLogger::VERBOSE );
|
||||
DefaultLogger::get()->info("Start logging");*/
|
||||
|
||||
// allocate a default IO handler
|
||||
mIOHandler = new DefaultIOSystem;
|
||||
|
||||
|
||||
@@ -244,6 +244,7 @@ void MD2Importer::InternReadFile(
|
||||
unsigned int iCurrent = 0;
|
||||
if (0 != this->m_pcHeader->numTexCoords)
|
||||
{
|
||||
|
||||
for (unsigned int i = 0; i < (unsigned int)this->m_pcHeader->numTriangles;++i)
|
||||
{
|
||||
// allocate the face
|
||||
@@ -253,10 +254,9 @@ void MD2Importer::InternReadFile(
|
||||
// copy texture coordinates
|
||||
// check whether they are different from the previous value at this index.
|
||||
// In this case, create a full separate set of vertices/normals/texcoords
|
||||
unsigned int iTemp = iCurrent;
|
||||
for (unsigned int c = 0; c < 3;++c,++iCurrent)
|
||||
{
|
||||
pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
|
||||
|
||||
// validate vertex indices
|
||||
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
|
||||
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
|
||||
@@ -295,6 +295,9 @@ void MD2Importer::InternReadFile(
|
||||
pcOut->x = u;
|
||||
pcOut->y = v;
|
||||
}
|
||||
pScene->mMeshes[0]->mFaces[i].mIndices[0] = iTemp+2;
|
||||
pScene->mMeshes[0]->mFaces[i].mIndices[1] = iTemp+1;
|
||||
pScene->mMeshes[0]->mFaces[i].mIndices[2] = iTemp+0;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -308,10 +311,9 @@ void MD2Importer::InternReadFile(
|
||||
// copy texture coordinates
|
||||
// check whether they are different from the previous value at this index.
|
||||
// In this case, create a full separate set of vertices/normals/texcoords
|
||||
unsigned int iTemp = iCurrent;
|
||||
for (unsigned int c = 0; c < 3;++c,++iCurrent)
|
||||
{
|
||||
pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
|
||||
|
||||
// validate vertex indices
|
||||
if (pcTriangles[i].vertexIndices[c] >= this->m_pcHeader->numVertices)
|
||||
pcTriangles[i].vertexIndices[c] = this->m_pcHeader->numVertices-1;
|
||||
@@ -343,6 +345,9 @@ void MD2Importer::InternReadFile(
|
||||
pcOut->x = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].s / this->m_pcHeader->skinWidth;
|
||||
pcOut->y = (float)pcTexCoords[pcTriangles[i].textureIndices[c]].t / this->m_pcHeader->skinHeight;
|
||||
}
|
||||
pScene->mMeshes[0]->mFaces[i].mIndices[0] = iTemp+2;
|
||||
pScene->mMeshes[0]->mFaces[i].mIndices[1] = iTemp+1;
|
||||
pScene->mMeshes[0]->mFaces[i].mIndices[2] = iTemp+0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ struct Vertex
|
||||
* \note This has been taken from q3 source (misc_model.c)
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
inline void LatLngNormalToVec3(uint16_t p_iNormal, float* p_afOut)
|
||||
inline void LatLngNormalToVec3(int16_t p_iNormal, float* p_afOut)
|
||||
{
|
||||
float lat = (float)(( p_iNormal >> 8 ) & 0xff);
|
||||
float lng = (float)(( p_iNormal & 0xff ));
|
||||
|
||||
@@ -201,25 +201,28 @@ void MD3Importer::InternReadFile(
|
||||
pcMesh->mFaces[i].mIndices = new unsigned int[3];
|
||||
pcMesh->mFaces[i].mNumIndices = 3;
|
||||
|
||||
unsigned int iTemp = iCurrent;
|
||||
for (unsigned int c = 0; c < 3;++c,++iCurrent)
|
||||
{
|
||||
pcMesh->mFaces[i].mIndices[c] = iCurrent;
|
||||
|
||||
// read vertices
|
||||
pcMesh->mVertices[iCurrent].x = pcVertices[ pcTriangles->INDEXES[c]].X;
|
||||
pcMesh->mVertices[iCurrent].y = pcVertices[ pcTriangles->INDEXES[c]].Y;
|
||||
pcMesh->mVertices[iCurrent].z = pcVertices[ pcTriangles->INDEXES[c]].Z * -1.0f;
|
||||
pcMesh->mVertices[iCurrent].z = pcVertices[ pcTriangles->INDEXES[c]].Z*-1.0f;
|
||||
|
||||
// convert the normal vector to uncompressed float3 format
|
||||
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,
|
||||
(float*)&pcMesh->mNormals[iCurrent]);
|
||||
|
||||
std::swap ( pcMesh->mNormals[iCurrent].y,pcMesh->mNormals[iCurrent].z );
|
||||
//std::swap(pcMesh->mNormals[iCurrent].z,pcMesh->mNormals[iCurrent].y);
|
||||
pcMesh->mNormals[iCurrent].z *= -1.0f;
|
||||
|
||||
// read texture coordinates
|
||||
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
|
||||
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f - pcUVs[ pcTriangles->INDEXES[c]].V;
|
||||
}
|
||||
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
|
||||
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
|
||||
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
|
||||
pcTriangles++;
|
||||
}
|
||||
|
||||
|
||||
@@ -654,6 +654,7 @@ void MDLImporter::InternReadFile_Quake1( )
|
||||
pcMesh->mFaces[i].mIndices = new unsigned int[3];
|
||||
pcMesh->mFaces[i].mNumIndices = 3;
|
||||
|
||||
unsigned int iTemp = iCurrent;
|
||||
for (unsigned int c = 0; c < 3;++c,++iCurrent)
|
||||
{
|
||||
pcMesh->mFaces[i].mIndices[c] = iCurrent;
|
||||
@@ -705,6 +706,9 @@ void MDLImporter::InternReadFile_Quake1( )
|
||||
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-(t + 0.5f) / this->m_pcHeader->skinheight;
|
||||
|
||||
}
|
||||
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
|
||||
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
|
||||
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
|
||||
pcTriangles++;
|
||||
}
|
||||
return;
|
||||
@@ -824,10 +828,9 @@ void MDLImporter::InternReadFile_GameStudio( )
|
||||
pcMesh->mFaces[i].mIndices = new unsigned int[3];
|
||||
pcMesh->mFaces[i].mNumIndices = 3;
|
||||
|
||||
unsigned int iTemp = iCurrent;
|
||||
for (unsigned int c = 0; c < 3;++c,++iCurrent)
|
||||
{
|
||||
pcMesh->mFaces[i].mIndices[c] = iCurrent;
|
||||
|
||||
// read vertices
|
||||
unsigned int iIndex = pcTriangles->index_xyz[c];
|
||||
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
|
||||
@@ -879,6 +882,9 @@ void MDLImporter::InternReadFile_GameStudio( )
|
||||
vTexCoords[iCurrent].x = s;
|
||||
vTexCoords[iCurrent].y = t;
|
||||
}
|
||||
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
|
||||
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
|
||||
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
|
||||
pcTriangles++;
|
||||
}
|
||||
|
||||
@@ -901,10 +907,9 @@ void MDLImporter::InternReadFile_GameStudio( )
|
||||
pcMesh->mFaces[i].mIndices = new unsigned int[3];
|
||||
pcMesh->mFaces[i].mNumIndices = 3;
|
||||
|
||||
unsigned int iTemp = iCurrent;
|
||||
for (unsigned int c = 0; c < 3;++c,++iCurrent)
|
||||
{
|
||||
pcMesh->mFaces[i].mIndices[c] = iCurrent;
|
||||
|
||||
// read vertices
|
||||
unsigned int iIndex = pcTriangles->index_xyz[c];
|
||||
if (iIndex >= (unsigned int)this->m_pcHeader->num_verts)
|
||||
@@ -956,6 +961,9 @@ void MDLImporter::InternReadFile_GameStudio( )
|
||||
vTexCoords[iCurrent].x = s;
|
||||
vTexCoords[iCurrent].y = t;
|
||||
}
|
||||
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
|
||||
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
|
||||
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
|
||||
pcTriangles++;
|
||||
}
|
||||
}
|
||||
@@ -1384,7 +1392,7 @@ void MDLImporter::InternReadFile_GameStudioA7( )
|
||||
unsigned int iOutIndex = iTriangle * 3 + c;
|
||||
|
||||
// write the output face index
|
||||
pcFaces[iTriangle].mIndices[c] = iOutIndex;
|
||||
pcFaces[iTriangle].mIndices[c] = iTriangle * 3 + (2-c);
|
||||
|
||||
// swap z and y axis
|
||||
vPositions[iOutIndex].x = _AI_MDL7_ACCESS_VERT(pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .x;
|
||||
|
||||
221
code/MakeVerboseFormat.cpp
Normal file
221
code/MakeVerboseFormat.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (ASSIMP)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
/** @file Implementation of the post processing step "MakeVerboseFormat"
|
||||
*/
|
||||
#include "MakeVerboseFormat.h"
|
||||
#include "DefaultLogger.h"
|
||||
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiScene.h"
|
||||
#include "../include/aiAssert.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
||||
MakeVerboseFormatProcess::MakeVerboseFormatProcess()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
MakeVerboseFormatProcess::~MakeVerboseFormatProcess()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported data.
|
||||
void MakeVerboseFormatProcess::Execute( aiScene* pScene)
|
||||
{
|
||||
ai_assert(NULL != pScene);
|
||||
DefaultLogger::get()->debug("MakeVerboseFormatProcess begin");
|
||||
|
||||
bool bHas = false;
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
{
|
||||
if( this->MakeVerboseFormat( pScene->mMeshes[a]))
|
||||
bHas = true;
|
||||
}
|
||||
if (bHas)DefaultLogger::get()->info("MakeVerboseFormatProcess finished. There was much work to do ...");
|
||||
else DefaultLogger::get()->debug("MakeVerboseFormatProcess. There was nothing to do.");
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported data.
|
||||
bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
|
||||
{
|
||||
ai_assert(NULL != pcMesh);
|
||||
|
||||
unsigned int iOldNumVertices = pcMesh->mNumVertices;
|
||||
const unsigned int iNumVerts = pcMesh->mNumFaces*3;
|
||||
|
||||
aiVector3D* pvPositions = new aiVector3D[iNumVerts];
|
||||
|
||||
aiVector3D* pvNormals;
|
||||
if (pcMesh->HasNormals())
|
||||
{
|
||||
pvNormals = new aiVector3D[iNumVerts];
|
||||
}
|
||||
aiVector3D* pvTangents, *pvBitangents;
|
||||
if (pcMesh->HasTangentsAndBitangents())
|
||||
{
|
||||
pvTangents = new aiVector3D[iNumVerts];
|
||||
pvBitangents = new aiVector3D[iNumVerts];
|
||||
}
|
||||
|
||||
ai_assert(AI_MAX_NUMBER_OF_TEXTURECOORDS == 4);
|
||||
ai_assert(AI_MAX_NUMBER_OF_COLOR_SETS == 4);
|
||||
|
||||
aiVector3D* apvTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS] = {NULL,NULL,NULL,NULL};
|
||||
aiColor4D* apvColorSets[AI_MAX_NUMBER_OF_COLOR_SETS] = {NULL,NULL,NULL,NULL};
|
||||
|
||||
unsigned int p = 0;
|
||||
while (pcMesh->HasTextureCoords(p))
|
||||
apvTextureCoords[p++] = new aiVector3D[iNumVerts];
|
||||
|
||||
p = 0;
|
||||
while (pcMesh->HasVertexColors(p))
|
||||
apvColorSets[p++] = new aiColor4D[iNumVerts];
|
||||
|
||||
// allocate enough memory to hold output bones and vertex weights ...
|
||||
std::vector<aiVertexWeight>* newWeights = new std::vector<aiVertexWeight>[pcMesh->mNumBones];
|
||||
for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
|
||||
{
|
||||
newWeights[i].reserve(pcMesh->mBones[i]->mNumWeights*3);
|
||||
}
|
||||
|
||||
// iterate through all faces and build a clean list
|
||||
unsigned int iIndex = 0;
|
||||
for (unsigned int a = 0; a< pcMesh->mNumFaces;++a)
|
||||
{
|
||||
aiFace* pcFace = &pcMesh->mFaces[a];
|
||||
for (unsigned int q = 0; q < 3;++q,++iIndex)
|
||||
{
|
||||
// need to build a clean list of bones, too
|
||||
for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
|
||||
{
|
||||
for (unsigned int a = 0; a < pcMesh->mBones[i]->mNumWeights;a++)
|
||||
{
|
||||
const aiVertexWeight& w = pcMesh->mBones[i]->mWeights[a];
|
||||
if(pcFace->mIndices[q] == w.mVertexId)
|
||||
{
|
||||
aiVertexWeight wNew;
|
||||
wNew.mVertexId = iIndex;
|
||||
wNew.mWeight = w.mWeight;
|
||||
newWeights[i].push_back(wNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]];
|
||||
|
||||
if (pcMesh->HasNormals())
|
||||
{
|
||||
pvNormals[iIndex] = pcMesh->mNormals[pcFace->mIndices[q]];
|
||||
}
|
||||
if (pcMesh->HasTangentsAndBitangents())
|
||||
{
|
||||
pvTangents[iIndex] = pcMesh->mTangents[pcFace->mIndices[q]];
|
||||
pvBitangents[iIndex] = pcMesh->mBitangents[pcFace->mIndices[q]];
|
||||
}
|
||||
|
||||
unsigned int p = 0;
|
||||
while (pcMesh->HasTextureCoords(p))
|
||||
{
|
||||
apvTextureCoords[p][iIndex] = pcMesh->mTextureCoords[p][pcFace->mIndices[q]];
|
||||
++p;
|
||||
}
|
||||
p = 0;
|
||||
while (pcMesh->HasVertexColors(p))
|
||||
{
|
||||
apvColorSets[p][iIndex] = pcMesh->mColors[p][pcFace->mIndices[q]];
|
||||
++p;
|
||||
}
|
||||
pcFace->mIndices[q] = iIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// build output vertex weights
|
||||
for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
|
||||
{
|
||||
delete pcMesh->mBones[i]->mWeights;
|
||||
if (!newWeights[i].empty())
|
||||
{
|
||||
pcMesh->mBones[i]->mWeights = new aiVertexWeight[newWeights[i].size()];
|
||||
memcpy(pcMesh->mBones[i]->mWeights,&newWeights[i][0],
|
||||
sizeof(aiVertexWeight) * newWeights[i].size());
|
||||
}
|
||||
else pcMesh->mBones[i]->mWeights = NULL;
|
||||
}
|
||||
|
||||
// delete the old members
|
||||
delete[] pcMesh->mVertices;
|
||||
pcMesh->mVertices = pvPositions;
|
||||
|
||||
p = 0;
|
||||
while (pcMesh->HasTextureCoords(p))
|
||||
{
|
||||
delete pcMesh->mTextureCoords[p];
|
||||
pcMesh->mTextureCoords[p] = apvTextureCoords[p];
|
||||
++p;
|
||||
}
|
||||
p = 0;
|
||||
while (pcMesh->HasVertexColors(p))
|
||||
{
|
||||
delete pcMesh->mColors[p];
|
||||
pcMesh->mColors[p] = apvColorSets[p];
|
||||
++p;
|
||||
}
|
||||
pcMesh->mNumVertices = iNumVerts;
|
||||
|
||||
if (pcMesh->HasNormals())
|
||||
{
|
||||
delete[] pcMesh->mNormals;
|
||||
pcMesh->mNormals = pvNormals;
|
||||
}
|
||||
if (pcMesh->HasTangentsAndBitangents())
|
||||
{
|
||||
delete[] pcMesh->mTangents;
|
||||
pcMesh->mTangents = pvTangents;
|
||||
delete[] pcMesh->mBitangents;
|
||||
pcMesh->mBitangents = pvBitangents;
|
||||
}
|
||||
return (pcMesh->mNumVertices != iOldNumVertices);
|
||||
}
|
||||
106
code/MakeVerboseFormat.h
Normal file
106
code/MakeVerboseFormat.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Defines a post processing step to bring a given scene
|
||||
into the verbose format that is expected by most postprocess steps.
|
||||
This is the inverse of the "JoinIdenticalVertices" steps */
|
||||
#ifndef AI_MAKEVERBOSEFORMAT_H_INC
|
||||
#define AI_MAKEVERBOSEFORMAT_H_INC
|
||||
|
||||
#include "BaseProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** MakeVerboseFormatProcess: Class to convert an asset to the verbose
|
||||
* format which is expected by most postprocess steps.
|
||||
*
|
||||
* This is the inverse of what the "JoinIdenticalVertices" step is doing.
|
||||
* This step has no official flag (since it wouldn't make sense to run it
|
||||
* during import). It is intended for applications intending to modify the
|
||||
* returned aiScene. After this step has been executed, they can execute
|
||||
* other postprocess steps on the data.
|
||||
* The step has been added because it was required by the viewer, however
|
||||
* it has been moved to the main library since others might find it
|
||||
* useful, too.
|
||||
*/
|
||||
class MakeVerboseFormatProcess : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
public:
|
||||
/** Constructor to be privately used by Importer, or by applications
|
||||
which know what they are doing if they modify the aiScene object */
|
||||
MakeVerboseFormatProcess();
|
||||
|
||||
/** Destructor, private as well */
|
||||
~MakeVerboseFormatProcess();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag field.
|
||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||
* combination of #aiPostProcessSteps.
|
||||
* @return true if the process is present in this flag fields, false if not.
|
||||
*/
|
||||
bool IsActive( unsigned int pFlags) const
|
||||
{
|
||||
// NOTE: There is no direct flag that corresponds to
|
||||
// this postprocess step.
|
||||
return false;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
* At the moment a process is not supposed to fail.
|
||||
* @param pScene The imported data to work at.
|
||||
*/
|
||||
void Execute( aiScene* pScene);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//! Apply the postprocess step to a given submesh
|
||||
bool MakeVerboseFormat (aiMesh* pcMesh);
|
||||
};
|
||||
}; // end of namespace Assimp
|
||||
|
||||
#endif // !!AI_KILLNORMALPROCESS_H_INC
|
||||
@@ -64,7 +64,7 @@ aiReturn aiSetVertexSplitLimit(unsigned int pLimit)
|
||||
}
|
||||
|
||||
SplitLargeMeshesProcess_Vertex::LIMIT = pLimit;
|
||||
//DefaultLogger::get()->debug("aiSetVertexSplitLimit() - vertex split limit was changed");
|
||||
DefaultLogger::get()->debug("aiSetVertexSplitLimit() - vertex split limit was changed");
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -77,7 +77,7 @@ aiReturn aiSetTriangleSplitLimit(unsigned int pLimit)
|
||||
}
|
||||
|
||||
SplitLargeMeshesProcess_Triangle::LIMIT = pLimit;
|
||||
//DefaultLogger::get()->debug("aiSetTriangleSplitLimit() - triangle split limit was changed");
|
||||
DefaultLogger::get()->debug("aiSetTriangleSplitLimit() - triangle split limit was changed");
|
||||
return AI_SUCCESS;
|
||||
}
|
||||
}; //! extern "C"
|
||||
|
||||
@@ -570,7 +570,8 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
|
||||
|
||||
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||
// material colours
|
||||
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
|
||||
// FIX: Setup this as ambient not as emissive color
|
||||
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||
mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
|
||||
mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
|
||||
|
||||
134
code/jAssimp/JNILogger.cpp
Normal file
134
code/jAssimp/JNILogger.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (ASSIMP)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Implementation of the JNI API for jAssimp */
|
||||
|
||||
#if (defined ASSIMP_JNI_EXPORT)
|
||||
|
||||
|
||||
// include assimp
|
||||
#include "../../include/aiTypes.h"
|
||||
#include "../../include/aiMesh.h"
|
||||
#include "../../include/aiAnim.h"
|
||||
#include "../../include/aiScene.h"
|
||||
#include "../../include/aiAssert.h"
|
||||
#include "../../include/aiPostProcess.h"
|
||||
#include "../../include/assimp.hpp"
|
||||
|
||||
#include "../DefaultLogger.h"
|
||||
|
||||
#include "JNILogger.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
||||
namespace Assimp {
|
||||
namespace JNIBridge {
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void JNILogDispatcher::SetJNIEnvironment(JNIEnv* ptr)
|
||||
{
|
||||
// there is much error handling code in this function.
|
||||
// However, it is not impossible that the jAssimp package
|
||||
// loaded by the JVM is incomplete ...
|
||||
|
||||
jclass java_lang_Exception = this->GetJNIEnv()->FindClass("java.lang.Exception");
|
||||
|
||||
// get a handle to the assimp.DefaultLogger class
|
||||
this->m_pcJNIEnv = ptr;
|
||||
if( NULL == (this->m_pcClass = this->GetJNIEnv()->FindClass("assimp.DefaultLogger")))
|
||||
{
|
||||
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
|
||||
"Unable to get class handle to assimp.DefaultLogger");
|
||||
return;
|
||||
}
|
||||
// get handles to the logging functions
|
||||
if( NULL == (this->m_pcMethodError = this->GetJNIEnv()->GetStaticMethodID(
|
||||
this->m_pcClass,"_NativeCallWriteError","(Ljava/lang/String;)V")))
|
||||
{
|
||||
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
|
||||
"Unable to get class handle to assimp.DefaultLogger._NativeCallWriteError()");
|
||||
return;
|
||||
}
|
||||
if( NULL == (this->m_pcMethodWarn = this->GetJNIEnv()->GetStaticMethodID(
|
||||
this->m_pcClass,"_NativeCallWriteWarn","(Ljava/lang/String;)V")))
|
||||
{
|
||||
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
|
||||
"Unable to get class handle to assimp.DefaultLogger._NativeCallWriteWarn()");
|
||||
return;
|
||||
}
|
||||
if( NULL == (this->m_pcMethodInfo = this->GetJNIEnv()->GetStaticMethodID(
|
||||
this->m_pcClass,"_NativeCallWriteInfo","(Ljava/lang/String;)V")))
|
||||
{
|
||||
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
|
||||
"Unable to get class handle to assimp.DefaultLogger._NativeCallWriteInfo()");
|
||||
return;
|
||||
}
|
||||
if( NULL == (this->m_pcMethodDebug = this->GetJNIEnv()->GetStaticMethodID(
|
||||
this->m_pcClass,"_NativeCallWriteDebug","(Ljava/lang/String;)V")))
|
||||
{
|
||||
this->GetJNIEnv()->ThrowNew(java_lang_Exception,
|
||||
"Unable to get class handle to assimp.DefaultLogger._NativeCallWriteDebug()");
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void JNILogDispatcher::debug(const std::string &message)
|
||||
{
|
||||
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void JNILogDispatcher::info(const std::string &message)
|
||||
{
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void JNILogDispatcher::warn(const std::string &message)
|
||||
{
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void JNILogDispatcher::error(const std::string &message)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
};};
|
||||
|
||||
#endif // jni
|
||||
122
code/jAssimp/JNILogger.h
Normal file
122
code/jAssimp/JNILogger.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
Open Asset Import Library (ASSIMP)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if (!defined AI_JNILOGGER_H_INCLUDED)
|
||||
#define AI_JNILOGGER_H_INCLUDED
|
||||
|
||||
|
||||
#include "../../include/Logger.h"
|
||||
#include <vector>
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
namespace Assimp {
|
||||
namespace JNIBridge {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
class IOStream;
|
||||
struct LogStreamInfo;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @class JNILogDispatcher
|
||||
* @brief Logging system implementation that is used to send all
|
||||
* log messages generated by native code to the Java logging system.
|
||||
*/
|
||||
class JNILogDispatcher : public Logger
|
||||
{
|
||||
public:
|
||||
/** @brief Logs a debug message */
|
||||
void debug(const std::string &message);
|
||||
|
||||
/** @brief Logs an info message */
|
||||
void info(const std::string &message);
|
||||
|
||||
/** @brief Logs a warning message */
|
||||
void warn(const std::string &message);
|
||||
|
||||
/** @brief Logs an error message */
|
||||
void error(const std::string &message);
|
||||
|
||||
/** @brief Log severity setter */
|
||||
void setLogSeverity(LogSeverity log_severity) {}
|
||||
|
||||
/** @brief Detach a still attached stream from logger */
|
||||
void attachStream(LogStream *pStream, unsigned int severity) {}
|
||||
|
||||
/** @brief Detach a still attached stream from logger */
|
||||
void detatchStream(LogStream *pStream, unsigned int severity) {}
|
||||
|
||||
//! Setup the JNI environment to use
|
||||
//! (must be attached to the thread)
|
||||
//! \param ptr Java environment to be used. != 0
|
||||
void SetJNIEnvironment(JNIEnv* ptr);
|
||||
|
||||
//! Get the current JNI environment
|
||||
inline JNIEnv* GetJNIEnv()
|
||||
{
|
||||
ai_assert(NULL != m_pcJNIEnv);
|
||||
return m_pcJNIEnv;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//! JNI environment pointer
|
||||
JNIEnv* m_pcJNIEnv;
|
||||
|
||||
//! Handle to assimp.DefaultLogger class
|
||||
jclass m_pcClass;
|
||||
|
||||
//! Handle to the static assimp.DefaultLogger._NativeCallWriteError() method
|
||||
jmethodID m_pcMethodError;
|
||||
|
||||
//! Handle to the static assimp.DefaultLogger._NativeCallWriteInfo() method
|
||||
jmethodID m_pcMethodInfo;
|
||||
|
||||
//! Handle to the static assimp.DefaultLogger._NativeCallWriteDebug() method
|
||||
jmethodID m_pcMethodDebug;
|
||||
|
||||
//! Handle to the static assimp.DefaultLogger._NativeCallWriteWarn() method
|
||||
jmethodID m_pcMethodWarn;
|
||||
};
|
||||
|
||||
};};
|
||||
|
||||
#endif // AI_JNILOGGER_H_INCLUDED
|
||||
Reference in New Issue
Block a user