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
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);
break;
@ -747,8 +749,8 @@ void Dot3DSImporter::ParseMeshChunk(int& piRemaining)
{
mMesh.mPositions.push_back(*((aiVector3D*)this->mCurrent));
aiVector3D& v = mMesh.mPositions.back();
std::swap( (float&)v.y, (float&)v.z);
//v.y *= -1.0f;
//std::swap( (float&)v.y, (float&)v.z);
v.y *= -1.0f;
this->mCurrent += sizeof(aiVector3D);
}
break;
@ -1019,8 +1021,6 @@ void Dot3DSImporter::ParseTextureChunk(int& piRemaining,Dot3DS::Texture* pcOut)
"x direction is zero. Assuming this should be 1.0 ... ");
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;
case Dot3DSFile::CHUNK_MAT_MAP_VSCALE:
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 ... ");
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;
case Dot3DSFile::CHUNK_MAT_MAP_UOFFSET:
pcOut->mOffsetU = *((float*)this->mCurrent);
@ -1103,14 +1101,15 @@ void Dot3DSImporter::ParseColorChunk(aiColor3D* p_pcOut,
return;
}
const unsigned int diff = psChunk->Size - sizeof(Dot3DSFile::Chunk);
const unsigned char* pcCur = this->mCurrent;
this->mCurrent += diff;
bool bGamma = false;
switch(psChunk->Flag)
{
case Dot3DSFile::CHUNK_LINRGBF:
bGamma = true;
case Dot3DSFile::CHUNK_RGBF:
if (sizeof(float) * 3 > diff)
{

View File

@ -471,7 +471,7 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
// allocate output storage
std::vector<aiVector3D> mPositions;
std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
std::vector<aiColor4D> mVertexColors;
std::vector<aiColor4D> mVertexColors;
std::vector<aiVector3D> mNormals;
std::vector<BoneVertex> mBoneVertices;
@ -512,7 +512,8 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
for (unsigned int n = 0; n < 3;++n,++iCurrent)
{
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
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())
{
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
@ -1014,27 +1018,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
}
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()
{
@ -1149,23 +1133,21 @@ void ASEImporter::GenerateNormals(ASE::Mesh& mesh)
{
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
for (std::vector<aiVector3D>::const_iterator
qq = mesh.mNormals.begin();
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, "
"but not all vertices seem to have normals assigned. The "
"whole normal set will be recomputed.");
mesh.mNormals.clear();
break;
return;
}
}
mesh.mNormals.clear();
}
if (mesh.mNormals.empty())
{
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
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 "GenericProperty.h"
#include <map>
struct aiScene;
namespace Assimp
{
namespace Assimp {
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.
* 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.
*/
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 <assert.h>
// internal headers
#include "CalcTangentsProcess.h"
#include "SpatialSort.h"
// public ASSIMP headers
#include "../include/DefaultLogger.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/assimp.hpp"
// internal headers
#include "CalcTangentsProcess.h"
#include "ProcessHelper.h"
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
@ -99,7 +99,7 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
bool bHas = false;
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");
else DefaultLogger::get()->debug("CalcTangentsProcess finished");
@ -107,7 +107,7 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------
// 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
// 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 ");
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;
// 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
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;
const float fLimit = cosf(this->configMaxAngle);
@ -223,7 +229,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
closeVertices.push_back( a);
// 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
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
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] ];
smoothBitangent += meshBitang[ closeVertices[b] ];
@ -254,7 +260,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
smoothBitangent.Normalize();
// 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;
meshBitang[ closeVertices[b] ] = smoothBitangent;

View File

@ -97,8 +97,9 @@ protected:
// -------------------------------------------------------------------
/** Calculates tangents and bitangents for a specific mesh.
* @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.

View File

@ -122,7 +122,8 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
// ------------------------------------------------------------------------------------------------
bool DXFImporter::GetNextLine()
{
if(!SkipLine(&buffer))return false;
if(!SkipLine(&buffer))
return false;
if(!SkipSpaces(&buffer))return GetNextLine();
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
else
{
bool b = false;
while (GetNextToken())
{
if (!groupCode && !::strcmp(cursor,"ENDSEC"))
{b = true;break;}
if (!groupCode && !::strcmp(cursor,"ENDSEC"))break;
}
if (!b)break;
}
}
// 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();
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()];
for (unsigned int i = 0; i < vPositions.size();++i)
clrOut[i] = aiColor4D(0.6f,0.6f,0.6f,1.0f);
clr = &vColors[0];
break;
}
@ -262,7 +263,13 @@ void DXFImporter::InternReadFile( const std::string& pFile,
for (unsigned int a = 0; a < face.mNumIndices;++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++;
}
vp += 4;
@ -325,7 +332,7 @@ bool DXFImporter::ParseEntities()
if (!::strcmp(cursor,"3DFACE"))
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 (!::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
* normals for all imported faces.
*/
#include "GenVertexNormalsProcess.h"
#include "SpatialSort.h"
// public ASSIMP headers
#include "../include/DefaultLogger.h"
#include "../include/aiPostProcess.h"
#include "../include/aiMesh.h"
#include "../include/aiScene.h"
#include "../include/assimp.hpp"
// internal headers
#include "GenVertexNormalsProcess.h"
#include "ProcessHelper.h"
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
@ -90,7 +93,7 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene)
bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
{
if(this->GenMeshVertexNormals( pScene->mMeshes[a]))
if(this->GenMeshVertexNormals( pScene->mMeshes[a],a))
bHas = true;
}
@ -105,7 +108,7 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------
// 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;
@ -123,49 +126,87 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh)
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
SpatialSort vertexFinder( pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
std::vector<unsigned int> verticesFound;
const float fLimit = cos(this->configMaxAngle);
aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices];
for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
// check whether we can reuse the SpatialSort of a previous step.
SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder;
float posEpsilon;
const float epsilon = 1e-5f;
if (shared)
{
const aiVector3D& posThis = pMesh->mVertices[i];
// get all vertices that share this one ...
vertexFinder.FindPositions( posThis, posEpsilon, verticesFound);
aiVector3D pcNor;
for (unsigned int a = 0; a < verticesFound.size(); ++a)
std::vector<std::pair<SpatialSort,float> >* avf;
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
if (avf)
{
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];
std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
vertexFinder = &blubb.first;
posEpsilon = blubb.second;
}
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;
pMesh->mNormals = pcNew;

View File

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

View File

@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------
template <class T>
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);
@ -85,4 +85,39 @@ inline T GetGenericProperty(const std::map< uint32_t, T >& list,
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

View File

@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "DefaultIOStream.h"
#include "DefaultIOSystem.h"
#include "GenericProperty.h"
#include "ProcessHelper.h"
// Importers
#if (!defined AI_BUILD_NO_X_IMPORTER)
@ -167,6 +168,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
@ -179,11 +181,12 @@ Importer::Importer() :
// allocate a default IO handler
mIOHandler = new DefaultIOSystem;
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
// the order doesn't really care, however file formats that are
// used more frequently than others should be at the beginning.
mImporter.reserve(25);
#if (!defined AI_BUILD_NO_X_IMPORTER)
mImporter.push_back( new XFileImporter());
@ -248,6 +251,7 @@ Importer::Importer() :
// 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 -
// as RegisterPPStep() does - all dependencies must be there.
mPostProcessingSteps.reserve(25);
#if (!defined AI_BUILD_NO_VALIDATEDS_PROCESS)
mPostProcessingSteps.push_back( new ValidateDSProcess()); // must be first
@ -276,6 +280,11 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_GENFACENORMALS_PROCESS)
mPostProcessingSteps.push_back( new GenFaceNormalsProcess());
#endif
// DON'T change the order of these five!
mPostProcessingSteps.push_back( new ComputeSpatialSortProcess());
#if (!defined AI_BUILD_NO_GENVERTEXNORMALS_PROCESS)
mPostProcessingSteps.push_back( new GenVertexNormalsProcess());
#endif
@ -285,6 +294,10 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_JOINVERTICES_PROCESS)
mPostProcessingSteps.push_back( new JoinVerticesProcess());
#endif
mPostProcessingSteps.push_back( new DestroySpatialSortProcess());
#if (!defined AI_BUILD_NO_SPLITLARGEMESHES_PROCESS)
mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Vertex());
#endif
@ -297,6 +310,15 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
mPostProcessingSteps.push_back( new ImproveCacheLocalityProcess());
#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
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;
#endif // ! DEBUG
}
// if failed, extract the error string
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
return mScene;
}

View File

@ -44,13 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <vector>
#include "JoinVerticesProcess.h"
#include "SpatialSort.h"
#include "../include/DefaultLogger.h"
#include "../include/aiPostProcess.h"
#include "../include/aiMesh.h"
#include "../include/aiScene.h"
// internal headers
#include "JoinVerticesProcess.h"
#include "ProcessHelper.h"
using namespace Assimp;
#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)
std::vector<bool> isVertexUnique( pMesh->mNumVertices, 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++)
// a little helper to find locally close vertices faster
// FIX: check whether we can reuse the SpatialSort of a previous step
const float epsilon = 1e-5f;
float posEpsilon;
SpatialSort* vertexFinder = NULL;
SpatialSort _vertexFinder;
if (shared)
{
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);
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);
}
// squared because we check against squared length of the vector difference
const float epsilon = 1e-5f;
const float posEpsilon = (maxVec - minVec).Length() * epsilon;
// squared because we check against squared length of the vector difference
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;
// 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);
// 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;
// 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
replaceIndex[a] = matchIndex;
isVertexUnique[a] = false;
} else
}
else
{
// no unique vertex matches it upto now -> so add it
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)
{
@ -278,39 +290,39 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
// color texture
case AI_LWO_CTEX:
{
surf.mColorTextures.push_back(Texture());
pTex = &surf.mColorTextures.back();
pTex = SetupNewTextureLWOB(surf.mColorTextures,
head->length);
break;
}
// diffuse texture
case AI_LWO_DTEX:
{
surf.mDiffuseTextures.push_back(Texture());
pTex = &surf.mDiffuseTextures.back();
pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
head->length);
break;
}
// specular texture
case AI_LWO_STEX:
{
surf.mSpecularTextures.push_back(Texture());
pTex = &surf.mSpecularTextures.back();
pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
head->length);
break;
}
// bump texture
case AI_LWO_BTEX:
{
surf.mBumpTextures.push_back(Texture());
pTex = &surf.mBumpTextures.back();
pTex = SetupNewTextureLWOB(surf.mBumpTextures,
head->length);
break;
}
// transparency texture
case AI_LWO_TTEX:
{
surf.mOpacityTextures.push_back(Texture());
pTex = &surf.mOpacityTextures.back();
pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
head->length);
break;
}
// texture path
// texture path
case AI_LWO_TIMG:
{
if (pTex)

View File

@ -56,7 +56,6 @@ Original copyright notice: "Ernie Wright 17 Sep 00"
// internal headers
#include "IFF.h"
#include "SmoothingGroups.h"
namespace Assimp {
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 */
// internal headers
#include "LWOLoader.h"
#include "MaterialSystem.h"
#include "StringComparison.h"
#include "SGSpatialSort.h"
#include "ByteSwap.h"
// public assimp headers
#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/assimp.hpp"
// internal headers
#include "LWOLoader.h"
#include "MaterialSystem.h"
#include "StringComparison.h"
#include "SGSpatialSort.h"
#include "ByteSwap.h"
#include "ProcessHelper.h"
// boost headers
#include <boost/scoped_ptr.hpp>
#include <sstream>
@ -313,7 +315,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
aiVector3D*& pp = pvUV[w];
const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
pp->x = src.x;
pp->y = 1.0f - src.y; // DX to OGL
pp->y = 1.f-src.y; // DX to OGL
pp++;
}
@ -414,20 +416,7 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
out[face.mIndices[i]] = vNor;
}
if (!surface.mMaximumSmoothAngle)return;
// 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;
const float posEpsilon = ComputePositionEpsilon(mesh);
// now generate the spatial sort tree
SGSpatialSort sSort;
@ -443,9 +432,11 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
}
// sort everything - this takes O(logn) time
sSort.Prepare();
std::vector<unsigned int> poResult;poResult.reserve(20);
std::vector<unsigned int> poResult;
poResult.reserve(20);
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
// 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;
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;
for (std::vector<unsigned int>::const_iterator
a = poResult.begin(), end = poResult.end();
a != end;++a)
for (a = poResult.begin();a != end;++a)
{
const aiVector3D& v = faceNormals[*a];
if (v * faceNormals[*beginIdx] < fLimit)continue;
if (v * faceNormals[idx] < fLimit)continue;
vNormals += v;
}
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)
{
T& chan = *it;
chan.abAssigned[srcIdx] = true;
chan.abAssigned.resize(chan.abAssigned.size()+1,false);
for (unsigned int a = 0; a < 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];
const unsigned int numPoints = (unsigned int)pointList.size();
const unsigned int numFaces = (unsigned int)list.size();
while (mFileBuffer < end)
{
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");
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 need to duplicate the corresponding polygon.
if (polyIdx >= list.size())
if (polyIdx >= numFaces)
{
DefaultLogger::get()->warn("LWO2: VMAD polygon index is out of range");
mFileBuffer += base->dims*4;continue;
}
LWO::Face& src = list[polyIdx];
refList.resize(refList.size()+src.mNumIndices, 0xffffffff);
// generate new vertex positions
for (unsigned int i = 0; i < src.mNumIndices;++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
// so we get a single linked list we can traverse in
// only one direction
refList.push_back(0xffffffff);
AddToSingleLinkedList(refList,srcIdx,(src.mIndices[i] = (unsigned int)pointList.size()));
AddToSingleLinkedList(refList,srcIdx,src.mIndices[i]);
pointList.push_back(pointList[srcIdx]);
CreateNewEntry(mCurLayer->mVColorChannels, srcIdx );

View File

@ -339,6 +339,17 @@ private:
void ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
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:
/** true if the file is a LWO2 file*/

View File

@ -87,7 +87,6 @@ struct Vertex
aiVector3D normal;
aiVector2D texCoords;
uint32_t numWeights;
Weight weights; // variable sized
} PACK_STRUCT;
// ---------------------------------------------------------------------------
@ -147,7 +146,6 @@ struct Frame {
aiVector3D localOrigin; // midpoint of bounds, used for sphere cull
float radius; // dist from localOrigin to corner
char name[16];
Bone bones[1]; // [numBones]
} 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);
if (!pcLOD->numSurfaces)
throw new ImportErrorException("MDR: LOD has zero surfaces assigned");
uint32_t cur = pcLOD->ofsSurfaces;
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.
void MDRImporter::InternReadFile(
const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
void MDRImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
#if 0
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
// 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
this->pcHeader = (BE_NCONST MDR::Header*)this->mBuffer;
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];
// assume it is a triangle
aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]];
aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]];
aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]];
@ -76,9 +75,7 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
sMesh.mNormals[face.mIndices[2]] = vNor;
}
// calculate the position bounds so we have a reliable epsilon to
// check position differences against
// @Schrompf: This is the 6th time this snippet is repeated!
// 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 < sMesh.mPositions.size(); a++)
{
@ -104,14 +101,17 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
}
sSort.Prepare();
std::vector<bool> vertexDone(sMesh.mPositions.size(),false);
for( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
i != sMesh.mFaces.end();++i)
{
std::vector<unsigned int> poResult;
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);
aiVector3D vNormals;
@ -120,10 +120,18 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
a != poResult.end();++a)
{
vNormals += sMesh.mNormals[(*a)];
//fDiv += 1.0f;
}
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;

View File

@ -47,7 +47,22 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// 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
// 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());
}
// ------------------------------------------------------------------------------------------------
// Destructor
SpatialSort::~SpatialSort()
{
// nothing to do here, everything destructs automatically
}
// ------------------------------------------------------------------------------------------------
// 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

View File

@ -67,9 +67,23 @@ public:
* by index.
* @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.
* @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 */
~SpatialSort();

View File

@ -106,10 +106,9 @@ inline const char* fast_atof_move( const char* c, float& out)
++c;
inv = true;
}
else if (*c=='+')++c;
//f = (float)strtol(c, &t, 10);
f = (float) strtol10_64 ( c, &c );
if (*c == '.')
{
++c;
@ -129,10 +128,10 @@ inline const char* fast_atof_move( const char* c, float& out)
c = t;
if (*c == 'e')
// FIX: a large 'E' should be allowed, too
if (*c == 'e' || *c == 'E')
{
++c;
//float exp = (float)strtol(c, &t, 10);
bool einv = (*c=='-');
if (einv)
++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.
*
* 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.
* 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
* 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.
*/
#define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE "pp.gsn.max_smoothing"

View File

@ -76,6 +76,7 @@ namespace Assimp
class BaseImporter;
class BaseProcess;
class SharedPostProcessInfo;
class IOStream;
class IOSystem;
@ -403,6 +404,9 @@ protected:
validateDataStructure-Step to be executed before
and after every single postprocess step */
bool bExtraVerbose;
/** Used by post-process steps to share data */
SharedPostProcessInfo* mPPShared;
};
} // 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
#include "../../include/aiTypes.h"
#include "../../include/aiMesh.h"
#include "../../include/aiAnim.h"
#include "../../include/aiScene.h"
#include "../../include/aiAssert.h"
#include "../../include/aiPostProcess.h"
#include "../../include/assimp.hpp"
#include "../../include/DefaultLogger.h"
#include <aiTypes.h>
#include <aiMesh.h>
#include <aiAnim.h>
#include <aiScene.h>
#include <aiAssert.h>
#include <aiPostProcess.h>
#include <assimp.hpp>
#include <DefaultLogger.h>
// include all jAssimp internal header files
#include "JNIEnvironment.h"
@ -93,6 +93,7 @@ bool jValidateContext (JASSIMP_CONTEXT context)
DefaultLogger::get()->error("[jnibridge] Invalid context");
return false;
}
// ------------------------------------------------------------------------------------------------
/* Used in debug builds to validate a given scene
*/
@ -107,6 +108,7 @@ bool jValidateScene (const aiScene* scene)
}
#endif // ! ASSIMP_DEBUG
// ------------------------------------------------------------------------------------------------
/* Used in debug builds to validate a given scene
*/
@ -124,6 +126,7 @@ Assimp::Importer* jGetValidImporterScenePair (JASSIMP_CONTEXT jvmcontext)
#endif // ! ASSIMP_DEBUG
return pcImp;
}
// ------------------------------------------------------------------------------------------------
/*
* Class: assimp_Importer
@ -164,6 +167,7 @@ JNIEXPORT jlong JNICALL Java_assimp_Importer__1NativeInitContext
return context;
}
// ------------------------------------------------------------------------------------------------
/*
* Class: assimp_Importer
@ -189,6 +193,7 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeFreeContext
JNIEnvironment::Get()->DetachFromCurrentThread();
return 0;
}
// ------------------------------------------------------------------------------------------------
/*
* Class: assimp_Importer
@ -213,7 +218,7 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
}
// get the importer instance from the context
Assimp::Importer* pcImp = (Assimp::Importer*)jvmcontext;
aiScene* pcOut;
const aiScene* pcOut;
// and load the file. The aiScene object itself remains accessible
// via Importer.GetScene().
@ -227,7 +232,7 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
}
// release the path again
free((void*)szPath);
::free((void*)szPath);
// allocate a new assimp.Scene object to be returned by the importer
jobject jScene;
@ -245,6 +250,67 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
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 Assimp

View File

@ -6,36 +6,8 @@ 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.
See the disclaimer in JNIEnvironment.h for licensing and distribution
conditions.
---------------------------------------------------------------------------
*/
@ -106,29 +78,29 @@ JNIThreadData* JNIEnvironment::GetThread()
// ------------------------------------------------------------------------------------------------
void JNIEnvironment::_java::_lang::_String::Initialize()
{
JNIEnv* pcEnv = JJNIEnvironment::Get()->GetThread()->m_pcEnv;
JNIEnv* pcEnv = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// first initialize some members
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")))
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(
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()
{
JNIEnv* pcEnv = JJNIEnvironment::Get()->GetThread()->m_pcEnv;
JNIEnv* pcEnv = JNIEnvironment::Get()->GetThread()->m_pcEnv;
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")))
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)
@ -140,7 +112,7 @@ jstring JNU_NewStringNative(JNIEnv *env, const char *str)
{
return NULL; /* out of memory error */
}
len = strlen(str);
len = (int)::strlen(str);
bytes = env->NewByteArray(len);
if (bytes != NULL)
{
@ -187,13 +159,13 @@ char *JNU_GetStringNativeChars(JNIEnv *env, jstring jstr)
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;
jboolean iscopy = FALSE;
// 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");
// 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
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 <jni.h>
#include "../../../include/aiAssert.h"
#include "../../../include/aiMesh.h"
#include "../../../include/aiScene.h"
#include <aiAssert.h>
#include <aiMesh.h>
#include <aiScene.h>
namespace Assimp {
@ -60,17 +60,18 @@ namespace JNIBridge {
#define AIJ_GET_HANDLE(__handle__) \
(JNIEnvironment::Get()-> __handle__)
#define AIJ_GET_DEFAULT_CTOR_HANDLE (__handle__) \
#define AIJ_GET_DEFAULT_CTOR_HANDLE(__handle__) \
(JNIEnvironment::Get()-> __handle__ . DefaultCtor)
#define AIJ_GET_CLASS_HANDLE (__handle__) \
(JNIEnvironment::Get()-> __handle__ . Class)
#define AIJ_GET_CLASS_HANDLE(__handle__) \
(JNIEnvironment::Get()-> __handle__.Class)
// ---------------------------------------------------------------------------
/** @class JNIThreadData
* @brief Manages a list of JNI data structures that are
* private to a thread.
*/
// ---------------------------------------------------------------------------
struct JNIThreadData
{
//! Default constructor
@ -93,6 +94,7 @@ struct JNIThreadData
* @brief Helper class to manage the JNI environment for multithreaded
* use of the library.
*/
// ---------------------------------------------------------------------------
class JNIEnvironment
{
private:
@ -151,7 +153,6 @@ public:
public:
struct _java
{
inline void Initialize()
@ -195,6 +196,20 @@ public:
} 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
struct _assimp
@ -202,7 +217,7 @@ public:
//! Initializes the package assimp for use with jAssimp
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
NativeException.Initialize();
@ -223,7 +238,7 @@ public:
};
//! Represents the JNI interface to class assimp.NativeException
struct _NativeException
struct _NativeException
{
void Initialize();
@ -245,13 +260,11 @@ public:
//! Represents the JNI interface to class assimp.Scene
struct _Scene
struct _Scene : public _Base
{
void Initialize();
AIJ_SET_INPUT_TYPE(aiScene);
jclass Class;
jmethodID DefaultCtor;
jfieldID m_vMeshes;
jfieldID m_vTextures;
@ -264,14 +277,10 @@ public:
//! Represents the JNI interface to class assimp.Mesh
struct _Mesh
struct _Mesh : public _Base
{
AIJ_SET_INPUT_TYPE(aiMesh);
void Initialize();
void Fill(jobject obj,const aiMesh* pcSrc);
jclass Class;
jmethodID DefaultCtor;
jfieldID m_vVertices;
jfieldID m_vTangents;
@ -287,27 +296,33 @@ public:
} Mesh;
//! Represents the JNI interface to class assimp.Bone
struct _Bone
struct _Bone : public _Base
{
void Initialize();
jclass Class;
jmethodID DefaultCtor;
AIJ_SET_INPUT_TYPE(aiBone);
jfieldID name;
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;
//! Represents the JNI interface to class assimp.Animation
struct _Animation
struct _Animation : public _Base
{
void Initialize();
jclass Class;
jmethodID DefaultCtor;
AIJ_SET_INPUT_TYPE(aiAnimation);
jfieldID name;
jfieldID mDuration;
@ -317,10 +332,10 @@ public:
} Animation;
//! Represents the JNI interface to class assimp.BoneAnim
struct _BoneAnim
struct _BoneAnim : public _Base
{
void Initialize();
AIJ_SET_INPUT_TYPE(aiBoneAnim);
//! Represents the JNI interface to class assimp.BoneAnim.KeyFrame<quak>
struct _KeyFrame
@ -334,10 +349,6 @@ public:
} KeyFrame;
jclass Class;
jmethodID DefaultCtor;
jfieldID mName;
jfieldID mQuatKeys;
jfieldID mPosKeys;
@ -346,13 +357,10 @@ public:
} BoneAnim;
//! Represents the JNI interface to class assimp.Texture
struct _Texture
struct _Texture : public _Base
{
void Initialize();
jclass Class;
jmethodID DefaultCtor;
AIJ_SET_INPUT_TYPE(aiTexture);
jfieldID width;
jfieldID height;
@ -361,67 +369,58 @@ public:
} Texture;
//! Represents the JNI interface to class assimp.CompressedTexture
struct _CompressedTexture
struct _CompressedTexture : public _Base
{
void Initialize();
AIJ_SET_INPUT_TYPE(aiTexture);
jclass Class;
jmethodID DefaultCtor;
jfieldID m_format;
} CompressedTexture;
//! Represents the JNI interface to class assimp.Material
struct _Material
struct _Material : public _Base
{
void Initialize();
AIJ_SET_INPUT_TYPE(aiMaterial);
//! 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 value;
} Property;
jclass Class;
jmethodID DefaultCtor;
jfieldID properties;
} Material;
//! Represents the JNI interface to class assimp.Matrix4x4
struct _Matrix4x4
struct _Matrix4x4 : public _Base
{
void Initialize();
jclass Class;
jmethodID DefaultCtor;
AIJ_SET_INPUT_TYPE(aiMatrix4x4);
jfieldID coeff;
} Matrix4x4;
//! Represents the JNI interface to class assimp.Matrix3x3
struct _Matrix3x3
struct _Matrix3x3 : public _Base
{
void Initialize();
jclass Class;
jmethodID DefaultCtor;
AIJ_SET_INPUT_TYPE(aiMatrix3x3);
jfieldID coeff;
} Matrix3x3;
//! Represents the JNI interface to class assimp.Quaternion
struct _Quaternion
struct _Quaternion : public _Base
{
void Initialize();
jclass Class;
jmethodID DefaultCtor;
AIJ_SET_INPUT_TYPE(aiQuaternion);
jfieldID x;
jfieldID y;
@ -431,13 +430,10 @@ public:
} Quaternion;
//! Represents the JNI interface to class assimp.Node
struct _Node
struct _Node : public _Base
{
void Initialize();
jclass Class;
jmethodID DefaultCtor;
AIJ_SET_INPUT_TYPE(aiNode);
jfieldID meshIndices;
jfieldID nodeTransform;
@ -449,6 +445,12 @@ public:
} assimp;
inline void Initialize()
{
assimp.Initialize();
java.Initialize();
}
private:
//! Singleton instance
@ -461,17 +463,15 @@ private:
unsigned int m_iRefCnt;
};
};};
// ---------------------------------------------------------------------------
/** @brief Helper function to copy data to a Java array
*
* @param pc JNI env handle
* @param jfl Java array
* @param data Input data
* @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
@ -494,6 +494,23 @@ jstring JNU_NewStringNative(JNIEnv *env, const char *str);
*/
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

View File

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

View File

@ -52,12 +52,14 @@ namespace JNIBridge {
// ------------------------------------------------------------------------------------------------
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
if(!(this->Class = pc->FindClass("assimp.Mesh")))
JNIEnvironment::Get()->ThrowNativeError("Unable to load class assimp.mesh");
DefaultCtor = pc->GetMethodID(Class,"<init>","");
// load all fields of the class
this->m_vVertices = pc->GetFieldID(Class,"m_vVertices","[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)
{
JNIEnv* pc = JJNIEnvironment::Get()->GetThread()->m_pcEnv;
JNIEnv* pc = JNIEnvironment::Get()->GetThread()->m_pcEnv;
// set the material index
pc->SetIntField(obj,this->m_iMaterialIndex,pcSrc->mMaterialIndex);
// allocate the arrays and fill them
float* pf;
const unsigned int size = pcSrc->mNumVertices*12;
const unsigned int size2 = pcSrc->mNumVertices*3;
// copy vertex positions
if (pcSrc->HasPositions())
{
// allocate and copy data
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);
}
// copy vertex normals
@ -109,25 +108,20 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
{
// allocate and copy data
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);
}
// copy tangents and bitangents
if (pcSrc->HasTangentsAndBitangents())
{
// allocate and copy data
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);
jfl = pc->NewFloatArray(size2);
JNU_CopyDataToArray(jfl,pcSrc->mBitangents,size);
// set the corresponding field in the java object
JNU_CopyDataToArray(pc,jfl,pcSrc->mBitangents,size);
pc->SetObjectField(obj,this->m_vBitangents,jfl);
}
// copy texture coordinates
@ -140,9 +134,9 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
while (pcSrc->HasTextureCoords(channel))
{
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;
}
@ -150,7 +144,7 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
pc->SetObjectField(obj,this->m_avUVs,jobjarr);
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);
}
// copy vertex colors
@ -166,7 +160,7 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
while (pcSrc->HasVertexColors(channel))
{
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);
++channel;
@ -186,15 +180,13 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
// allocate and copy data
jintArray jil = pc->NewIntArray(size2);
int* pf;
uint32_t* pf;
jboolean iscopy = FALSE;
// lock the array and get direct access to its buffer
if(!pf = pc->GetPrimitiveArrayCritical(jil,&iscopy))
if(!(pf = (uint32_t*)pc->GetPrimitiveArrayCritical(jil,&iscopy)))
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)
{
ai_assert(3 == pcCur->mNumIndices);
@ -203,36 +195,17 @@ void JNIEnvironment::_assimp::_Mesh::Fill(jobject obj,const aiMesh* pcSrc)
*pf++ = pcCur->mIndices[2];
}
// release our reference to the array
pc->ReleasePrimitiveArrayCritical(jil,pf,0);
// set the corresponding field in the java object
pc->SetObjectField(obj,this->m_vFaces,jil);
}
// copy bones
if (pcSrc->mNumBones)
{
// allocate the array
jobjectArray jarr = pc->NewObjectArray(pcSrc->mNumBones,
AIJ_GET_HANDLE(assimp.Bone.Class),0);
// 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);
jobjectArray ja;
JNU_CopyObjectArrayToVM(pc,(const void**)pcSrc->mBones,pcSrc->mNumBones,
AIJ_GET_HANDLE(assimp.Bone),ja);
pc->SetObjectField(obj,m_vBones,ja);
}
}

View File

@ -6,36 +6,8 @@ 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.
See the disclaimer in JNIEnvironment.h for licensing and distribution
conditions.
---------------------------------------------------------------------------
*/
@ -50,10 +22,10 @@ namespace Assimp {
namespace JNIBridge {
// ------------------------------------------------------------------------------------------------
JNIEnvironment::_assimp::_NativeException::Initialize()
void JNIEnvironment::_assimp::_NativeException::Initialize()
{
// 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
if(!(this->Class = pc->FindClass("assimp.NativeException")))
@ -77,4 +49,5 @@ void JNIEnvironment::ThrowNativeError(const char* msg /*= NULL*/)
pc->ThrowNew(this->assimp.NativeException.Class,
msg ? msg
: "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
(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
}
#endif

View File

@ -61,7 +61,7 @@ public class Scene {
private Animation[] m_vAnimations = null;
private Node m_rootNode = null;
private Importer imp = null;
private int flags;
private int flags = 0;
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.
* @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
* However, at least one parameter is expected

View File

@ -2,13 +2,13 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
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
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{5691E159-2D9B-407F-971F-EA5C592DC524} = {5691E159-2D9B-407F-971F-EA5C592DC524}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Assimp", "assimp.vcproj", "{5691E159-2D9B-407F-971F-EA5C592DC524}"
ProjectSection(WebsiteProperties) = preProject
@ -17,15 +17,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Assimp", "assimp.vcproj", "
EndProjectSection
EndProject
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
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{5691E159-2D9B-407F-971F-EA5C592DC524} = {5691E159-2D9B-407F-971F-EA5C592DC524}
EndProjectSection
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
Debug.AspNetCompiler.Debug = "True"
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.Build.0 = Release|x64
{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|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|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|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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

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

View File

@ -2,7 +2,7 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="jAssimp_NOT_FINISHED"
Name="jAssimp_NOT_WORKING"
ProjectGUID="{FE78BFBA-4BA5-457D-8602-B800D498102D}"
RootNamespace="jAssimp"
Keyword="Win32Proj"
@ -11,16 +11,19 @@
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
OutputDirectory="./../../bin/$(ProjectName)_$(ConfigurationName)_$(PlatformName)"
IntermediateDirectory="./../../obj/$(ProjectName)_$(ConfigurationName)_$(PlatformName)"
ConfigurationType="2"
CharacterSet="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
@ -40,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
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"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -61,7 +64,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="assimp.lib"
OutputFile="$(OutDir)\jAssimp32d.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="$(SolutionDir)..\..\lib\assimp_$(ConfigurationName)_DLL_$(PlatformName)\"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
@ -92,11 +98,91 @@
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
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"
>
<Tool
@ -116,7 +202,7 @@
/>
<Tool
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"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@ -135,7 +221,10 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="assimp.lib"
OutputFile="$(OutDir)\jAssimp32.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="$(SolutionDir)..\..\lib\assimp_$(ConfigurationName)_DLL_$(PlatformName)\"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
@ -167,6 +256,86 @@
Name="VCPostBuildEventTool"
/>
</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>
<References>
</References>
@ -253,18 +422,6 @@
RelativePath="..\..\port\jAssimp\jni_bridge\assimp_Importer.h"
>
</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