Optimized GenVertexNormal-Step.

Added SharedPostProcessInfo-class to allow pp-steps to interact with each other.
Used this new feature for some cross-optimization between the steps: SpatialSort is now solely computed once, not up to three times.
3DS bugfix - orientation was wrong.
ASE normal vectors - although they are normally wrong and not orthonormal they are working now.
Fix in fast_atof.h - 1.45E45 (major 'E') is handlded correctly now.
Improvements on jAssimp, still WIP and not working.
Some LightWave bugfixes, still WIP.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@164 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-09-27 16:46:05 +00:00
parent a4f2aab6c3
commit 9279513700
41 changed files with 2128 additions and 1128 deletions

View File

@ -490,7 +490,9 @@ void Dot3DSImporter::ParseHierarchyChunk(int& piRemaining)
// pivot = origin of rotation and scaling // pivot = origin of rotation and scaling
this->mCurrentNode->vPivot = *((const aiVector3D*)this->mCurrent); this->mCurrentNode->vPivot = *((const aiVector3D*)this->mCurrent);
std::swap((float&)mCurrentNode->vPivot.y,(float&)mCurrentNode->vPivot.z); //std::swap((float&)mCurrentNode->vPivot.y,(float&)mCurrentNode->vPivot.z);
mCurrentNode->vPivot.y *= -1.f;
this->mCurrent += sizeof(aiVector3D); this->mCurrent += sizeof(aiVector3D);
break; break;
@ -747,8 +749,8 @@ void Dot3DSImporter::ParseMeshChunk(int& piRemaining)
{ {
mMesh.mPositions.push_back(*((aiVector3D*)this->mCurrent)); mMesh.mPositions.push_back(*((aiVector3D*)this->mCurrent));
aiVector3D& v = mMesh.mPositions.back(); aiVector3D& v = mMesh.mPositions.back();
std::swap( (float&)v.y, (float&)v.z); //std::swap( (float&)v.y, (float&)v.z);
//v.y *= -1.0f; v.y *= -1.0f;
this->mCurrent += sizeof(aiVector3D); this->mCurrent += sizeof(aiVector3D);
} }
break; break;
@ -1019,8 +1021,6 @@ void Dot3DSImporter::ParseTextureChunk(int& piRemaining,Dot3DS::Texture* pcOut)
"x direction is zero. Assuming this should be 1.0 ... "); "x direction is zero. Assuming this should be 1.0 ... ");
pcOut->mScaleU = 1.0f; pcOut->mScaleU = 1.0f;
} }
// NOTE: some docs state it is 1/u, others say it is u ... ARGHH!
//pcOut->mScaleU = 1.0f / pcOut->mScaleU;
break; break;
case Dot3DSFile::CHUNK_MAT_MAP_VSCALE: case Dot3DSFile::CHUNK_MAT_MAP_VSCALE:
pcOut->mScaleV = *((float*)this->mCurrent); pcOut->mScaleV = *((float*)this->mCurrent);
@ -1030,8 +1030,6 @@ void Dot3DSImporter::ParseTextureChunk(int& piRemaining,Dot3DS::Texture* pcOut)
"y direction is zero. Assuming this should be 1.0 ... "); "y direction is zero. Assuming this should be 1.0 ... ");
pcOut->mScaleV = 1.0f; pcOut->mScaleV = 1.0f;
} }
// NOTE: some docs state it is 1/v, others say it is v ... ARGHH!
//pcOut->mScaleV = 1.0f / pcOut->mScaleV;
break; break;
case Dot3DSFile::CHUNK_MAT_MAP_UOFFSET: case Dot3DSFile::CHUNK_MAT_MAP_UOFFSET:
pcOut->mOffsetU = *((float*)this->mCurrent); pcOut->mOffsetU = *((float*)this->mCurrent);
@ -1103,14 +1101,15 @@ void Dot3DSImporter::ParseColorChunk(aiColor3D* p_pcOut,
return; return;
} }
const unsigned int diff = psChunk->Size - sizeof(Dot3DSFile::Chunk); const unsigned int diff = psChunk->Size - sizeof(Dot3DSFile::Chunk);
const unsigned char* pcCur = this->mCurrent; const unsigned char* pcCur = this->mCurrent;
this->mCurrent += diff; this->mCurrent += diff;
bool bGamma = false; bool bGamma = false;
switch(psChunk->Flag) switch(psChunk->Flag)
{ {
case Dot3DSFile::CHUNK_LINRGBF: case Dot3DSFile::CHUNK_LINRGBF:
bGamma = true; bGamma = true;
case Dot3DSFile::CHUNK_RGBF: case Dot3DSFile::CHUNK_RGBF:
if (sizeof(float) * 3 > diff) if (sizeof(float) * 3 > diff)
{ {

View File

@ -471,7 +471,7 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
// allocate output storage // allocate output storage
std::vector<aiVector3D> mPositions; std::vector<aiVector3D> mPositions;
std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
std::vector<aiColor4D> mVertexColors; std::vector<aiColor4D> mVertexColors;
std::vector<aiVector3D> mNormals; std::vector<aiVector3D> mNormals;
std::vector<BoneVertex> mBoneVertices; std::vector<BoneVertex> mBoneVertices;
@ -512,7 +512,8 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
for (unsigned int n = 0; n < 3;++n,++iCurrent) for (unsigned int n = 0; n < 3;++n,++iCurrent)
{ {
mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]]; mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]];
std::swap((float&)mPositions[iCurrent].z,(float&)mPositions[iCurrent].y); // DX-to-OGL //std::swap((float&)mPositions[iCurrent].z,(float&)mPositions[iCurrent].y); // DX-to-OGL
mPositions[iCurrent].y *= -1.f;
// add texture coordinates // add texture coordinates
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
@ -532,7 +533,10 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
if (!mesh.mNormals.empty()) if (!mesh.mNormals.empty())
{ {
mNormals[iCurrent] = mesh.mNormals[(*i).mIndices[n]]; mNormals[iCurrent] = mesh.mNormals[(*i).mIndices[n]];
std::swap((float&)mNormals[iCurrent].z,(float&)mNormals[iCurrent].y); // DX-to-OGL mNormals[iCurrent].Normalize();
//std::swap((float&)mNormals[iCurrent].z,(float&)mNormals[iCurrent].y); // DX-to-OGL
mNormals[iCurrent].y *= -1.0f;
} }
// handle bone vertices // handle bone vertices
@ -1014,27 +1018,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
} }
return; return;
} }
// ------------------------------------------------------------------------------------------------
void ComputeBounds(ASE::Mesh& mesh,aiVector3D& minVec, aiVector3D& maxVec,
aiMatrix4x4& matrix)
{
minVec = aiVector3D( 1e10f, 1e10f, 1e10f);
maxVec = aiVector3D( -1e10f, -1e10f, -1e10f);
for( std::vector<aiVector3D>::const_iterator
i = mesh.mPositions.begin();
i != mesh.mPositions.end();++i)
{
aiVector3D v = matrix*(*i);
minVec.x = std::min( minVec.x, v.x);
minVec.y = std::min( minVec.y, v.y);
minVec.z = std::min( minVec.z, v.z);
maxVec.x = std::max( maxVec.x, v.x);
maxVec.y = std::max( maxVec.y, v.y);
maxVec.z = std::max( maxVec.z, v.z);
}
return;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ASEImporter::BuildMaterialIndices() void ASEImporter::BuildMaterialIndices()
{ {
@ -1149,23 +1133,21 @@ void ASEImporter::GenerateNormals(ASE::Mesh& mesh)
{ {
if (!mesh.mNormals.empty()) if (!mesh.mNormals.empty())
{ {
// check whether there are uninitialized normals. If there are // check whether there are only uninitialized normals. If there are
// some, skip all normals from the file and compute them on our own // some, skip all normals from the file and compute them on our own
for (std::vector<aiVector3D>::const_iterator for (std::vector<aiVector3D>::const_iterator
qq = mesh.mNormals.begin(); qq = mesh.mNormals.begin();
qq != mesh.mNormals.end();++qq) qq != mesh.mNormals.end();++qq)
{ {
if (is_qnan((*qq).x)) if (!(*qq).x || !(*qq).y || !(*qq).z)
{ {
DefaultLogger::get()->warn("Normals were specified in the file, " return;
"but not all vertices seem to have normals assigned. The "
"whole normal set will be recomputed.");
mesh.mNormals.clear();
break;
} }
} }
mesh.mNormals.clear();
} }
if (mesh.mNormals.empty()) if (mesh.mNormals.empty())
{
ComputeNormalsWithSmoothingsGroups<ASE::Face>(mesh); ComputeNormalsWithSmoothingsGroups<ASE::Face>(mesh);
return; }
} }

File diff suppressed because it is too large Load Diff

View File

@ -53,7 +53,7 @@ using namespace Assimp;
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
BaseProcess::BaseProcess() BaseProcess::BaseProcess()
{ {
// nothing to do here shared = NULL;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -44,14 +44,140 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/aiTypes.h" #include "../include/aiTypes.h"
#include "GenericProperty.h"
#include <map>
struct aiScene; struct aiScene;
namespace Assimp namespace Assimp {
{
class Importer; class Importer;
// ---------------------------------------------------------------------------
/** Helper class to allow post-processing steps to interact with each other.
*
* The class maintains a simple property list that can be used by pp-steps
* to provide additional information to other steps. This is primarily
* intended for cross-step optimizations.
*/
class ASSIMP_API SharedPostProcessInfo
{
public:
struct Base
{
virtual ~Base()
{}
};
template <typename T>
struct THeapData : public Base
{
THeapData(T* in)
: data (in)
{}
~THeapData()
{
delete data;
}
T* data;
};
template <typename T>
struct TStaticData : public Base
{
TStaticData(T in)
: data (in)
{}
~TStaticData()
{}
T data;
};
typedef uint32_t KeyType;
typedef std::map<KeyType, Base*> PropertyMap;
public:
~SharedPostProcessInfo()
{
Clean();
}
void Clean()
{
// invoke the virtual destructor for all stored properties
for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
it != end; ++it)
{
delete (*it).second;
}
pmap.clear();
}
template <typename T>
inline void AddProperty( const char* name, T* in )
{
AddProperty(name,(Base*)new THeapData<T>(in));
}
template <typename T>
inline void AddProperty( const char* name, T in )
{
AddProperty(name,(Base*)new TStaticData<T>(in));
}
template <typename T>
inline bool GetProperty( const char* name, T*& out ) const
{
THeapData<T>* t;
GetProperty(name,(Base*&)t);
if(!t)
{
out = NULL;
return false;
}
out = t->data;
return true;
}
template <typename T>
inline bool GetProperty( const char* name, T& out ) const
{
TStaticData<T>* t;
GetProperty(name,(Base*&)t);
if(!t)return false;
out = t->data;
return true;
}
inline void RemoveProperty( const char* name)
{
AddProperty<int*>(name, NULL);
}
private:
inline void AddProperty( const char* name, Base* data)
{
SetGenericPropertyPtr<Base>(pmap,name,data);
}
inline void GetProperty( const char* name, Base*& data) const
{
data = GetGenericProperty<Base*>(pmap,name,NULL);
}
PropertyMap pmap;
};
#define AI_SPP_SPATIAL_SORT "$Spat"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The BaseProcess defines a common interface for all post processing steps. /** The BaseProcess defines a common interface for all post processing steps.
* A post processing step is run after a successful import if the caller * A post processing step is run after a successful import if the caller
@ -107,6 +233,31 @@ public:
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
virtual void Execute( aiScene* pScene) = 0; virtual void Execute( aiScene* pScene) = 0;
// -------------------------------------------------------------------
/** Assign a new SharedPostProcessInfo to the step. This object
* allows multiple postprocess steps to share data.
* @param sh May be NULL
*/
inline void SetSharedData(SharedPostProcessInfo* sh)
{
shared = sh;
}
// -------------------------------------------------------------------
/** Get the shared data that is assigned to the step.
*/
inline SharedPostProcessInfo* GetSharedData()
{
return shared;
}
protected:
/** See the doc of #SharedPostProcessInfo for more details
*/
SharedPostProcessInfo* shared;
}; };

View File

@ -47,10 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector> #include <vector>
#include <assert.h> #include <assert.h>
// internal headers
#include "CalcTangentsProcess.h"
#include "SpatialSort.h"
// public ASSIMP headers // public ASSIMP headers
#include "../include/DefaultLogger.h" #include "../include/DefaultLogger.h"
#include "../include/aiPostProcess.h" #include "../include/aiPostProcess.h"
@ -58,6 +54,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/aiScene.h" #include "../include/aiScene.h"
#include "../include/assimp.hpp" #include "../include/assimp.hpp"
// internal headers
#include "CalcTangentsProcess.h"
#include "ProcessHelper.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -99,7 +99,7 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
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]))bHas = true; if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
if (bHas)DefaultLogger::get()->debug("CalcTangentsProcess finished. Tangents have been calculated"); if (bHas)DefaultLogger::get()->debug("CalcTangentsProcess finished. Tangents have been calculated");
else DefaultLogger::get()->debug("CalcTangentsProcess finished"); else DefaultLogger::get()->debug("CalcTangentsProcess finished");
@ -107,7 +107,7 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Calculates tangents and bitangents for the given mesh // Calculates tangents and bitangents for the given mesh
bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh) bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
{ {
// we assume that the mesh is still in the verbose vertex format where each face has its own set // 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 // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
@ -129,22 +129,6 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
DefaultLogger::get()->error("Unable to compute tangents: UV0 and normals must be there "); DefaultLogger::get()->error("Unable to compute tangents: UV0 and normals must be there ");
return false; 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);
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
{
minVec.x = std::min( minVec.x, pMesh->mVertices[a].x);
minVec.y = std::min( minVec.y, pMesh->mVertices[a].y);
minVec.z = std::min( minVec.z, pMesh->mVertices[a].z);
maxVec.x = std::max( maxVec.x, pMesh->mVertices[a].x);
maxVec.y = std::max( maxVec.y, pMesh->mVertices[a].y);
maxVec.z = std::max( maxVec.z, pMesh->mVertices[a].z);
}
// calculate epsilons border
const float epsilon = 1e-5f;
const float posEpsilon = (maxVec - minVec).Length() * epsilon;
const float angleEpsilon = 0.9999f; const float angleEpsilon = 0.9999f;
// create space for the tangents and bitangents // create space for the tangents and bitangents
@ -201,8 +185,30 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
} }
} }
// create a helper to quickly find locally close vertices among the vertex array // create a helper to quickly find locally close vertices among the vertex array
SpatialSort vertexFinder( meshPos, pMesh->mNumVertices, sizeof( aiVector3D)); // FIX: check whether we can reuse the SpatialSort of a previous step
SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder;
float posEpsilon;
if (shared)
{
std::vector<std::pair<SpatialSort,float> >* avf;
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
if (avf)
{
std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
vertexFinder = &blubb.first;
posEpsilon = blubb.second;;
}
}
if (!vertexFinder)
{
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
vertexFinder = &_vertexFinder;
posEpsilon = ComputePositionEpsilon(pMesh);
}
std::vector<unsigned int> verticesFound; std::vector<unsigned int> verticesFound;
const float fLimit = cosf(this->configMaxAngle); const float fLimit = cosf(this->configMaxAngle);
@ -223,7 +229,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
closeVertices.push_back( a); closeVertices.push_back( a);
// find all vertices close to that position // find all vertices close to that position
vertexFinder.FindPositions( origPos, posEpsilon, verticesFound); vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);
// look among them for other vertices sharing the same normal and a close-enough tangent/bitangent // look among them for other vertices sharing the same normal and a close-enough tangent/bitangent
for( unsigned int b = 0; b < verticesFound.size(); b++) for( unsigned int b = 0; b < verticesFound.size(); b++)
@ -245,7 +251,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
// smooth the tangents and bitangents of all vertices that were found to be close enough // smooth the tangents and bitangents of all vertices that were found to be close enough
aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0); aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0);
for( unsigned int b = 0; b < closeVertices.size(); b++) for( unsigned int b = 0; b < closeVertices.size(); ++b)
{ {
smoothTangent += meshTang[ closeVertices[b] ]; smoothTangent += meshTang[ closeVertices[b] ];
smoothBitangent += meshBitang[ closeVertices[b] ]; smoothBitangent += meshBitang[ closeVertices[b] ];
@ -254,7 +260,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
smoothBitangent.Normalize(); smoothBitangent.Normalize();
// and write it back into all affected tangents // and write it back into all affected tangents
for( unsigned int b = 0; b < closeVertices.size(); b++) for( unsigned int b = 0; b < closeVertices.size(); ++b)
{ {
meshTang[ closeVertices[b] ] = smoothTangent; meshTang[ closeVertices[b] ] = smoothTangent;
meshBitang[ closeVertices[b] ] = smoothBitangent; meshBitang[ closeVertices[b] ] = smoothBitangent;

View File

@ -97,8 +97,9 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Calculates tangents and bitangents for a specific mesh. /** Calculates tangents and bitangents for a specific mesh.
* @param pMesh The mesh to process. * @param pMesh The mesh to process.
* @param meshIndex Index of the mesh
*/ */
bool ProcessMesh( aiMesh* pMesh); bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.

View File

@ -122,7 +122,8 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool DXFImporter::GetNextLine() bool DXFImporter::GetNextLine()
{ {
if(!SkipLine(&buffer))return false; if(!SkipLine(&buffer))
return false;
if(!SkipSpaces(&buffer))return GetNextLine(); if(!SkipSpaces(&buffer))return GetNextLine();
return true; return true;
} }
@ -187,13 +188,10 @@ void DXFImporter::InternReadFile( const std::string& pFile,
// other sections - skip them to make sure there will be no name conflicts // other sections - skip them to make sure there will be no name conflicts
else else
{ {
bool b = false;
while (GetNextToken()) while (GetNextToken())
{ {
if (!groupCode && !::strcmp(cursor,"ENDSEC")) if (!groupCode && !::strcmp(cursor,"ENDSEC"))break;
{b = true;break;}
} }
if (!b)break;
} }
} }
// print comment strings // print comment strings
@ -233,9 +231,12 @@ void DXFImporter::InternReadFile( const std::string& pFile,
for (std::vector<aiColor4D>::const_iterator it2 = (*it).vColors.begin(), end2 = (*it).vColors.end(); for (std::vector<aiColor4D>::const_iterator it2 = (*it).vColors.begin(), end2 = (*it).vColors.end();
it2 != end2; ++it2) it2 != end2; ++it2)
{ {
if (std::numeric_limits<float>::quiet_NaN() != (*it2).r) if ((*it2).r == (*it2).r) // check against qnan
{ {
clrOut = pMesh->mColors[0] = new aiColor4D[vPositions.size()]; clrOut = pMesh->mColors[0] = new aiColor4D[vPositions.size()];
for (unsigned int i = 0; i < vPositions.size();++i)
clrOut[i] = aiColor4D(0.6f,0.6f,0.6f,1.0f);
clr = &vColors[0]; clr = &vColors[0];
break; break;
} }
@ -262,7 +263,13 @@ void DXFImporter::InternReadFile( const std::string& pFile,
for (unsigned int a = 0; a < face.mNumIndices;++a) for (unsigned int a = 0; a < face.mNumIndices;++a)
{ {
*vpOut++ = vp[a]; *vpOut++ = vp[a];
if (clr)*clrOut++ = clr[a]; if (clr)
{
if (std::numeric_limits<float>::quiet_NaN() != clr[a].r)
*clrOut = clr[a];
++clrOut;
}
face.mIndices[a] = pMesh->mNumVertices++; face.mIndices[a] = pMesh->mNumVertices++;
} }
vp += 4; vp += 4;
@ -325,7 +332,7 @@ bool DXFImporter::ParseEntities()
if (!::strcmp(cursor,"3DFACE")) if (!::strcmp(cursor,"3DFACE"))
if (!Parse3DFace()) return false; else bRepeat = true; if (!Parse3DFace()) return false; else bRepeat = true;
if (!::strcmp(cursor,"POLYLINE")) if (!::strcmp(cursor,"POLYLINE") || !::strcmp(cursor,"LWPOLYLINE"))
if (!ParsePolyLine()) return false; else bRepeat = true; if (!ParsePolyLine()) return false; else bRepeat = true;
if (!::strcmp(cursor,"ENDSEC")) if (!::strcmp(cursor,"ENDSEC"))

View File

@ -42,14 +42,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the post processing step to generate face /** @file Implementation of the post processing step to generate face
* normals for all imported faces. * normals for all imported faces.
*/ */
#include "GenVertexNormalsProcess.h"
#include "SpatialSort.h" // public ASSIMP headers
#include "../include/DefaultLogger.h" #include "../include/DefaultLogger.h"
#include "../include/aiPostProcess.h" #include "../include/aiPostProcess.h"
#include "../include/aiMesh.h"
#include "../include/aiScene.h" #include "../include/aiScene.h"
#include "../include/assimp.hpp" #include "../include/assimp.hpp"
// internal headers
#include "GenVertexNormalsProcess.h"
#include "ProcessHelper.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -90,7 +93,7 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene)
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(this->GenMeshVertexNormals( pScene->mMeshes[a])) if(this->GenMeshVertexNormals( pScene->mMeshes[a],a))
bHas = true; bHas = true;
} }
@ -105,7 +108,7 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh) bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex)
{ {
if (NULL != pMesh->mNormals)return false; if (NULL != pMesh->mNormals)return false;
@ -123,49 +126,87 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh)
pMesh->mNormals[face.mIndices[i]] = vNor; pMesh->mNormals[face.mIndices[i]] = vNor;
} }
// calculate the position bounds so we have a reliable epsilon to
// check position differences against
aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
{
minVec.x = std::min( minVec.x, pMesh->mVertices[a].x);
minVec.y = std::min( minVec.y, pMesh->mVertices[a].y);
minVec.z = std::min( minVec.z, pMesh->mVertices[a].z);
maxVec.x = std::max( maxVec.x, pMesh->mVertices[a].x);
maxVec.y = std::max( maxVec.y, pMesh->mVertices[a].y);
maxVec.z = std::max( maxVec.z, pMesh->mVertices[a].z);
}
const float posEpsilon = (maxVec - minVec).Length() * 1e-5f;
// set up a SpatialSort to quickly find all vertices close to a given position // set up a SpatialSort to quickly find all vertices close to a given position
SpatialSort vertexFinder( pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D)); // check whether we can reuse the SpatialSort of a previous step.
std::vector<unsigned int> verticesFound; SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder;
const float fLimit = cos(this->configMaxAngle); float posEpsilon;
const float epsilon = 1e-5f;
aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices]; if (shared)
for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
{ {
const aiVector3D& posThis = pMesh->mVertices[i]; std::vector<std::pair<SpatialSort,float> >* avf;
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
// get all vertices that share this one ... if (avf)
vertexFinder.FindPositions( posThis, posEpsilon, verticesFound);
aiVector3D pcNor;
for (unsigned int a = 0; a < verticesFound.size(); ++a)
{ {
unsigned int vidx = verticesFound[a]; std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
vertexFinder = &blubb.first;
// check whether the angle between the two normals is not too large posEpsilon = blubb.second;
if (pMesh->mNormals[vidx] * pMesh->mNormals[i] < fLimit)
continue;
pcNor += pMesh->mNormals[vidx];
} }
pcNor.Normalize();
pcNew[i] = pcNor;
} }
if (!vertexFinder)
{
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
vertexFinder = &_vertexFinder;
posEpsilon = ComputePositionEpsilon(pMesh);
}
std::vector<unsigned int> verticesFound;
aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices];
if (configMaxAngle >= AI_DEG_TO_RAD( 175.f ))
{
// there is no angle limit. Thus all vertices with positions close
// to each other will receive the same vertex normal. This allows us
// to optimize the whole algorithm a little bit ...
std::vector<bool> abHad(pMesh->mNumVertices,false);
for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
{
if (abHad[i])continue;
// get all vertices that share this one ...
vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound);
aiVector3D pcNor;
for (unsigned int a = 0; a < verticesFound.size(); ++a)
{
register unsigned int vidx = verticesFound[a];
pcNor += pMesh->mNormals[vidx];
}
pcNor.Normalize();
// write the smoothed normal back to all affected normals
for (unsigned int a = 0; a < verticesFound.size(); ++a)
{
register unsigned int vidx = verticesFound[a];
pcNew[vidx] = pcNor;
abHad[vidx] = true;
}
}
}
else
{
const float fLimit = cos(configMaxAngle);
for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
{
// get all vertices that share this one ...
vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
aiVector3D pcNor;
for (unsigned int a = 0; a < verticesFound.size(); ++a)
{
register unsigned int vidx = verticesFound[a];
// check whether the angle between the two normals is not too large
if (pMesh->mNormals[vidx] * pMesh->mNormals[i] < fLimit)
continue;
pcNor += pMesh->mNormals[vidx];
}
pcNor.Normalize();
pcNew[i] = pcNor;
}
}
delete[] pMesh->mNormals; delete[] pMesh->mNormals;
pMesh->mNormals = pcNew; pMesh->mNormals = pcNew;

View File

@ -101,9 +101,10 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes normals for a specific mesh /** Computes normals for a specific mesh
* @param pcMesh Mesh * @param pcMesh Mesh
* @param meshIndex Index of the mesh
* @return true if vertex normals have been computed * @return true if vertex normals have been computed
*/ */
bool GenMeshVertexNormals (aiMesh* pcMesh); bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex);
private: private:

View File

@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
template <class T> template <class T>
inline void SetGenericProperty(std::map< uint32_t, T >& list, inline void SetGenericProperty(std::map< uint32_t, T >& list,
const char* szName, const T& value, bool* bWasExisting) const char* szName, const T& value, bool* bWasExisting = NULL)
{ {
ai_assert(NULL != szName); ai_assert(NULL != szName);
@ -85,4 +85,39 @@ inline T GetGenericProperty(const std::map< uint32_t, T >& list,
return (*it).second; return (*it).second;
} }
// ------------------------------------------------------------------------------------------------
// Special version for pointer types - they will be deleted when replaced with another value
// passing NULL removes the whole property
template <class T>
inline void SetGenericPropertyPtr(std::map< uint32_t, T* >& list,
const char* szName, T* value, bool* bWasExisting = NULL)
{
ai_assert(NULL != szName);
typedef std::map< uint32_t, T* > GenericPropertyMap;
typedef std::pair< uint32_t, T* > GenericPair;
uint32_t hash = SuperFastHash(szName);
typename GenericPropertyMap::iterator it = list.find(hash);
if (it == list.end())
{
if (bWasExisting)*bWasExisting = false;
list.insert(GenericPair( hash, value ));
return;
}
if ((*it).second != value)
{
delete (*it).second;
(*it).second = value;
}
if (!value)
{
list.erase(it);
}
if (bWasExisting)*bWasExisting = true;
}
#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED #endif // !! AI_GENERIC_PROPERTY_H_INCLUDED

View File

@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "DefaultIOStream.h" #include "DefaultIOStream.h"
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
#include "GenericProperty.h" #include "GenericProperty.h"
#include "ProcessHelper.h"
// Importers // Importers
#if (!defined AI_BUILD_NO_X_IMPORTER) #if (!defined AI_BUILD_NO_X_IMPORTER)
@ -167,6 +168,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif #endif
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -179,11 +181,12 @@ Importer::Importer() :
// allocate a default IO handler // allocate a default IO handler
mIOHandler = new DefaultIOSystem; mIOHandler = new DefaultIOSystem;
mIsDefaultHandler = true; mIsDefaultHandler = true;
bExtraVerbose = false; // disable extra verbose mode by default bExtraVerbose = false; // disable extra verbose mode by default
// add an instance of each worker class here // add an instance of each worker class here
// the order doesn't really care, however file formats that are // the order doesn't really care, however file formats that are
// used more frequently than others should be at the beginning. // used more frequently than others should be at the beginning.
mImporter.reserve(25);
#if (!defined AI_BUILD_NO_X_IMPORTER) #if (!defined AI_BUILD_NO_X_IMPORTER)
mImporter.push_back( new XFileImporter()); mImporter.push_back( new XFileImporter());
@ -248,6 +251,7 @@ Importer::Importer() :
// add an instance of each post processing step here in the order // add an instance of each post processing step here in the order
// of sequence it is executed. steps that are added here are not validated - // of sequence it is executed. steps that are added here are not validated -
// as RegisterPPStep() does - all dependencies must be there. // as RegisterPPStep() does - all dependencies must be there.
mPostProcessingSteps.reserve(25);
#if (!defined AI_BUILD_NO_VALIDATEDS_PROCESS) #if (!defined AI_BUILD_NO_VALIDATEDS_PROCESS)
mPostProcessingSteps.push_back( new ValidateDSProcess()); // must be first mPostProcessingSteps.push_back( new ValidateDSProcess()); // must be first
@ -276,6 +280,11 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_GENFACENORMALS_PROCESS) #if (!defined AI_BUILD_NO_GENFACENORMALS_PROCESS)
mPostProcessingSteps.push_back( new GenFaceNormalsProcess()); mPostProcessingSteps.push_back( new GenFaceNormalsProcess());
#endif #endif
// DON'T change the order of these five!
mPostProcessingSteps.push_back( new ComputeSpatialSortProcess());
#if (!defined AI_BUILD_NO_GENVERTEXNORMALS_PROCESS) #if (!defined AI_BUILD_NO_GENVERTEXNORMALS_PROCESS)
mPostProcessingSteps.push_back( new GenVertexNormalsProcess()); mPostProcessingSteps.push_back( new GenVertexNormalsProcess());
#endif #endif
@ -285,6 +294,10 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_JOINVERTICES_PROCESS) #if (!defined AI_BUILD_NO_JOINVERTICES_PROCESS)
mPostProcessingSteps.push_back( new JoinVerticesProcess()); mPostProcessingSteps.push_back( new JoinVerticesProcess());
#endif #endif
mPostProcessingSteps.push_back( new DestroySpatialSortProcess());
#if (!defined AI_BUILD_NO_SPLITLARGEMESHES_PROCESS) #if (!defined AI_BUILD_NO_SPLITLARGEMESHES_PROCESS)
mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Vertex()); mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Vertex());
#endif #endif
@ -297,6 +310,15 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_IMPROVECACHELOCALITY_PROCESS) #if (!defined AI_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
mPostProcessingSteps.push_back( new ImproveCacheLocalityProcess()); mPostProcessingSteps.push_back( new ImproveCacheLocalityProcess());
#endif #endif
// allocate a SharedPostProcessInfo object and store pointers to it
// in all post-process steps in the list.
mPPShared = new SharedPostProcessInfo();
for (std::vector<BaseProcess*>::iterator it = mPostProcessingSteps.begin(),
end = mPostProcessingSteps.end(); it != end; ++it)
{
(*it)->SetSharedData(mPPShared);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -313,6 +335,9 @@ Importer::~Importer()
// kill imported scene. Destructors should do that recursivly // kill imported scene. Destructors should do that recursivly
delete mScene; delete mScene;
// delete shared post-processing data
delete mPPShared;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -519,10 +544,12 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
if (bExtraVerbose)mScene->mFlags &= ~0x80000000; if (bExtraVerbose)mScene->mFlags &= ~0x80000000;
#endif // ! DEBUG #endif // ! DEBUG
} }
// if failed, extract the error string // if failed, extract the error string
else if( !mScene)mErrorString = imp->GetErrorText(); else if( !mScene)mErrorString = imp->GetErrorText();
// clear any data allocated by post-process steps
mPPShared->Clean();
// either successful or failure - the pointer expresses it anyways // either successful or failure - the pointer expresses it anyways
return mScene; return mScene;
} }

View File

@ -44,13 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <vector> #include <vector>
#include "JoinVerticesProcess.h"
#include "SpatialSort.h"
#include "../include/DefaultLogger.h" #include "../include/DefaultLogger.h"
#include "../include/aiPostProcess.h" #include "../include/aiPostProcess.h"
#include "../include/aiMesh.h" #include "../include/aiMesh.h"
#include "../include/aiScene.h" #include "../include/aiScene.h"
// internal headers
#include "JoinVerticesProcess.h"
#include "ProcessHelper.h"
using namespace Assimp; using namespace Assimp;
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
@ -141,25 +144,32 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// for each vertex whether it was replaced by an existing unique vertex (true) or a new vertex was created for it (false) // for each vertex whether it was replaced by an existing unique vertex (true) or a new vertex was created for it (false)
std::vector<bool> isVertexUnique( pMesh->mNumVertices, false); std::vector<bool> isVertexUnique( pMesh->mNumVertices, false);
// calculate the position bounds so we have a reliable epsilon to check position differences against // a little helper to find locally close vertices faster
aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f); // FIX: check whether we can reuse the SpatialSort of a previous step
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) const float epsilon = 1e-5f;
float posEpsilon;
SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder;
if (shared)
{ {
minVec.x = std::min( minVec.x, pMesh->mVertices[a].x); std::vector<std::pair<SpatialSort,float> >* avf;
minVec.y = std::min( minVec.y, pMesh->mVertices[a].y); shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
minVec.z = std::min( minVec.z, pMesh->mVertices[a].z); if (avf)
maxVec.x = std::max( maxVec.x, pMesh->mVertices[a].x); {
maxVec.y = std::max( maxVec.y, pMesh->mVertices[a].y); std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
maxVec.z = std::max( maxVec.z, pMesh->mVertices[a].z); vertexFinder = &blubb.first;
posEpsilon = blubb.second;
}
}
if (!vertexFinder)
{
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
vertexFinder = &_vertexFinder;
posEpsilon = ComputePositionEpsilon(pMesh);
} }
// squared because we check against squared length of the vector difference // squared because we check against squared length of the vector difference
const float epsilon = 1e-5f;
const float posEpsilon = (maxVec - minVec).Length() * epsilon;
const float squareEpsilon = epsilon * epsilon; const float squareEpsilon = epsilon * epsilon;
// a little helper to find locally close vertices faster
SpatialSort vertexFinder( pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
std::vector<unsigned int> verticesFound; std::vector<unsigned int> verticesFound;
// now check each vertex if it brings something new to the table // now check each vertex if it brings something new to the table
@ -177,7 +187,7 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
v.mTexCoords[b] = (pMesh->mTextureCoords[b] != NULL) ? pMesh->mTextureCoords[b][a] : aiVector3D( 0, 0, 0); v.mTexCoords[b] = (pMesh->mTextureCoords[b] != NULL) ? pMesh->mTextureCoords[b][a] : aiVector3D( 0, 0, 0);
// collect all vertices that are close enough to the given position // collect all vertices that are close enough to the given position
vertexFinder.FindPositions( v.mPosition, posEpsilon, verticesFound); vertexFinder->FindPositions( v.mPosition, posEpsilon, verticesFound);
unsigned int matchIndex = 0xffffffff; unsigned int matchIndex = 0xffffffff;
// check all unique vertices close to the position if this vertex is already present among them // check all unique vertices close to the position if this vertex is already present among them
@ -233,7 +243,8 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// store where to found the matching unique vertex // store where to found the matching unique vertex
replaceIndex[a] = matchIndex; replaceIndex[a] = matchIndex;
isVertexUnique[a] = false; isVertexUnique[a] = false;
} else }
else
{ {
// no unique vertex matches it upto now -> so add it // no unique vertex matches it upto now -> so add it
replaceIndex[a] = (unsigned int)uniqueVertices.size(); replaceIndex[a] = (unsigned int)uniqueVertices.size();

View File

@ -192,6 +192,18 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
} }
} }
// ------------------------------------------------------------------------------------------------
LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
{
list.push_back(LWO::Texture());
LWO::Texture* tex = &list.back();
std::string type;
GetS0(type,size);
return tex;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOBSurface(unsigned int size) void LWOImporter::LoadLWOBSurface(unsigned int size)
{ {
@ -278,39 +290,39 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
// color texture // color texture
case AI_LWO_CTEX: case AI_LWO_CTEX:
{ {
surf.mColorTextures.push_back(Texture()); pTex = SetupNewTextureLWOB(surf.mColorTextures,
pTex = &surf.mColorTextures.back(); head->length);
break; break;
} }
// diffuse texture // diffuse texture
case AI_LWO_DTEX: case AI_LWO_DTEX:
{ {
surf.mDiffuseTextures.push_back(Texture()); pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
pTex = &surf.mDiffuseTextures.back(); head->length);
break; break;
} }
// specular texture // specular texture
case AI_LWO_STEX: case AI_LWO_STEX:
{ {
surf.mSpecularTextures.push_back(Texture()); pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
pTex = &surf.mSpecularTextures.back(); head->length);
break; break;
} }
// bump texture // bump texture
case AI_LWO_BTEX: case AI_LWO_BTEX:
{ {
surf.mBumpTextures.push_back(Texture()); pTex = SetupNewTextureLWOB(surf.mBumpTextures,
pTex = &surf.mBumpTextures.back(); head->length);
break; break;
} }
// transparency texture // transparency texture
case AI_LWO_TTEX: case AI_LWO_TTEX:
{ {
surf.mOpacityTextures.push_back(Texture()); pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
pTex = &surf.mOpacityTextures.back(); head->length);
break; break;
} }
// texture path // texture path
case AI_LWO_TIMG: case AI_LWO_TIMG:
{ {
if (pTex) if (pTex)

View File

@ -56,7 +56,6 @@ Original copyright notice: "Ernie Wright 17 Sep 00"
// internal headers // internal headers
#include "IFF.h" #include "IFF.h"
#include "SmoothingGroups.h"
namespace Assimp { namespace Assimp {
namespace LWO { namespace LWO {

View File

@ -41,12 +41,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the LWO importer class */ /** @file Implementation of the LWO importer class */
// internal headers
#include "LWOLoader.h"
#include "MaterialSystem.h"
#include "StringComparison.h"
#include "SGSpatialSort.h"
#include "ByteSwap.h"
// public assimp headers // public assimp headers
#include "../include/IOStream.h" #include "../include/IOStream.h"
@ -55,6 +49,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../include/aiAssert.h" #include "../include/aiAssert.h"
#include "../include/assimp.hpp" #include "../include/assimp.hpp"
// internal headers
#include "LWOLoader.h"
#include "MaterialSystem.h"
#include "StringComparison.h"
#include "SGSpatialSort.h"
#include "ByteSwap.h"
#include "ProcessHelper.h"
// boost headers // boost headers
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <sstream> #include <sstream>
@ -313,7 +315,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
aiVector3D*& pp = pvUV[w]; aiVector3D*& pp = pvUV[w];
const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx]; const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
pp->x = src.x; pp->x = src.x;
pp->y = 1.0f - src.y; // DX to OGL pp->y = 1.f-src.y; // DX to OGL
pp++; pp++;
} }
@ -414,20 +416,7 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
out[face.mIndices[i]] = vNor; out[face.mIndices[i]] = vNor;
} }
if (!surface.mMaximumSmoothAngle)return; if (!surface.mMaximumSmoothAngle)return;
const float posEpsilon = ComputePositionEpsilon(mesh);
// calculate the position bounds so we have a reliable epsilon to
// check position differences against
aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
for( unsigned int a = 0; a < mesh->mNumVertices; a++)
{
minVec.x = std::min( minVec.x, mesh->mVertices[a].x);
minVec.y = std::min( minVec.y, mesh->mVertices[a].y);
minVec.z = std::min( minVec.z, mesh->mVertices[a].z);
maxVec.x = std::max( maxVec.x, mesh->mVertices[a].x);
maxVec.y = std::max( maxVec.y, mesh->mVertices[a].y);
maxVec.z = std::max( maxVec.z, mesh->mVertices[a].z);
}
const float posEpsilon = (maxVec - minVec).Length() * 1e-5f;
// now generate the spatial sort tree // now generate the spatial sort tree
SGSpatialSort sSort; SGSpatialSort sSort;
@ -443,9 +432,11 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
} }
// sort everything - this takes O(logn) time // sort everything - this takes O(logn) time
sSort.Prepare(); sSort.Prepare();
std::vector<unsigned int> poResult;poResult.reserve(20); std::vector<unsigned int> poResult;
poResult.reserve(20);
const float fLimit = cos(surface.mMaximumSmoothAngle); const float fLimit = cos(surface.mMaximumSmoothAngle);
std::vector<bool> vertexDone(mesh->mNumVertices,false);
// generate vertex normals. We have O(logn) for the binary lookup, which we need // generate vertex normals. We have O(logn) for the binary lookup, which we need
// for n elements, thus the EXPECTED complexity is O(nlogn) // for n elements, thus the EXPECTED complexity is O(nlogn)
@ -457,19 +448,26 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices; unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx) for (; beginIdx != endIdx; ++beginIdx)
{ {
sSort.FindPositions(mesh->mVertices[*beginIdx],sg,posEpsilon,poResult,true); register unsigned int idx = *beginIdx;
if (vertexDone[idx])continue;
sSort.FindPositions(mesh->mVertices[idx],sg,posEpsilon,poResult,true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals; aiVector3D vNormals;
for (std::vector<unsigned int>::const_iterator for (a = poResult.begin();a != end;++a)
a = poResult.begin(), end = poResult.end();
a != end;++a)
{ {
const aiVector3D& v = faceNormals[*a]; const aiVector3D& v = faceNormals[*a];
if (v * faceNormals[*beginIdx] < fLimit)continue; if (v * faceNormals[idx] < fLimit)continue;
vNormals += v; vNormals += v;
} }
vNormals.Normalize(); vNormals.Normalize();
mesh->mNormals[*beginIdx] = vNormals; for (a = poResult.begin();a != end;++a)
{
mesh->mNormals[*a] = vNormals;
vertexDone[*a] = true;
}
} }
} }
} }
@ -802,12 +800,12 @@ void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
it != end;++it) it != end;++it)
{ {
T& chan = *it; T& chan = *it;
chan.abAssigned[srcIdx] = true;
chan.abAssigned.resize(chan.abAssigned.size()+1,false);
for (unsigned int a = 0; a < chan.dims;++a) for (unsigned int a = 0; a < chan.dims;++a)
{
chan.rawData.push_back(chan.rawData[srcIdx*chan.dims+a]); chan.rawData.push_back(chan.rawData[srcIdx*chan.dims+a]);
chan.abAssigned[srcIdx] = true;
chan.abAssigned.resize(chan.abAssigned.size()+1,false);
}
} }
} }
@ -891,10 +889,13 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
float temp[4]; float temp[4];
const unsigned int numPoints = (unsigned int)pointList.size();
const unsigned int numFaces = (unsigned int)list.size();
while (mFileBuffer < end) while (mFileBuffer < end)
{ {
unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs; unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
if (idx >= pointList.size()) if (idx >= numPoints)
{ {
DefaultLogger::get()->warn("LWO2: vertex index in vmap/vmad is out of range"); DefaultLogger::get()->warn("LWO2: vertex index in vmap/vmad is out of range");
mFileBuffer += base->dims*4;continue; mFileBuffer += base->dims*4;continue;
@ -906,24 +907,29 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
{ {
// we have already a VMAP entry for this vertex - thus // we have already a VMAP entry for this vertex - thus
// we need to duplicate the corresponding polygon. // we need to duplicate the corresponding polygon.
if (polyIdx >= list.size()) if (polyIdx >= numFaces)
{ {
DefaultLogger::get()->warn("LWO2: VMAD polygon index is out of range"); DefaultLogger::get()->warn("LWO2: VMAD polygon index is out of range");
mFileBuffer += base->dims*4;continue; mFileBuffer += base->dims*4;continue;
} }
LWO::Face& src = list[polyIdx]; LWO::Face& src = list[polyIdx];
refList.resize(refList.size()+src.mNumIndices, 0xffffffff);
// generate new vertex positions // generate new vertex positions
for (unsigned int i = 0; i < src.mNumIndices;++i) for (unsigned int i = 0; i < src.mNumIndices;++i)
{ {
register unsigned int srcIdx = src.mIndices[i]; register unsigned int srcIdx = src.mIndices[i];
if (idx == srcIdx)
{
idx = (unsigned int)pointList.size();
}
src.mIndices[i] = (unsigned int)pointList.size();
// store the index of the new vertex in the old vertex // store the index of the new vertex in the old vertex
// so we get a single linked list we can traverse in // so we get a single linked list we can traverse in
// only one direction // only one direction
refList.push_back(0xffffffff); AddToSingleLinkedList(refList,srcIdx,src.mIndices[i]);
AddToSingleLinkedList(refList,srcIdx,(src.mIndices[i] = (unsigned int)pointList.size()));
pointList.push_back(pointList[srcIdx]); pointList.push_back(pointList[srcIdx]);
CreateNewEntry(mCurLayer->mVColorChannels, srcIdx ); CreateNewEntry(mCurLayer->mVColorChannels, srcIdx );

View File

@ -339,6 +339,17 @@ private:
void ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups, void ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
const LWO::Surface& surface); const LWO::Surface& surface);
// -------------------------------------------------------------------
/** Setup a new texture after the corresponding chunk was
* encountered in the file.
* @param list Texture list
* @param size Maximum number of bytes to be read
* @return Pointer to new texture
*/
LWO::Texture* SetupNewTextureLWOB(LWO::TextureList& list,
unsigned int size);
protected: protected:
/** true if the file is a LWO2 file*/ /** true if the file is a LWO2 file*/

View File

@ -87,7 +87,6 @@ struct Vertex
aiVector3D normal; aiVector3D normal;
aiVector2D texCoords; aiVector2D texCoords;
uint32_t numWeights; uint32_t numWeights;
Weight weights; // variable sized
} PACK_STRUCT; } PACK_STRUCT;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -147,7 +146,6 @@ struct Frame {
aiVector3D localOrigin; // midpoint of bounds, used for sphere cull aiVector3D localOrigin; // midpoint of bounds, used for sphere cull
float radius; // dist from localOrigin to corner float radius; // dist from localOrigin to corner
char name[16]; char name[16];
Bone bones[1]; // [numBones]
} PACK_STRUCT; } PACK_STRUCT;

View File

@ -157,6 +157,9 @@ void MDRImporter::ValidateLODHeader(BE_NCONST MDR::LOD* pcLOD)
const unsigned int iMax = this->fileSize - (unsigned int)((int8_t*)pcLOD-(int8_t*)pcHeader); const unsigned int iMax = this->fileSize - (unsigned int)((int8_t*)pcLOD-(int8_t*)pcHeader);
if (!pcLOD->numSurfaces)
throw new ImportErrorException("MDR: LOD has zero surfaces assigned");
uint32_t cur = pcLOD->ofsSurfaces; uint32_t cur = pcLOD->ofsSurfaces;
for (unsigned int i = 0; i < pcLOD->numSurfaces;++i) for (unsigned int i = 0; i < pcLOD->numSurfaces;++i)
{ {
@ -208,9 +211,10 @@ void MDRImporter::SetupProperties(const Importer* pImp)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void MDRImporter::InternReadFile( void MDRImporter::InternReadFile( const std::string& pFile,
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) aiScene* pScene, IOSystem* pIOHandler)
{ {
#if 0
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile)); boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
// Check whether we can read from the file // Check whether we can read from the file
@ -229,4 +233,113 @@ void MDRImporter::InternReadFile(
// validate the file header and do BigEndian byte swapping for all sub headers // validate the file header and do BigEndian byte swapping for all sub headers
this->pcHeader = (BE_NCONST MDR::Header*)this->mBuffer; this->pcHeader = (BE_NCONST MDR::Header*)this->mBuffer;
this->ValidateHeader(); this->ValidateHeader();
// go to the first LOD
LE_NCONST MDR::LOD* lod = (LE_NCONST MDR::LOD*)((uint8_t*)this->pcHeader+pcHeader->ofsLODs);
std::vector<aiMesh*> outMeshes;
outMeshes.reserve(lod->numSurfaces);
// get a pointer to the first surface
LE_NCONST MDR::Surface* surf = (LE_NCONST MDR::Surface*)((uint8_t*)lod+lod->ofsSurfaces);
for (uint32_t i = 0; i < lod->numSurfaces; ++i)
{
if (surf->numTriangles && surf->numVerts && surf->numBoneReferences)
{
outMeshes.push_back(new aiMesh());
aiMesh* mesh = outMeshes.back();
mesh->mNumFaces = surf->numTriangles;
mesh->mNumVertices = mesh->mNumFaces*3;
mesh->mNumBones = surf->numBoneReferences;
mesh->mFaces = new aiFace[mesh->mNumFaces];
mesh->mVertices = new aiVector3D[mesh->mNumVertices];
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
mesh->mBones = new aiBone*[mesh->mNumBones];
// allocate output bones
for (unsigned int p = 0; p < mesh->mNumBones;++p)
{
aiBone* bone = mesh->mBones[p] = new aiBone();
bone->mName.length = ::sprintf( bone->mName.data, "B_%i",p);
}
struct VertexInfo
{
aiVector3D xyz;
aiVector3D normal;
aiVector3D uv;
unsigned int start,num;
};
typedef std::pair<uint32_t,float> BoneWeightInfo;
std::vector<BoneWeightInfo> mWeights;
mWeights.reserve(surf->numVerts << 1);
std::vector<VertexInfo> mVertices(surf->numVerts);
// get a pointer to the first vertex
LE_NCONST MDR::Vertex* v = (LE_NCONST MDR::Vertex*)((uint8_t*)surf+surf->ofsVerts);
for (unsigned int m = 0; m < surf->numVerts; ++m)
{
// get a pointer to the next vertex
v = (LE_NCONST MDR::Vertex*)((uint8_t*)(v+1) + v->numWeights*sizeof(MDR::Weight));
AI_SWAP4(v->numWeights);
AI_SWAP4(v->normal.x);AI_SWAP4(v->normal.y);AI_SWAP4(v->normal.z);
AI_SWAP4(v->texCoords.x);AI_SWAP4(v->texCoords.y);
VertexInfo& vert = mVertices[m];
vert.uv.x = v->texCoords.x; vert.uv.y = v->texCoords.y;
vert.normal = v->normal;
vert.start = (unsigned int)mWeights.size();
vert.num = v->numWeights;
for (unsigned int l = 0; l < vert.num; ++l)
{
}
}
// find out how large the output weight buffers must be
LE_NCONST MDR::Triangle* tri = (LE_NCONST MDR::Triangle*)((uint8_t*)surf+surf->ofsTriangles);
LE_NCONST MDR::Triangle* const triEnd = tri + surf->numTriangles;
for (; tri != triEnd; ++tri)
{
for (unsigned int o = 0; o < 3;++o)
{
AI_SWAP4(tri->indexes[o]);
register unsigned int temp = tri->indexes[o];
if (temp >= surf->numVerts)
throw new ImportErrorException("MDR: Vertex index is out of range");
VertexInfo& vert = mVertices[temp];
for (unsigned int l = vert.start; l < vert.start + vert.num; ++l)
{
if (mWeights[l].first >= surf->numBoneReferences)
throw new ImportErrorException("MDR: Bone index is out of range");
++mesh->mBones[mWeights[l].first]->mNumWeights;
}
}
}
// allocate storage for output bone weights
for (unsigned int p = 0; p < mesh->mNumBones;++p)
{
aiBone* bone = mesh->mBones[p];
ai_assert(0 != bone->mNumWeights);
bone->mWeights = new aiVertexWeight[bone->mNumWeights];
}
// and build the final output buffers
}
// get a pointer to the next surface
surf = (LE_NCONST MDR::Surface*)((uint8_t*)surf + surf->ofsEnd);
}
pScene->mNumMeshes = (unsigned int) outMeshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
::memcpy(pScene->mMeshes,&outMeshes[0],sizeof(void*)*pScene->mNumMeshes);
#endif
} }

View File

@ -0,0 +1,113 @@
/*
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.
----------------------------------------------------------------------
*/
#ifndef AI_PROCESS_HELPER_H_INCLUDED
#define AI_PROCESS_HELPER_H_INCLUDED
#include "SpatialSort.h"
#include "../include/aiPostProcess.h"
namespace Assimp {
// ------------------------------------------------------------------------------------------------
inline float ComputePositionEpsilon(const aiMesh* pMesh)
{
const float epsilon = 1e-5f;
// calculate the position bounds so we have a reliable epsilon to check position differences against
aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
{
minVec.x = std::min( minVec.x, pMesh->mVertices[a].x);
minVec.y = std::min( minVec.y, pMesh->mVertices[a].y);
minVec.z = std::min( minVec.z, pMesh->mVertices[a].z);
maxVec.x = std::max( maxVec.x, pMesh->mVertices[a].x);
maxVec.y = std::max( maxVec.y, pMesh->mVertices[a].y);
maxVec.z = std::max( maxVec.z, pMesh->mVertices[a].z);
}
return (maxVec - minVec).Length() * epsilon;
}
// ------------------------------------------------------------------------------------------------
class ComputeSpatialSortProcess : public BaseProcess
{
bool IsActive( unsigned int pFlags) const
{
return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace |
aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
}
void Execute( aiScene* pScene)
{
typedef std::pair<SpatialSort, float> _Type;
std::vector<_Type>* p = new std::vector<_Type>(pScene->mNumMeshes);
std::vector<_Type>::iterator it = p->begin();
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i, ++it)
{
aiMesh* mesh = pScene->mMeshes[i];
_Type& blubb = *it;
blubb.first.Fill(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D));
blubb.second = ComputePositionEpsilon(mesh);
}
shared->AddProperty(AI_SPP_SPATIAL_SORT,p);
}
};
// ------------------------------------------------------------------------------------------------
class DestroySpatialSortProcess : public BaseProcess
{
bool IsActive( unsigned int pFlags) const
{
return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace |
aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
}
void Execute( aiScene* pScene)
{
shared->RemoveProperty(AI_SPP_SPATIAL_SORT);
}
};
} // !! Assimp
#endif // !! AI_PROCESS_HELPER_H_INCLUDED

View File

@ -62,7 +62,6 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
{ {
T& face = sMesh.mFaces[a]; T& face = sMesh.mFaces[a];
// assume it is a triangle
aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]]; aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]];
aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]]; aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]];
aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]]; aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]];
@ -76,9 +75,7 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
sMesh.mNormals[face.mIndices[2]] = vNor; sMesh.mNormals[face.mIndices[2]] = vNor;
} }
// calculate the position bounds so we have a reliable epsilon to // calculate the position bounds so we have a reliable epsilon to check position differences against
// check position differences against
// @Schrompf: This is the 6th time this snippet is repeated!
aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f); aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
for( unsigned int a = 0; a < sMesh.mPositions.size(); a++) for( unsigned int a = 0; a < sMesh.mPositions.size(); a++)
{ {
@ -104,14 +101,17 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
} }
sSort.Prepare(); sSort.Prepare();
std::vector<bool> vertexDone(sMesh.mPositions.size(),false);
for( typename std::vector<T>::iterator i = sMesh.mFaces.begin(); for( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
i != sMesh.mFaces.end();++i) i != sMesh.mFaces.end();++i)
{ {
std::vector<unsigned int> poResult; std::vector<unsigned int> poResult;
for (unsigned int c = 0; c < 3;++c) for (unsigned int c = 0; c < 3;++c)
{ {
sSort.FindPositions(sMesh.mPositions[(*i).mIndices[c]],(*i).iSmoothGroup, register unsigned int idx = (*i).mIndices[c];
if (vertexDone[idx])continue;
sSort.FindPositions(sMesh.mPositions[idx],(*i).iSmoothGroup,
posEpsilon,poResult); posEpsilon,poResult);
aiVector3D vNormals; aiVector3D vNormals;
@ -120,10 +120,18 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
a != poResult.end();++a) a != poResult.end();++a)
{ {
vNormals += sMesh.mNormals[(*a)]; vNormals += sMesh.mNormals[(*a)];
//fDiv += 1.0f;
} }
vNormals.Normalize(); vNormals.Normalize();
avNormals[(*i).mIndices[c]] = vNormals;
// write back into all affected normals
for (std::vector<unsigned int>::const_iterator
a = poResult.begin();
a != poResult.end();++a)
{
idx = *a;
avNormals [idx] = vNormals;
vertexDone[idx] = true;
}
} }
} }
sMesh.mNormals = avNormals; sMesh.mNormals = avNormals;

View File

@ -47,7 +47,22 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructs a spatially sorted representation from the given position array. // Constructs a spatially sorted representation from the given position array.
SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions, unsigned int pElementOffset) SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,
unsigned int pElementOffset)
{
Fill(pPositions,pNumPositions,pElementOffset);
}
// ------------------------------------------------------------------------------------------------
// Destructor
SpatialSort::~SpatialSort()
{
// nothing to do here, everything destructs automatically
}
// ------------------------------------------------------------------------------------------------
void SpatialSort::Fill( const aiVector3D* pPositions, unsigned int pNumPositions,
unsigned int pElementOffset)
{ {
// define the reference plane. We choose some arbitrary vector away from all basic axises // define the reference plane. We choose some arbitrary vector away from all basic axises
// in the hope that no model spreads all its vertices along this plane. // in the hope that no model spreads all its vertices along this plane.
@ -70,13 +85,6 @@ SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositio
std::sort( mPositions.begin(), mPositions.end()); std::sort( mPositions.begin(), mPositions.end());
} }
// ------------------------------------------------------------------------------------------------
// Destructor
SpatialSort::~SpatialSort()
{
// nothing to do here, everything destructs automatically
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns an iterator for all positions close to the given position. // Returns an iterator for all positions close to the given position.
void SpatialSort::FindPositions( const aiVector3D& pPosition, float pRadius, std::vector<unsigned int>& poResults) const void SpatialSort::FindPositions( const aiVector3D& pPosition, float pRadius, std::vector<unsigned int>& poResults) const

View File

@ -67,9 +67,23 @@ public:
* by index. * by index.
* @param pPositions Pointer to the first position vector of the array. * @param pPositions Pointer to the first position vector of the array.
* @param pNumPositions Number of vectors to expect in that array. * @param pNumPositions Number of vectors to expect in that array.
* @param pElementOffset Offset in bytes from the beginning of one vector in memory to the beginning of the next vector. * @param pElementOffset Offset in bytes from the beginning of one vector in memory
* to the beginning of the next vector.
*/ */
SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions, unsigned int pElementOffset); SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,
unsigned int pElementOffset);
/** Sets the input data for the SpatialSort. This replaces the old data.
*
* @param pPositions Pointer to the first position vector of the array.
* @param pNumPositions Number of vectors to expect in that array.
* @param pElementOffset Offset in bytes from the beginning of one vector in memory
* to the beginning of the next vector.
*/
void Fill( const aiVector3D* pPositions, unsigned int pNumPositions,
unsigned int pElementOffset);
/** Destructor */ /** Destructor */
~SpatialSort(); ~SpatialSort();

View File

@ -106,10 +106,9 @@ inline const char* fast_atof_move( const char* c, float& out)
++c; ++c;
inv = true; inv = true;
} }
else if (*c=='+')++c;
//f = (float)strtol(c, &t, 10);
f = (float) strtol10_64 ( c, &c ); f = (float) strtol10_64 ( c, &c );
if (*c == '.') if (*c == '.')
{ {
++c; ++c;
@ -129,10 +128,10 @@ inline const char* fast_atof_move( const char* c, float& out)
c = t; c = t;
if (*c == 'e') // FIX: a large 'E' should be allowed, too
if (*c == 'e' || *c == 'E')
{ {
++c; ++c;
//float exp = (float)strtol(c, &t, 10);
bool einv = (*c=='-'); bool einv = (*c=='-');
if (einv) if (einv)
++c; ++c;

View File

@ -116,7 +116,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* that their tangents and bitangents are smoothed. * that their tangents and bitangents are smoothed.
* *
* This applies to the CalcTangentSpace-Step. The angle is specified * This applies to the CalcTangentSpace-Step. The angle is specified
* in degrees , so 180 is PI. The default value is * in degrees, so 180 is PI. The default value is
* 45 degrees. The maximum value is 175. * 45 degrees. The maximum value is 175.
* Property type: float. * Property type: float.
*/ */
@ -128,7 +128,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* This applies to the GenSmoothNormals-Step. The angle is specified * This applies to the GenSmoothNormals-Step. The angle is specified
* in degrees, so 180 is PI. The default value is * in degrees, so 180 is PI. The default value is
* 180 degrees (all vertex normals are smoothed). The maximum value is 175 * 175 degrees (all vertex normals are smoothed). The maximum value is 175
* Property type: float. * Property type: float.
*/ */
#define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE "pp.gsn.max_smoothing" #define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE "pp.gsn.max_smoothing"

View File

@ -76,6 +76,7 @@ namespace Assimp
class BaseImporter; class BaseImporter;
class BaseProcess; class BaseProcess;
class SharedPostProcessInfo;
class IOStream; class IOStream;
class IOSystem; class IOSystem;
@ -403,6 +404,9 @@ protected:
validateDataStructure-Step to be executed before validateDataStructure-Step to be executed before
and after every single postprocess step */ and after every single postprocess step */
bool bExtraVerbose; bool bExtraVerbose;
/** Used by post-process steps to share data */
SharedPostProcessInfo* mPPShared;
}; };
} // End of namespace Assimp } // End of namespace Assimp

View File

@ -0,0 +1,81 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
See the disclaimer in JNIEnvironment.h for licensing and distribution
conditions.
---------------------------------------------------------------------------
*/
/** @file Implementation of the JNI API for jAssimp */
#include "JNIEnvironment.h"
#include "JNILogger.h"
using namespace Assimp;
namespace Assimp {
namespace JNIBridge {
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_Bone::Initialize()
{
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// load a handle to the class
if(!(Class = pc->FindClass("assimp.Bone")))
JNIEnvironment::Get()->ThrowNativeError("Unable to load class assimp.Bone");
DefaultCtor = pc->GetMethodID(Class,"<init>","");
// load all fields of the class
name = pc->GetFieldID(Class,"name", "Ljava.lang.String;");
weights = pc->GetFieldID(Class,"weights", "[Lassimp.Bone.Weight;");
// check whether all fields have been loaded properly
if (!name || !weights)
JNIEnvironment::Get()->ThrowNativeError("Unable to load all fields of class assimp.Bone");
Weight.Initialize();
}
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_Bone::Fill(jobject obj,const aiBone* pcSrc)
{
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
}
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_Bone::_Weight::Initialize()
{
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// load a handle to the class
if(!(Class = pc->FindClass("assimp.Bone.Weight")))
JNIEnvironment::Get()->ThrowNativeError("Unable to load class assimp.Bone.Weights");
DefaultCtor = pc->GetMethodID(Class,"<init>","");
// load all fields of the class
index = pc->GetFieldID(Class,"index", "I");
weight = pc->GetFieldID(Class,"weight", "F");
// check whether all fields have been loaded properly
if (!index || !weight)
JNIEnvironment::Get()->ThrowNativeError("Unable to load all fields of class assimp.Bone.Weight");
}
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_Bone::_Weight::Fill(jobject obj,const aiVertexWeight* pcSrc)
{
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
pc->SetIntField(obj,index,(jint)pcSrc->mVertexId);
pc->SetFloatField(obj,index,(jfloat)pcSrc->mWeight);
}
}}

View File

@ -0,0 +1,53 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
See the disclaimer in JNIEnvironment.h for licensing and distribution
conditions.
---------------------------------------------------------------------------
*/
/** @file Implementation of the JNI API for jAssimp */
#include "JNIEnvironment.h"
#include "JNILogger.h"
using namespace Assimp;
namespace Assimp {
namespace JNIBridge {
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_BoneAnim::Initialize()
{
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// load a handle to the class
if(!(Class = pc->FindClass("assimp.BoneAnim")))
JNIEnvironment::Get()->ThrowNativeError("Unable to load class assimp.BoneAnim");
DefaultCtor = pc->GetMethodID(Class,"<init>","");
// load all fields of the class
mName = pc->GetFieldID(Class,"mName","Lassimp.Node;");
mPosKeys = pc->GetFieldID(Class,"mPosKeys", "[Lassimp.BoneAnim.Keyframe<[F>;");
mScalingKeys = pc->GetFieldID(Class,"mScalingKeys","[Lassimp.BoneAnim.Keyframe<[F>;");
mQuatKeys = pc->GetFieldID(Class,"mQuatKeys","[Lassimp.BoneAnim.Keyframe<Lassimp.Quaternion;>;");
// check whether all fields have been loaded properly
if (!mName || !mPosKeys || !mScalingKeys || !mQuatKeys)
JNIEnvironment::Get()->ThrowNativeError("Unable to load all fields of class assimp.BoneAnim");
}
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_BoneAnim::Fill(jobject obj,const aiBoneAnim* pcSrc)
{
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
}
}}

View File

@ -46,14 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "assimp_Importer.h" #include "assimp_Importer.h"
// include assimp // include assimp
#include "../../include/aiTypes.h" #include <aiTypes.h>
#include "../../include/aiMesh.h" #include <aiMesh.h>
#include "../../include/aiAnim.h" #include <aiAnim.h>
#include "../../include/aiScene.h" #include <aiScene.h>
#include "../../include/aiAssert.h" #include <aiAssert.h>
#include "../../include/aiPostProcess.h" #include <aiPostProcess.h>
#include "../../include/assimp.hpp" #include <assimp.hpp>
#include "../../include/DefaultLogger.h" #include <DefaultLogger.h>
// include all jAssimp internal header files // include all jAssimp internal header files
#include "JNIEnvironment.h" #include "JNIEnvironment.h"
@ -93,6 +93,7 @@ bool jValidateContext (JASSIMP_CONTEXT context)
DefaultLogger::get()->error("[jnibridge] Invalid context"); DefaultLogger::get()->error("[jnibridge] Invalid context");
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/* Used in debug builds to validate a given scene /* Used in debug builds to validate a given scene
*/ */
@ -107,6 +108,7 @@ bool jValidateScene (const aiScene* scene)
} }
#endif // ! ASSIMP_DEBUG #endif // ! ASSIMP_DEBUG
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/* Used in debug builds to validate a given scene /* Used in debug builds to validate a given scene
*/ */
@ -124,6 +126,7 @@ Assimp::Importer* jGetValidImporterScenePair (JASSIMP_CONTEXT jvmcontext)
#endif // ! ASSIMP_DEBUG #endif // ! ASSIMP_DEBUG
return pcImp; return pcImp;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/* /*
* Class: assimp_Importer * Class: assimp_Importer
@ -164,6 +167,7 @@ JNIEXPORT jlong JNICALL Java_assimp_Importer__1NativeInitContext
return context; return context;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/* /*
* Class: assimp_Importer * Class: assimp_Importer
@ -189,6 +193,7 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeFreeContext
JNIEnvironment::Get()->DetachFromCurrentThread(); JNIEnvironment::Get()->DetachFromCurrentThread();
return 0; return 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/* /*
* Class: assimp_Importer * Class: assimp_Importer
@ -213,7 +218,7 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
} }
// get the importer instance from the context // get the importer instance from the context
Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext; Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext;
aiScene* pcOut; const aiScene* pcOut;
// and load the file. The aiScene object itself remains accessible // and load the file. The aiScene object itself remains accessible
// via Importer.GetScene(). // via Importer.GetScene().
@ -227,7 +232,7 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
} }
// release the path again // release the path again
free((void*)szPath); ::free((void*)szPath);
// allocate a new assimp.Scene object to be returned by the importer // allocate a new assimp.Scene object to be returned by the importer
jobject jScene; jobject jScene;
@ -245,6 +250,67 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
return iRet; return iRet;
} }
// ------------------------------------------------------------------------------------------------
/*
* Class: assimp_Importer
* Method: _NativeSetPropertyInt
* Signature: (Ljava/lang/String;IJ)I
*/
JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyInt
(JNIEnv * jvmenv, jobject _this, jstring name, jint value, jlong jvmcontext)
{
#if (defined _DEBUG)
if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext))return AI_JNI_ERROR_RETURN;
#endif // ! ASSIMP_DEBUG
Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext;
const char* sz = JNU_GetStringNativeChars(jvmenv,name);
pcImp->SetPropertyInteger(sz,(int)value,NULL);
::free((void*)sz);
return 0;
}
// ------------------------------------------------------------------------------------------------
/*
* Class: assimp_Importer
* Method: _NativeSetPropertyFloat
* Signature: (Ljava/lang/String;FJ)I
*/
JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyFloat
(JNIEnv * jvmenv, jobject _this, jstring name, jfloat value, jlong jvmcontext)
{
#if (defined _DEBUG)
if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext))return AI_JNI_ERROR_RETURN;
#endif // ! ASSIMP_DEBUG
Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext;
const char* sz = JNU_GetStringNativeChars(jvmenv,name);
pcImp->SetPropertyFloat(sz,(float)value,NULL);
::free((void*)sz);
return 0;
}
// ------------------------------------------------------------------------------------------------
/*
* Class: assimp_Importer
* Method: _NativeSetPropertyString
* Signature: (Ljava/lang/String;Ljava/lang/String;J)I
*/
JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyString
(JNIEnv * jvmenv, jobject _this, jstring name, jstring value, jlong jvmcontext)
{
#if (defined _DEBUG)
if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext))return AI_JNI_ERROR_RETURN;
#endif // ! ASSIMP_DEBUG
Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext;
const char* sz = JNU_GetStringNativeChars(jvmenv,name);
const char* sz2 = JNU_GetStringNativeChars(jvmenv,value);
pcImp->SetPropertyString(sz,sz2,NULL);
::free((void*)sz);::free((void*)sz2);
return 0;
}
}; //! namespace JNIBridge }; //! namespace JNIBridge
}; //! namespace Assimp }; //! namespace Assimp

View File

@ -6,36 +6,8 @@ Open Asset Import Library (ASSIMP)
Copyright (c) 2006-2008, ASSIMP Development Team Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved. All rights reserved.
See the disclaimer in JNIEnvironment.h for licensing and distribution
Redistribution and use of this software in source and binary forms, conditions.
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.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
@ -106,29 +78,29 @@ JNIThreadData* JNIEnvironment::GetThread()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void JNIEnvironment::_java::_lang::_String::Initialize() void JNIEnvironment::_java::_lang::_String::Initialize()
{ {
JNIEnv* pcEnv = JJNIEnvironment::Get()->GetThread()->m_pcEnv; JNIEnv* pcEnv = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// first initialize some members // first initialize some members
if( !(this->Class = pcEnv->FindClass("java.lang.String"))) if( !(this->Class = pcEnv->FindClass("java.lang.String")))
JNIEnvironment::Get()->ThrowException("Unable to get handle of class java.lang.String"); JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class java.lang.String");
if( !(this->getBytes = pcEnv->GetMethodID(this->Class,"getBytes","()[byte"))) if( !(this->getBytes = pcEnv->GetMethodID(this->Class,"getBytes","()[byte")))
JNIEnvironment::Get()->ThrowException("Unable to get handle of class java.lang.String"); JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class java.lang.String");
if( !(this->constructor_ByteArray = pcEnv->GetStaticMethodID( if( !(this->constructor_ByteArray = pcEnv->GetStaticMethodID(
this->Class,"<init>","([byte)V"))) this->Class,"<init>","([byte)V")))
JNIEnvironment::Get()->ThrowException("Unable to get handle of class java.lang.String"); JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class java.lang.String");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void JNIEnvironment::_java::_lang::_Array::Initialize() void JNIEnvironment::_java::_lang::_Array::Initialize()
{ {
JNIEnv* pcEnv = JJNIEnvironment::Get()->GetThread()->m_pcEnv; JNIEnv* pcEnv = JNIEnvironment::Get()->GetThread()->m_pcEnv;
if( !(this->FloatArray_Class = pcEnv->FindClass("[F"))) if( !(this->FloatArray_Class = pcEnv->FindClass("[F")))
JNIEnvironment::Get()->ThrowException("Unable to get handle of class float[]"); JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class float[]");
if( !(this->IntArray_Class = pcEnv->FindClass("[I"))) if( !(this->IntArray_Class = pcEnv->FindClass("[I")))
JNIEnvironment::Get()->ThrowException("Unable to get handle of class int[]"); JNIEnvironment::Get()->ThrowNativeError("Unable to get handle of class int[]");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
jstring JNU_NewStringNative(JNIEnv *env, const char *str) jstring JNU_NewStringNative(JNIEnv *env, const char *str)
@ -140,7 +112,7 @@ jstring JNU_NewStringNative(JNIEnv *env, const char *str)
{ {
return NULL; /* out of memory error */ return NULL; /* out of memory error */
} }
len = strlen(str); len = (int)::strlen(str);
bytes = env->NewByteArray(len); bytes = env->NewByteArray(len);
if (bytes != NULL) if (bytes != NULL)
{ {
@ -187,13 +159,13 @@ char *JNU_GetStringNativeChars(JNIEnv *env, jstring jstr)
return result; return result;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
JNU_CopyDataToArray(jarray jfl, void* data, unsigned int size) void JNU_CopyDataToArray(JNIEnv* pc, jarray jfl, void* data, unsigned int size)
{ {
void* pf; void* pf;
jboolean iscopy = FALSE; jboolean iscopy = FALSE;
// lock the array and get direct access to its buffer // lock the array and get direct access to its buffer
if(!pf = pc->GetPrimitiveArrayCritical(jfl,&iscopy)) if(!(pf = pc->GetPrimitiveArrayCritical(jfl,&iscopy)))
JNIEnvironment::Get()->ThrowNativeError("Unable to lock array"); JNIEnvironment::Get()->ThrowNativeError("Unable to lock array");
// copy the data to the array // copy the data to the array
@ -202,6 +174,20 @@ JNU_CopyDataToArray(jarray jfl, void* data, unsigned int size)
// release our reference to the array // release our reference to the array
pc->ReleasePrimitiveArrayCritical(jfl,pf,0); pc->ReleasePrimitiveArrayCritical(jfl,pf,0);
} }
// ------------------------------------------------------------------------------------------------
void JNU_CopyObjectArrayToVM(JNIEnv* pc, const void** in, unsigned int num,
JNIEnvironment::_Base& type, jobjectArray& out)
{
jobjectArray jarr = pc->NewObjectArray(num,type.Class,0);
for (unsigned int i = 0; i < num;++i)
{
jobject jobj = pc->NewObject(type.Class,type.DefaultCtor);
type.Fill(jobj,in[i]);
pc->SetObjectArrayElement(jarr,i,jobj);
}
out = jarr;
}
};}; };};

View File

@ -48,9 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector> #include <vector>
#include <jni.h> #include <jni.h>
#include "../../../include/aiAssert.h" #include <aiAssert.h>
#include "../../../include/aiMesh.h" #include <aiMesh.h>
#include "../../../include/aiScene.h" #include <aiScene.h>
namespace Assimp { namespace Assimp {
@ -60,17 +60,18 @@ namespace JNIBridge {
#define AIJ_GET_HANDLE(__handle__) \ #define AIJ_GET_HANDLE(__handle__) \
(JNIEnvironment::Get()-> __handle__) (JNIEnvironment::Get()-> __handle__)
#define AIJ_GET_DEFAULT_CTOR_HANDLE (__handle__) \ #define AIJ_GET_DEFAULT_CTOR_HANDLE(__handle__) \
(JNIEnvironment::Get()-> __handle__ . DefaultCtor) (JNIEnvironment::Get()-> __handle__ . DefaultCtor)
#define AIJ_GET_CLASS_HANDLE (__handle__) \ #define AIJ_GET_CLASS_HANDLE(__handle__) \
(JNIEnvironment::Get()-> __handle__ . Class) (JNIEnvironment::Get()-> __handle__.Class)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @class JNIThreadData /** @class JNIThreadData
* @brief Manages a list of JNI data structures that are * @brief Manages a list of JNI data structures that are
* private to a thread. * private to a thread.
*/ */
// ---------------------------------------------------------------------------
struct JNIThreadData struct JNIThreadData
{ {
//! Default constructor //! Default constructor
@ -93,6 +94,7 @@ struct JNIThreadData
* @brief Helper class to manage the JNI environment for multithreaded * @brief Helper class to manage the JNI environment for multithreaded
* use of the library. * use of the library.
*/ */
// ---------------------------------------------------------------------------
class JNIEnvironment class JNIEnvironment
{ {
private: private:
@ -151,7 +153,6 @@ public:
public: public:
struct _java struct _java
{ {
inline void Initialize() inline void Initialize()
@ -195,6 +196,20 @@ public:
} java; } java;
struct _Base
{
virtual void Fill(jobject obj,const void* pcSrc) = 0;
jclass Class;
jmethodID DefaultCtor;
};
#define AIJ_SET_INPUT_TYPE(__type__) \
\
void Fill(jobject obj,const __type__* pcSrc); \
\
inline void Fill(jobject obj,const void* pcSrc) \
{Fill(obj,(const __type__*)pcSrc);}
//! Represents the JNI interface to the package assimp //! Represents the JNI interface to the package assimp
struct _assimp struct _assimp
@ -202,7 +217,7 @@ public:
//! Initializes the package assimp for use with jAssimp //! Initializes the package assimp for use with jAssimp
inline void Initialize() inline void Initialize()
{ {
// the NativeError class must be initialized first as it // the NativeException class must be initialized first as it
// is used by all other class initializers // is used by all other class initializers
NativeException.Initialize(); NativeException.Initialize();
@ -245,13 +260,11 @@ public:
//! Represents the JNI interface to class assimp.Scene //! Represents the JNI interface to class assimp.Scene
struct _Scene struct _Scene : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiScene);
jclass Class;
jmethodID DefaultCtor;
jfieldID m_vMeshes; jfieldID m_vMeshes;
jfieldID m_vTextures; jfieldID m_vTextures;
@ -264,14 +277,10 @@ public:
//! Represents the JNI interface to class assimp.Mesh //! Represents the JNI interface to class assimp.Mesh
struct _Mesh struct _Mesh : public _Base
{ {
AIJ_SET_INPUT_TYPE(aiMesh);
void Initialize(); void Initialize();
void Fill(jobject obj,const aiMesh* pcSrc);
jclass Class;
jmethodID DefaultCtor;
jfieldID m_vVertices; jfieldID m_vVertices;
jfieldID m_vTangents; jfieldID m_vTangents;
@ -287,27 +296,33 @@ public:
} Mesh; } Mesh;
//! Represents the JNI interface to class assimp.Bone //! Represents the JNI interface to class assimp.Bone
struct _Bone struct _Bone : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiBone);
jclass Class;
jmethodID DefaultCtor;
jfieldID name; jfieldID name;
jfieldID weights; jfieldID weights;
//! Represents the JNI interface to class assimp.Bone.Weight
struct _Weight : public _Base
{
void Initialize();
AIJ_SET_INPUT_TYPE(aiVertexWeight);
jfieldID index;
jfieldID weight;
} Weight;
} Bone; } Bone;
//! Represents the JNI interface to class assimp.Animation //! Represents the JNI interface to class assimp.Animation
struct _Animation struct _Animation : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiAnimation);
jclass Class;
jmethodID DefaultCtor;
jfieldID name; jfieldID name;
jfieldID mDuration; jfieldID mDuration;
@ -317,10 +332,10 @@ public:
} Animation; } Animation;
//! Represents the JNI interface to class assimp.BoneAnim //! Represents the JNI interface to class assimp.BoneAnim
struct _BoneAnim struct _BoneAnim : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiBoneAnim);
//! Represents the JNI interface to class assimp.BoneAnim.KeyFrame<quak> //! Represents the JNI interface to class assimp.BoneAnim.KeyFrame<quak>
struct _KeyFrame struct _KeyFrame
@ -334,10 +349,6 @@ public:
} KeyFrame; } KeyFrame;
jclass Class;
jmethodID DefaultCtor;
jfieldID mName; jfieldID mName;
jfieldID mQuatKeys; jfieldID mQuatKeys;
jfieldID mPosKeys; jfieldID mPosKeys;
@ -346,13 +357,10 @@ public:
} BoneAnim; } BoneAnim;
//! Represents the JNI interface to class assimp.Texture //! Represents the JNI interface to class assimp.Texture
struct _Texture struct _Texture : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiTexture);
jclass Class;
jmethodID DefaultCtor;
jfieldID width; jfieldID width;
jfieldID height; jfieldID height;
@ -361,67 +369,58 @@ public:
} Texture; } Texture;
//! Represents the JNI interface to class assimp.CompressedTexture //! Represents the JNI interface to class assimp.CompressedTexture
struct _CompressedTexture struct _CompressedTexture : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiTexture);
jclass Class;
jmethodID DefaultCtor;
jfieldID m_format; jfieldID m_format;
} CompressedTexture; } CompressedTexture;
//! Represents the JNI interface to class assimp.Material //! Represents the JNI interface to class assimp.Material
struct _Material struct _Material : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiMaterial);
//! Represents the JNI interface to class assimp.Material.Property //! Represents the JNI interface to class assimp.Material.Property
struct _Property struct _Property : public _Base
{ {
jclass Class; void Initialize();
AIJ_SET_INPUT_TYPE(aiMaterialProperty);
jfieldID key; jfieldID key;
jfieldID value; jfieldID value;
} Property; } Property;
jclass Class;
jmethodID DefaultCtor;
jfieldID properties; jfieldID properties;
} Material; } Material;
//! Represents the JNI interface to class assimp.Matrix4x4 //! Represents the JNI interface to class assimp.Matrix4x4
struct _Matrix4x4 struct _Matrix4x4 : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiMatrix4x4);
jclass Class;
jmethodID DefaultCtor;
jfieldID coeff; jfieldID coeff;
} Matrix4x4; } Matrix4x4;
//! Represents the JNI interface to class assimp.Matrix3x3 //! Represents the JNI interface to class assimp.Matrix3x3
struct _Matrix3x3 struct _Matrix3x3 : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiMatrix3x3);
jclass Class;
jmethodID DefaultCtor;
jfieldID coeff; jfieldID coeff;
} Matrix3x3; } Matrix3x3;
//! Represents the JNI interface to class assimp.Quaternion //! Represents the JNI interface to class assimp.Quaternion
struct _Quaternion struct _Quaternion : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiQuaternion);
jclass Class;
jmethodID DefaultCtor;
jfieldID x; jfieldID x;
jfieldID y; jfieldID y;
@ -431,13 +430,10 @@ public:
} Quaternion; } Quaternion;
//! Represents the JNI interface to class assimp.Node //! Represents the JNI interface to class assimp.Node
struct _Node struct _Node : public _Base
{ {
void Initialize(); void Initialize();
AIJ_SET_INPUT_TYPE(aiNode);
jclass Class;
jmethodID DefaultCtor;
jfieldID meshIndices; jfieldID meshIndices;
jfieldID nodeTransform; jfieldID nodeTransform;
@ -449,6 +445,12 @@ public:
} assimp; } assimp;
inline void Initialize()
{
assimp.Initialize();
java.Initialize();
}
private: private:
//! Singleton instance //! Singleton instance
@ -461,17 +463,15 @@ private:
unsigned int m_iRefCnt; unsigned int m_iRefCnt;
}; };
};};
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Helper function to copy data to a Java array /** @brief Helper function to copy data to a Java array
* *
* @param pc JNI env handle
* @param jfl Java array * @param jfl Java array
* @param data Input data * @param data Input data
* @param size Size of data to be copied, in bytes * @param size Size of data to be copied, in bytes
*/ */
JNU_CopyDataToArray(jarray jfl, void* data, unsigned int size); void JNU_CopyDataToArray(JNIEnv* pc, jarray jfl, void* data, unsigned int size);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Helper function to create a java.lang.String from /** @brief Helper function to create a java.lang.String from
@ -494,6 +494,23 @@ jstring JNU_NewStringNative(JNIEnv *env, const char *str);
*/ */
char* JNU_GetStringNativeChars(JNIEnv *env, jstring jstr); char* JNU_GetStringNativeChars(JNIEnv *env, jstring jstr);
// ---------------------------------------------------------------------------
/** @brief Helper function to copy a whole object array to the VM
*
* @param pc JNI env handle
* @param in Input object array
* @param num Size of input array
* @param type Type of input
* @param out Output object
*/
// ---------------------------------------------------------------------------
void JNU_CopyObjectArrayToVM(JNIEnv* pc, const void** in, unsigned int num,
JNIEnvironment::_Base& type, jobjectArray& out);
};};
#endif //! AI_JNIENVIRONMENT_H_INCLUDED #endif //! AI_JNIENVIRONMENT_H_INCLUDED

View File

@ -42,8 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_JNILOGGER_H_INCLUDED #define AI_JNILOGGER_H_INCLUDED
#include "../../include/Logger.h" #include "../../../include/Logger.h"
#include "../../include/DefaultLogger.h" #include "../../../include/DefaultLogger.h"
#include <vector> #include <vector>
#include <jni.h> #include <jni.h>

View File

@ -52,12 +52,14 @@ namespace JNIBridge {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_Mesh::Initialize() void JNIEnvironment::_assimp::_Mesh::Initialize()
{ {
JNIEnv* pc = JJNIEnvironment::Get()->GetThread()->m_pcEnv; JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// load a handle to the class // load a handle to the class
if(!(this->Class = pc->FindClass("assimp.Mesh"))) if(!(this->Class = pc->FindClass("assimp.Mesh")))
JNIEnvironment::Get()->ThrowNativeError("Unable to load class assimp.mesh"); JNIEnvironment::Get()->ThrowNativeError("Unable to load class assimp.mesh");
DefaultCtor = pc->GetMethodID(Class,"<init>","");
// load all fields of the class // load all fields of the class
this->m_vVertices = pc->GetFieldID(Class,"m_vVertices","[F"); this->m_vVertices = pc->GetFieldID(Class,"m_vVertices","[F");
this->m_vNormals = pc->GetFieldID(Class,"m_vNormals","[F"); this->m_vNormals = pc->GetFieldID(Class,"m_vNormals","[F");
@ -83,25 +85,22 @@ void JNIEnvironment::_assimp::_Mesh::Initialize()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc) void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
{ {
JNIEnv* pc = JJNIEnvironment::Get()->GetThread()->m_pcEnv; JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// set the material index // set the material index
pc->SetIntField(obj,this->m_iMaterialIndex,pcSrc->mMaterialIndex); pc->SetIntField(obj,this->m_iMaterialIndex,pcSrc->mMaterialIndex);
// allocate the arrays and fill them // allocate the arrays and fill them
float* pf;
const unsigned int size = pcSrc->mNumVertices*12; const unsigned int size = pcSrc->mNumVertices*12;
const unsigned int size2 = pcSrc->mNumVertices*3; const unsigned int size2 = pcSrc->mNumVertices*3;
// copy vertex positions // copy vertex positions
if (pcSrc->HasPositions()) if (pcSrc->HasPositions())
{ {
// allocate and copy data
jfloatArray jfl = pc->NewFloatArray(size2); jfloatArray jfl = pc->NewFloatArray(size2);
JNU_CopyDataToArray(jfl,pcSrc->mVertices,size); JNU_CopyDataToArray(pc,jfl,pcSrc->mVertices,size);
// set the corresponding field in the java object
pc->SetObjectField(obj,this->m_vVertices,jfl); pc->SetObjectField(obj,this->m_vVertices,jfl);
} }
// copy vertex normals // copy vertex normals
@ -109,25 +108,20 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
{ {
// allocate and copy data // allocate and copy data
jfloatArray jfl = pc->NewFloatArray(size2); jfloatArray jfl = pc->NewFloatArray(size2);
JNU_CopyDataToArray(jfl,pcSrc->mNormals,size); JNU_CopyDataToArray(pc,jfl,pcSrc->mNormals,size);
// set the corresponding field in the java object
pc->SetObjectField(obj,this->m_vNormals,jfl); pc->SetObjectField(obj,this->m_vNormals,jfl);
} }
// copy tangents and bitangents // copy tangents and bitangents
if (pcSrc->HasTangentsAndBitangents()) if (pcSrc->HasTangentsAndBitangents())
{ {
// allocate and copy data
jfloatArray jfl = pc->NewFloatArray(size2); jfloatArray jfl = pc->NewFloatArray(size2);
JNU_CopyDataToArray(jfl,pcSrc->mTangents,size); JNU_CopyDataToArray(pc,jfl,pcSrc->mTangents,size);
// set the corresponding field in the java object
pc->SetObjectField(obj,this->m_vTangents,jfl); pc->SetObjectField(obj,this->m_vTangents,jfl);
jfl = pc->NewFloatArray(size2); jfl = pc->NewFloatArray(size2);
JNU_CopyDataToArray(jfl,pcSrc->mBitangents,size); JNU_CopyDataToArray(pc,jfl,pcSrc->mBitangents,size);
// set the corresponding field in the java object
pc->SetObjectField(obj,this->m_vBitangents,jfl); pc->SetObjectField(obj,this->m_vBitangents,jfl);
} }
// copy texture coordinates // copy texture coordinates
@ -140,9 +134,9 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
while (pcSrc->HasTextureCoords(channel)) while (pcSrc->HasTextureCoords(channel))
{ {
jfloatArray jfl = pc->NewFloatArray(size2); jfloatArray jfl = pc->NewFloatArray(size2);
JNU_CopyDataToArray(jfl,pcSrc->mTextureCoords[channel],size); JNU_CopyDataToArray(pc,jfl,pcSrc->mTextureCoords[channel],size);
pc->SetObjectArrayElement(jobjarr,channel,jfl) pc->SetObjectArrayElement(jobjarr,channel,jfl);
++channel; ++channel;
} }
@ -150,7 +144,7 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
pc->SetObjectField(obj,this->m_avUVs,jobjarr); pc->SetObjectField(obj,this->m_avUVs,jobjarr);
jobjarr = (jobjectArray) pc->NewIntArray(AI_MAX_NUMBER_OF_TEXTURECOORDS); jobjarr = (jobjectArray) pc->NewIntArray(AI_MAX_NUMBER_OF_TEXTURECOORDS);
pc->SetIntArrayRegion((jintArray)jobjarr,0,channel,&pcSrc->mNumUVComponents); pc->SetIntArrayRegion((jintArray)jobjarr,0,channel,(const jint*)&pcSrc->mNumUVComponents);
pc->SetObjectField(obj,this->m_aiNumUVComponents,jobjarr); pc->SetObjectField(obj,this->m_aiNumUVComponents,jobjarr);
} }
// copy vertex colors // copy vertex colors
@ -166,7 +160,7 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
while (pcSrc->HasVertexColors(channel)) while (pcSrc->HasVertexColors(channel))
{ {
jfloatArray jfl = pc->NewFloatArray(size2); jfloatArray jfl = pc->NewFloatArray(size2);
JNU_CopyDataToArray(jfl,pcSrc->mColors[channel],size); JNU_CopyDataToArray(pc,jfl,pcSrc->mColors[channel],size);
pc->SetObjectArrayElement(jobjarr,channel,jfl); pc->SetObjectArrayElement(jobjarr,channel,jfl);
++channel; ++channel;
@ -186,15 +180,13 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
// allocate and copy data // allocate and copy data
jintArray jil = pc->NewIntArray(size2); jintArray jil = pc->NewIntArray(size2);
int* pf; uint32_t* pf;
jboolean iscopy = FALSE; jboolean iscopy = FALSE;
// lock the array and get direct access to its buffer if(!(pf = (uint32_t*)pc->GetPrimitiveArrayCritical(jil,&iscopy)))
if(!pf = pc->GetPrimitiveArrayCritical(jil,&iscopy))
JNIEnvironment::Get()->ThrowNativeError("Unable to lock face array"); JNIEnvironment::Get()->ThrowNativeError("Unable to lock face array");
// copy the data to the array - face by face const aiFace* const pcEnd = pcSrc->mFaces+pcSrc->mNumFaces;
const aiFace** const pcEnd = pcSrc->mFaces+pcSrc->mNumFaces;
for (const aiFace* pcCur = pcSrc->mFaces;pcCur != pcEnd;++pcCur) for (const aiFace* pcCur = pcSrc->mFaces;pcCur != pcEnd;++pcCur)
{ {
ai_assert(3 == pcCur->mNumIndices); ai_assert(3 == pcCur->mNumIndices);
@ -203,36 +195,17 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
*pf++ = pcCur->mIndices[2]; *pf++ = pcCur->mIndices[2];
} }
// release our reference to the array
pc->ReleasePrimitiveArrayCritical(jil,pf,0); pc->ReleasePrimitiveArrayCritical(jil,pf,0);
// set the corresponding field in the java object
pc->SetObjectField(obj,this->m_vFaces,jil); pc->SetObjectField(obj,this->m_vFaces,jil);
} }
// copy bones // copy bones
if (pcSrc->mNumBones) if (pcSrc->mNumBones)
{ {
// allocate the array jobjectArray ja;
jobjectArray jarr = pc->NewObjectArray(pcSrc->mNumBones, JNU_CopyObjectArrayToVM(pc,(const void**)pcSrc->mBones,pcSrc->mNumBones,
AIJ_GET_HANDLE(assimp.Bone.Class),0); AIJ_GET_HANDLE(assimp.Bone),ja);
pc->SetObjectField(obj,m_vBones,ja);
// and fill all members
for (unsigned int i = 0; i < pcSrc->mNumBones;++i)
{
// allocate the array element
jobject jobj = pc->NewObject(AIJ_GET_CLASS_HANDLE(assimp.Bone),
AIJ_GET_DEFAULT_CTOR_HANDLE(assimp.Bone));
// fill it from the native data
JNIEnvironment::Get()->assimp.Bone.Fill(jobj,pcSrc->mBones[i]);
// and set the corresponding array entry
pc->SetObjectArrayElement(jarr,i,jobj);
}
// set the corresponding field in the java object
pc->SetObjectField(obj,this->m_vBones,jil);
} }
} }

View File

@ -6,36 +6,8 @@ Open Asset Import Library (ASSIMP)
Copyright (c) 2006-2008, ASSIMP Development Team Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved. All rights reserved.
See the disclaimer in JNIEnvironment.h for licensing and distribution
Redistribution and use of this software in source and binary forms, conditions.
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.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
@ -50,10 +22,10 @@ namespace Assimp {
namespace JNIBridge { namespace JNIBridge {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
JNIEnvironment::_assimp::_NativeException::Initialize() void JNIEnvironment::_assimp::_NativeException::Initialize()
{ {
// get a handle to the JNI context for this thread // get a handle to the JNI context for this thread
JNIEnv* pc = JJNIEnvironment::Get()->GetThread()->m_pcEnv; JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// load a handle to the class // load a handle to the class
if(!(this->Class = pc->FindClass("assimp.NativeException"))) if(!(this->Class = pc->FindClass("assimp.NativeException")))
@ -78,3 +50,4 @@ void JNIEnvironment::ThrowNativeError(const char* msg /*= NULL*/)
msg ? msg msg ? msg
: "An unspecified error occured in the native interface to Assimp."); : "An unspecified error occured in the native interface to Assimp.");
} }
}}

View File

@ -0,0 +1,96 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
See the disclaimer in JNIEnvironment.h for licensing and distribution
conditions.
---------------------------------------------------------------------------
*/
/** @file Implementation of the JNI API for jAssimp */
#include "JNIEnvironment.h"
#include "JNILogger.h"
using namespace Assimp;
namespace Assimp {
namespace JNIBridge {
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_Scene::Initialize()
{
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// load a handle to the class
if(!(Class = pc->FindClass("assimp.Scene")))
JNIEnvironment::Get()->ThrowNativeError("Unable to load class assimp.Scene");
DefaultCtor = pc->GetMethodID(Class,"<init>","");
// load all fields of the class
m_rootNode = pc->GetFieldID(Class,"m_rootNode","Lassimp.Node;");
m_vAnimations = pc->GetFieldID(Class,"m_vAnimations","[Lassimp.Animation;");
m_vMaterials = pc->GetFieldID(Class,"m_vMaterials","[Lassimp.Material;");
m_vMeshes = pc->GetFieldID(Class,"m_vMeshes","[Lassimp.Mesh;");
m_vTextures = pc->GetFieldID(Class,"m_vTextures","[Lassimp.Texture;");
flags = pc->GetFieldID(Class,"flags","I");
// check whether all fields have been loaded properly
if (!m_vAnimations || !m_rootNode || !m_vMaterials || !m_vMeshes || !m_vTextures || !flags)
JNIEnvironment::Get()->ThrowNativeError("Unable to load all fields of class assimp.Scene");
}
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_assimp::_Scene::Fill(jobject obj,const aiScene* pcSrc)
{
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
jobjectArray ja;
// copy meshes
if (pcSrc->mNumMeshes)
{
JNU_CopyObjectArrayToVM(pc,(const void**)pcSrc->mMeshes,pcSrc->mNumMeshes,
AIJ_GET_HANDLE(assimp.Mesh),ja);
pc->SetObjectField(obj,m_vMeshes,ja);
}
// copy textures
if (pcSrc->mNumTextures)
{
JNU_CopyObjectArrayToVM(pc,(const void**)pcSrc->mTextures,pcSrc->mNumTextures,
AIJ_GET_HANDLE(assimp.Texture),ja);
pc->SetObjectField(obj,m_vTextures,ja);
}
// copy materials
if (pcSrc->mNumMeshes)
{
JNU_CopyObjectArrayToVM(pc,(const void**)pcSrc->mMaterials,pcSrc->mNumMaterials,
AIJ_GET_HANDLE(assimp.Material),ja);
pc->SetObjectField(obj,m_vMaterials,ja);
}
// copy animations
if (pcSrc->mNumAnimations)
{
JNU_CopyObjectArrayToVM(pc,(const void**)pcSrc->mAnimations,pcSrc->mNumAnimations,
AIJ_GET_HANDLE(assimp.Animation),ja);
pc->SetObjectField(obj,m_vAnimations,ja);
}
// copy flags
pc->SetIntField(obj,flags,(jint)pcSrc->mFlags);
// copy the root node
jobject root = pc->NewObject(AIJ_GET_CLASS_HANDLE(assimp.Node),
AIJ_GET_DEFAULT_CTOR_HANDLE(assimp.Node));
AIJ_GET_HANDLE(assimp.Node).Fill(root,pcSrc->mRootNode);
pc->SetObjectField(obj,m_rootNode,root);
}
}}

View File

@ -41,6 +41,22 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyInt JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyInt
(JNIEnv *, jobject, jstring, jint, jlong); (JNIEnv *, jobject, jstring, jint, jlong);
/*
* Class: assimp_Importer
* Method: _NativeSetPropertyFloat
* Signature: (Ljava/lang/String;FJ)I
*/
JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyFloat
(JNIEnv *, jobject, jstring, jfloat, jlong);
/*
* Class: assimp_Importer
* Method: _NativeSetPropertyString
* Signature: (Ljava/lang/String;Ljava/lang/String;J)I
*/
JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeSetPropertyString
(JNIEnv *, jobject, jstring, jstring, jlong);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -61,7 +61,7 @@ public class Scene {
private Animation[] m_vAnimations = null; private Animation[] m_vAnimations = null;
private Node m_rootNode = null; private Node m_rootNode = null;
private Importer imp = null; private Importer imp = null;
private int flags; private int flags = 0;
private Scene() { private Scene() {
} }

View File

@ -159,7 +159,7 @@ public class DumpToFile {
* mesh to be opened, the second is te name of the primary output file. * mesh to be opened, the second is te name of the primary output file.
* @throws IOException * @throws IOException
*/ */
public static void Main(String[] arguments) throws IOException { public static void main(String[] arguments) throws IOException {
/* Use output.txt as default output file if none was specified /* Use output.txt as default output file if none was specified
* However, at least one parameter is expected * However, at least one parameter is expected

View File

@ -2,13 +2,13 @@
Microsoft Visual Studio Solution File, Format Version 9.00 Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005 # Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssimpView", "assimp_view.vcproj", "{B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssimpView", "assimp_view.vcproj", "{B17B959B-BB8A-4596-AF0F-A8C8DBBC3C5E}"
ProjectSection(ProjectDependencies) = postProject
{5691E159-2D9B-407F-971F-EA5C592DC524} = {5691E159-2D9B-407F-971F-EA5C592DC524}
EndProjectSection
ProjectSection(WebsiteProperties) = preProject ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True" Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False" Release.AspNetCompiler.Debug = "False"
EndProjectSection EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{5691E159-2D9B-407F-971F-EA5C592DC524} = {5691E159-2D9B-407F-971F-EA5C592DC524}
EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Assimp", "assimp.vcproj", "{5691E159-2D9B-407F-971F-EA5C592DC524}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Assimp", "assimp.vcproj", "{5691E159-2D9B-407F-971F-EA5C592DC524}"
ProjectSection(WebsiteProperties) = preProject ProjectSection(WebsiteProperties) = preProject
@ -17,15 +17,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Assimp", "assimp.vcproj", "
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest.vcproj", "{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest.vcproj", "{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}"
ProjectSection(ProjectDependencies) = postProject
{5691E159-2D9B-407F-971F-EA5C592DC524} = {5691E159-2D9B-407F-971F-EA5C592DC524}
EndProjectSection
ProjectSection(WebsiteProperties) = preProject ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True" Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False" Release.AspNetCompiler.Debug = "False"
EndProjectSection EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{5691E159-2D9B-407F-971F-EA5C592DC524} = {5691E159-2D9B-407F-971F-EA5C592DC524}
EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jAssimp_NOT_FINISHED", "jAssimp.vcproj", "{FE78BFBA-4BA5-457D-8602-B800D498102D}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jAssimp", "jAssimp.vcproj", "{FE78BFBA-4BA5-457D-8602-B800D498102D}"
ProjectSection(WebsiteProperties) = preProject ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True" Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False" Release.AspNetCompiler.Debug = "False"
@ -92,13 +92,15 @@ Global
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|x64.ActiveCfg = Release|x64 {9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|x64.ActiveCfg = Release|x64
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|x64.Build.0 = Release|x64 {9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|x64.Build.0 = Release|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|Win32.ActiveCfg = Debug|Win32 {FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|Win32.ActiveCfg = Debug|Win32
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|x64.ActiveCfg = Debug|Win32 {FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|x64.ActiveCfg = Debug|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|Win32.ActiveCfg = Debug|Win32 {FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|Win32.ActiveCfg = Debug|Win32
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|x64.ActiveCfg = Debug|Win32 {FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|x64.ActiveCfg = Debug|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|x64.Build.0 = Debug|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|Win32.ActiveCfg = Release|Win32 {FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|Win32.ActiveCfg = Release|Win32
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|x64.ActiveCfg = Release|Win32 {FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|x64.ActiveCfg = Release|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|Win32.ActiveCfg = Release|Win32 {FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|Win32.ActiveCfg = Release|Win32
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|x64.ActiveCfg = Release|Win32 {FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|x64.ActiveCfg = Release|x64
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -713,14 +713,6 @@
RelativePath="..\..\code\ByteSwap.h" RelativePath="..\..\code\ByteSwap.h"
> >
</File> </File>
<File
RelativePath="..\..\code\CalcTangentsProcess.h"
>
</File>
<File
RelativePath="..\..\code\ConvertToLHProcess.h"
>
</File>
<File <File
RelativePath="..\..\code\DefaultIOStream.h" RelativePath="..\..\code\DefaultIOStream.h"
> >
@ -733,22 +725,10 @@
RelativePath="..\..\code\fast_atof.h" RelativePath="..\..\code\fast_atof.h"
> >
</File> </File>
<File
RelativePath="..\..\code\FixNormalsStep.h"
>
</File>
<File <File
RelativePath="..\..\code\GenericProperty.h" RelativePath="..\..\code\GenericProperty.h"
> >
</File> </File>
<File
RelativePath="..\..\code\GenFaceNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\GenVertexNormalsProcess.h"
>
</File>
<File <File
RelativePath="..\..\code\Hash.h" RelativePath="..\..\code\Hash.h"
> >
@ -757,38 +737,14 @@
RelativePath="..\..\code\IFF.h" RelativePath="..\..\code\IFF.h"
> >
</File> </File>
<File
RelativePath="..\..\code\ImproveCacheLocality.h"
>
</File>
<File
RelativePath="..\..\code\JoinVerticesProcess.h"
>
</File>
<File
RelativePath="..\..\code\KillNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\LimitBoneWeightsProcess.h"
>
</File>
<File <File
RelativePath="..\..\code\MaterialSystem.h" RelativePath="..\..\code\MaterialSystem.h"
> >
</File> </File>
<File
RelativePath="..\..\code\OptimizeGraphProcess.h"
>
</File>
<File <File
RelativePath="..\..\code\ParsingUtils.h" RelativePath="..\..\code\ParsingUtils.h"
> >
</File> </File>
<File
RelativePath="..\..\code\PretransformVertices.h"
>
</File>
<File <File
RelativePath="..\..\code\qnan.h" RelativePath="..\..\code\qnan.h"
> >
@ -797,10 +753,6 @@
RelativePath="..\..\code\RemoveComments.h" RelativePath="..\..\code\RemoveComments.h"
> >
</File> </File>
<File
RelativePath="..\..\code\RemoveRedundantMaterials.h"
>
</File>
<File <File
RelativePath="..\..\code\SGSpatialSort.h" RelativePath="..\..\code\SGSpatialSort.h"
> >
@ -817,10 +769,6 @@
RelativePath="..\..\code\SpatialSort.h" RelativePath="..\..\code\SpatialSort.h"
> >
</File> </File>
<File
RelativePath="..\..\code\SplitLargeMeshes.h"
>
</File>
<File <File
RelativePath="..\..\code\StandardShapes.h" RelativePath="..\..\code\StandardShapes.h"
> >
@ -833,14 +781,6 @@
RelativePath="..\..\code\TextureTransform.h" RelativePath="..\..\code\TextureTransform.h"
> >
</File> </File>
<File
RelativePath="..\..\code\TriangulateProcess.h"
>
</File>
<File
RelativePath="..\..\code\ValidateDataStructure.h"
>
</File>
<File <File
RelativePath="..\..\code\VertexTriangleAdjacency.h" RelativePath="..\..\code\VertexTriangleAdjacency.h"
> >
@ -1137,6 +1077,78 @@
> >
</Filter> </Filter>
</Filter> </Filter>
<Filter
Name="PostProcess"
>
<File
RelativePath="..\..\code\CalcTangentsProcess.h"
>
</File>
<File
RelativePath="..\..\code\ConvertToLHProcess.h"
>
</File>
<File
RelativePath="..\..\code\FixNormalsStep.h"
>
</File>
<File
RelativePath="..\..\code\GenFaceNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\GenVertexNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\ImproveCacheLocality.h"
>
</File>
<File
RelativePath="..\..\code\JoinVerticesProcess.h"
>
</File>
<File
RelativePath="..\..\code\KillNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\LimitBoneWeightsProcess.h"
>
</File>
<File
RelativePath="..\..\code\OptimizeGraphProcess.h"
>
</File>
<File
RelativePath="..\..\code\PretransformVertices.h"
>
</File>
<File
RelativePath="..\..\code\RemoveRedundantMaterials.h"
>
</File>
<File
RelativePath="..\..\code\SplitLargeMeshes.h"
>
</File>
<File
RelativePath="..\..\code\TriangulateProcess.h"
>
</File>
<File
RelativePath="..\..\code\ValidateDataStructure.h"
>
</File>
<Filter
Name="util"
>
<File
RelativePath="..\..\code\ProcessHelper.h"
>
</File>
</Filter>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="sources" Name="sources"
@ -1157,14 +1169,6 @@
RelativePath="..\..\code\BaseProcess.cpp" RelativePath="..\..\code\BaseProcess.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\CalcTangentsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\ConvertToLHProcess.cpp"
>
</File>
<File <File
RelativePath="..\..\code\DefaultIOStream.cpp" RelativePath="..\..\code\DefaultIOStream.cpp"
> >
@ -1177,58 +1181,18 @@
RelativePath="..\..\code\DefaultLogger.cpp" RelativePath="..\..\code\DefaultLogger.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\FixNormalsStep.cpp"
>
</File>
<File
RelativePath="..\..\code\GenFaceNormalsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\GenVertexNormalsProcess.cpp"
>
</File>
<File <File
RelativePath="..\..\code\Importer.cpp" RelativePath="..\..\code\Importer.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\ImproveCacheLocality.cpp"
>
</File>
<File
RelativePath="..\..\code\JoinVerticesProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\KillNormalsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\LimitBoneWeightsProcess.cpp"
>
</File>
<File <File
RelativePath="..\..\code\MaterialSystem.cpp" RelativePath="..\..\code\MaterialSystem.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\OptimizeGraphProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\PretransformVertices.cpp"
>
</File>
<File <File
RelativePath="..\..\code\RemoveComments.cpp" RelativePath="..\..\code\RemoveComments.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\RemoveRedundantMaterials.cpp"
>
</File>
<File <File
RelativePath="..\..\code\SGSpatialSort.cpp" RelativePath="..\..\code\SGSpatialSort.cpp"
> >
@ -1237,10 +1201,6 @@
RelativePath="..\..\code\SpatialSort.cpp" RelativePath="..\..\code\SpatialSort.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\SplitLargeMeshes.cpp"
>
</File>
<File <File
RelativePath="..\..\code\StandardShapes.cpp" RelativePath="..\..\code\StandardShapes.cpp"
> >
@ -1249,14 +1209,6 @@
RelativePath="..\..\code\TextureTransform.cpp" RelativePath="..\..\code\TextureTransform.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\TriangulateProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\ValidateDataStructure.cpp"
>
</File>
<File <File
RelativePath="..\..\code\VertexTriangleAdjacency.cpp" RelativePath="..\..\code\VertexTriangleAdjacency.cpp"
> >
@ -1477,6 +1429,70 @@
> >
</Filter> </Filter>
</Filter> </Filter>
<Filter
Name="PostProcess"
>
<File
RelativePath="..\..\code\CalcTangentsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\ConvertToLHProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\FixNormalsStep.cpp"
>
</File>
<File
RelativePath="..\..\code\GenFaceNormalsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\GenVertexNormalsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\ImproveCacheLocality.cpp"
>
</File>
<File
RelativePath="..\..\code\JoinVerticesProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\KillNormalsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\LimitBoneWeightsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\OptimizeGraphProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\PretransformVertices.cpp"
>
</File>
<File
RelativePath="..\..\code\RemoveRedundantMaterials.cpp"
>
</File>
<File
RelativePath="..\..\code\SplitLargeMeshes.cpp"
>
</File>
<File
RelativePath="..\..\code\TriangulateProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\ValidateDataStructure.cpp"
>
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="doc" Name="doc"

View File

@ -2,7 +2,7 @@
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="8,00" Version="8,00"
Name="jAssimp_NOT_FINISHED" Name="jAssimp_NOT_WORKING"
ProjectGUID="{FE78BFBA-4BA5-457D-8602-B800D498102D}" ProjectGUID="{FE78BFBA-4BA5-457D-8602-B800D498102D}"
RootNamespace="jAssimp" RootNamespace="jAssimp"
Keyword="Win32Proj" Keyword="Win32Proj"
@ -11,16 +11,19 @@
<Platform <Platform
Name="Win32" Name="Win32"
/> />
<Platform
Name="x64"
/>
</Platforms> </Platforms>
<ToolFiles> <ToolFiles>
</ToolFiles> </ToolFiles>
<Configurations> <Configurations>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)" OutputDirectory="./../../bin/$(ProjectName)_$(ConfigurationName)_$(PlatformName)"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="./../../obj/$(ProjectName)_$(ConfigurationName)_$(PlatformName)"
ConfigurationType="2" ConfigurationType="2"
CharacterSet="1" CharacterSet="2"
> >
<Tool <Tool
Name="VCPreBuildEventTool" Name="VCPreBuildEventTool"
@ -40,7 +43,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="&quot;$(JAVA_HOME)\include&quot;" AdditionalIncludeDirectories="&quot;$(JAVA_HOME)\include&quot;;&quot;$(JAVA_HOME)\include\win32&quot;;&quot;$(SolutionDir)..\..\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;JASSIMP_EXPORTS" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;JASSIMP_EXPORTS"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
@ -61,7 +64,10 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="assimp.lib"
OutputFile="$(OutDir)\jAssimp32d.dll"
LinkIncremental="2" LinkIncremental="2"
AdditionalLibraryDirectories="$(SolutionDir)..\..\lib\assimp_$(ConfigurationName)_DLL_$(PlatformName)\"
GenerateDebugInformation="true" GenerateDebugInformation="true"
SubSystem="2" SubSystem="2"
TargetMachine="1" TargetMachine="1"
@ -92,11 +98,91 @@
/> />
</Configuration> </Configuration>
<Configuration <Configuration
Name="Release|Win32" Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(ConfigurationName)" OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2" ConfigurationType="2"
CharacterSet="1" CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(JAVA_HOME)\include&quot;;&quot;$(JAVA_HOME)\include\win32&quot;;&quot;$(SolutionDir)..\..\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;JASSIMP_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="assimp.lib"
OutputFile="$(OutDir)\jAssimp64d.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="$(SolutionDir)..\..\lib\assimp_$(ConfigurationName)_DLL_$(PlatformName)\"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="./../../bin/$(ProjectName)_$(ConfigurationName)_$(PlatformName)"
IntermediateDirectory="./../../obj/$(ProjectName)_$(ConfigurationName)_$(PlatformName)"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1" WholeProgramOptimization="1"
> >
<Tool <Tool
@ -116,7 +202,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\include" AdditionalIncludeDirectories="&quot;$(JAVA_HOME)\include&quot;;&quot;$(JAVA_HOME)\include\win32&quot;;&quot;$(SolutionDir)..\..\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;JASSIMP_EXPORTS" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;JASSIMP_EXPORTS"
RuntimeLibrary="2" RuntimeLibrary="2"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
@ -135,7 +221,10 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="assimp.lib"
OutputFile="$(OutDir)\jAssimp32.dll"
LinkIncremental="1" LinkIncremental="1"
AdditionalLibraryDirectories="$(SolutionDir)..\..\lib\assimp_$(ConfigurationName)_DLL_$(PlatformName)\"
GenerateDebugInformation="true" GenerateDebugInformation="true"
SubSystem="2" SubSystem="2"
OptimizeReferences="2" OptimizeReferences="2"
@ -167,6 +256,86 @@
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
/> />
</Configuration> </Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(JAVA_HOME)\include&quot;;&quot;$(JAVA_HOME)\include\win32&quot;;&quot;$(SolutionDir)..\..\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;JASSIMP_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="assimp.lib"
OutputFile="$(OutDir)\jAssimp64.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="$(SolutionDir)..\..\lib\assimp_$(ConfigurationName)_DLL_$(PlatformName)\"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations> </Configurations>
<References> <References>
</References> </References>
@ -253,18 +422,6 @@
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Importer.h" RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Importer.h"
> >
</File> </File>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Importer_DefaultIOStream.h"
>
</File>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Importer_DefaultIOSystem.h"
>
</File>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Importer_Property.h"
>
</File>
</Filter> </Filter>
</Filter> </Filter>
<Filter <Filter