Browse Source

- ASE loader is now able to load triangles. Well, their position is not correct, but at least triangles ...
- jAssimp API WIP. assimp.Mesh interface finished, including JNI implementations. Maybe a few more native functions than necessary, but I want to keep the native parts as simple as possible
- Updates to the documentation

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@37 67173fc5-114c-0410-ac8e-9d2fd5bffc1f

aramis_acg 17 years ago
parent
commit
5d18194990

+ 74 - 6
code/ASELoader.cpp

@@ -145,12 +145,64 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
 	ai_assert(NULL != pcScene);
 
 	pcScene->mRootNode = new aiNode();
-	pcScene->mRootNode->mNumMeshes = pcScene->mNumMeshes;
-	pcScene->mRootNode->mMeshes = new unsigned int[pcScene->mRootNode->mNumMeshes];
+	pcScene->mRootNode->mNumMeshes = 0;
+	pcScene->mRootNode->mMeshes = 0;
 
-	for (unsigned int i = 0; i < pcScene->mRootNode->mNumMeshes;++i)
-		pcScene->mRootNode->mMeshes[i] = i;
+	ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
+	std::vector<std::pair<aiMatrix4x4,std::list<unsigned int> > > stack;
+	stack.reserve(pcScene->mNumMeshes);
+	for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
+	{
+		// get the transformation matrix of the node
+		aiMatrix4x4* pmTransform = (aiMatrix4x4*)pcScene->mMeshes[i]->mColors[2];
+		
+		// search for an identical matrix in our list
+		for (std::vector<std::pair<aiMatrix4x4,std::list<unsigned int> > >::iterator
+			a =  stack.begin();
+			a != stack.end();++a)
+		{
+			if ((*a).first == *pmTransform)
+			{
+				(*a).second.push_back(i);
+				pmTransform->a1 = std::numeric_limits<float>::quiet_NaN();
+				break;
+			}
+		}
+		if (is_not_qnan(pmTransform->a1))
+		{
+			// add a new entry ...
+			stack.push_back(std::pair<aiMatrix4x4,std::list<unsigned int> >(
+				*pmTransform,std::list<unsigned int>()));
+			stack.back().second.push_back(i);
+		}
+		// delete the matrix
+		delete pmTransform;
+		pcScene->mMeshes[i]->mColors[2] = NULL;
+	}
 
+	// allocate enough space for the child nodes
+	pcScene->mRootNode->mNumChildren = stack.size();
+	pcScene->mRootNode->mChildren = new aiNode*[stack.size()];
+
+	// now build all nodes
+	for (std::vector<std::pair<aiMatrix4x4,std::list<unsigned int> > >::iterator
+		a =  stack.begin();
+		a != stack.end();++a)
+	{
+		aiNode* pcNode = new aiNode();
+		pcNode->mNumMeshes = (*a).second.size();
+		pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
+		for (std::list<unsigned int>::const_iterator
+			i =  (*a).second.begin();
+			i != (*a).second.end();++i)
+		{
+			*pcNode->mMeshes++ = *i;
+		}
+		pcNode->mMeshes -= pcNode->mNumMeshes;
+		pcNode->mTransformation = (*a).first;
+		*pcScene->mRootNode->mChildren++ = pcNode;
+	}
+	pcScene->mRootNode->mChildren -= stack.size();
 	return;
 }
 // ------------------------------------------------------------------------------------------------
@@ -226,6 +278,18 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
 	for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
 		mesh.amTexCoords[c] = amTexCoords[c];
 
+	// now need to transform all vertices with the inverse of their
+	// transformation matrix ...
+	aiMatrix4x4 mInverse = mesh.mTransform;
+	mInverse.Inverse();
+
+	for (std::vector<aiVector3D>::iterator
+		i =  mesh.mPositions.begin();
+		i != mesh.mPositions.end();++i)
+	{
+		(*i) = mInverse * (*i);
+	}
+
 	return;
 }
 // ------------------------------------------------------------------------------------------------
@@ -415,8 +479,10 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
 				// we will need this material
 				this->mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials[p].bNeed = true;
 
-				// store the real index here ...
+				// store the real index here ... color channel 3
 				p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
+				// store the real transformation matrix in color channel 2
+				p_pcOut->mColors[2] = (aiColor4D*) new aiMatrix4x4(mesh.mTransform);
 				avOutMeshes.push_back(p_pcOut);
 
 				// convert vertices
@@ -495,8 +561,10 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
 		p_pcOut->mMaterialIndex = ASE::Face::DEFAULT_MATINDEX;
 		this->mParser->m_vMaterials[mesh.iMaterialIndex].bNeed = true;
 
-		// store the real index here ...
+		// store the real index here ... in color channel 3
 		p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
+		// store the transformation matrix in color channel 2
+		p_pcOut->mColors[2] = (aiColor4D*) new aiMatrix4x4(mesh.mTransform);
 		avOutMeshes.push_back(p_pcOut);
 
 		// convert vertices

+ 59 - 59
code/ASEParser.cpp

@@ -104,7 +104,7 @@ bool Parser::SkipToNextToken()
 {
 	while (true)
 	{
-		if ('*' == *this->m_szFile)return true;
+		if ('*' == *this->m_szFile || '}' == *this->m_szFile || '{' == *this->m_szFile)return true;
 		if ('\0' == *this->m_szFile)return false;
 
 		++this->m_szFile;
@@ -126,7 +126,7 @@ bool Parser::SkipOpeningBracket()
 bool Parser::SkipSection()
 {
 	// must handle subsections ...
-	unsigned int iCnt = 1;
+	int iCnt = 0;
 	while (true)
 	{
 		if ('}' == *this->m_szFile)
@@ -156,7 +156,7 @@ bool Parser::SkipSection()
 // ------------------------------------------------------------------------------------------------
 void Parser::Parse()
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -177,21 +177,21 @@ void Parser::Parse()
 				}
 			}
 			// main scene information
-			else if (0 == strncmp(this->m_szFile,"*SCENE",6) &&
+			if (0 == strncmp(this->m_szFile,"*SCENE",6) &&
 				IsSpaceOrNewLine(*(this->m_szFile+6)))
 			{
 				this->m_szFile+=7;
 				this->ParseLV1SceneBlock();
 			}
 			// material list
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL_LIST",14) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL_LIST",14) &&
 				IsSpaceOrNewLine(*(this->m_szFile+14)))
 			{
 				this->m_szFile+=15;
 				this->ParseLV1MaterialListBlock();
 			}
 			// geometric object (mesh)
-			else if (0 == strncmp(this->m_szFile,"*GEOMOBJECT",11) &&
+			if (0 == strncmp(this->m_szFile,"*GEOMOBJECT",11) &&
 				IsSpaceOrNewLine(*(this->m_szFile+11)))
 			{
 				this->m_szFile+=12;
@@ -224,7 +224,7 @@ void Parser::Parse()
 // ------------------------------------------------------------------------------------------------
 void Parser::ParseLV1SceneBlock()
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -237,7 +237,7 @@ void Parser::ParseLV1SceneBlock()
 				// parse a color triple and assume it is really the bg color
 				this->ParseLV4MeshFloatTriple( &this->m_clrBackground.r );
 			}
-			else if (0 == strncmp(this->m_szFile,"*SCENE_AMBIENT_STATIC",21) &&
+			if (0 == strncmp(this->m_szFile,"*SCENE_AMBIENT_STATIC",21) &&
 				IsSpaceOrNewLine(*(this->m_szFile+21)))
 			{
 				this->m_szFile+=22;
@@ -269,7 +269,7 @@ void Parser::ParseLV1SceneBlock()
 // ------------------------------------------------------------------------------------------------
 void Parser::ParseLV1MaterialListBlock()
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	unsigned int iMaterialCount = 0;
 	while (true)
 	{
@@ -284,7 +284,7 @@ void Parser::ParseLV1MaterialListBlock()
 				// now allocate enough storage to hold all materials
 				this->m_vMaterials.resize(iMaterialCount);
 			}
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL",9) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL",9) &&
 				IsSpaceOrNewLine(*(this->m_szFile+9)))
 			{
 				this->m_szFile+=10;
@@ -330,7 +330,7 @@ void Parser::ParseLV1MaterialListBlock()
 // ------------------------------------------------------------------------------------------------
 void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	unsigned int iNumSubMaterials = 0;
 	while (true)
 	{
@@ -352,28 +352,28 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				this->m_szFile = sz;
 			}
 			// ambient material color
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL_AMBIENT",17) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL_AMBIENT",17) &&
 				IsSpaceOrNewLine(*(this->m_szFile+17)))
 			{
 				this->m_szFile+=18;
 				this->ParseLV4MeshFloatTriple(&mat.mAmbient.r);
 			}
 			// diffuse material color
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL_DIFFUSE",17) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL_DIFFUSE",17) &&
 				IsSpaceOrNewLine(*(this->m_szFile+17)))
 			{
 				this->m_szFile+=18;
 				this->ParseLV4MeshFloatTriple(&mat.mDiffuse.r);
 			}
 			// specular material color
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL_SPECULAR",18) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL_SPECULAR",18) &&
 				IsSpaceOrNewLine(*(this->m_szFile+18)))
 			{
 				this->m_szFile+=19;
 				this->ParseLV4MeshFloatTriple(&mat.mSpecular.r);
 			}
 			// material shading type
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL_SHADING",17) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL_SHADING",17) &&
 				IsSpaceOrNewLine(*(this->m_szFile+17)))
 			{
 				this->m_szFile+=18;
@@ -410,7 +410,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				}
 			}
 			// material transparency
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL_TRANSPARENCY",22) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL_TRANSPARENCY",22) &&
 				IsSpaceOrNewLine(*(this->m_szFile+22)))
 			{
 				this->m_szFile+=23;
@@ -418,7 +418,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				mat.mTransparency = 1.0f - mat.mTransparency;
 			}
 			// material self illumination
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL_SELFILLUM",19) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL_SELFILLUM",19) &&
 				IsSpaceOrNewLine(*(this->m_szFile+19)))
 			{
 				this->m_szFile+=20;
@@ -430,7 +430,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				mat.mEmissive.b = f;
 			}
 			// material shininess
-			else if (0 == strncmp(this->m_szFile,"*MATERIAL_SHINE",15) &&
+			if (0 == strncmp(this->m_szFile,"*MATERIAL_SHINE",15) &&
 				IsSpaceOrNewLine(*(this->m_szFile+15)))
 			{
 				this->m_szFile+=16;
@@ -438,7 +438,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				mat.mSpecularExponent *= 15;
 			}
 			// diffuse color map
-			else if (0 == strncmp(this->m_szFile,"*MAP_DIFFUSE",12) &&
+			if (0 == strncmp(this->m_szFile,"*MAP_DIFFUSE",12) &&
 				IsSpaceOrNewLine(*(this->m_szFile+12)))
 			{
 				this->m_szFile+=13;
@@ -448,7 +448,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				this->ParseLV3MapBlock(mat.sTexDiffuse);
 			}
 			// ambient color map
-			else if (0 == strncmp(this->m_szFile,"*MAP_AMBIENT",12) &&
+			if (0 == strncmp(this->m_szFile,"*MAP_AMBIENT",12) &&
 				IsSpaceOrNewLine(*(this->m_szFile+12)))
 			{
 				this->m_szFile+=13;
@@ -458,7 +458,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				this->ParseLV3MapBlock(mat.sTexAmbient);
 			}
 			// specular color map
-			else if (0 == strncmp(this->m_szFile,"*MAP_SPECULAR",13) &&
+			if (0 == strncmp(this->m_szFile,"*MAP_SPECULAR",13) &&
 				IsSpaceOrNewLine(*(this->m_szFile+13)))
 			{
 				this->m_szFile+=14;
@@ -468,7 +468,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				this->ParseLV3MapBlock(mat.sTexSpecular);
 			}
 			// opacity map
-			else if (0 == strncmp(this->m_szFile,"*MAP_OPACITY",12) &&
+			if (0 == strncmp(this->m_szFile,"*MAP_OPACITY",12) &&
 				IsSpaceOrNewLine(*(this->m_szFile+12)))
 			{
 				this->m_szFile+=13;
@@ -478,7 +478,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				this->ParseLV3MapBlock(mat.sTexOpacity);
 			}
 			// emissive map
-			else if (0 == strncmp(this->m_szFile,"*MAP_SELFILLUM",14) &&
+			if (0 == strncmp(this->m_szFile,"*MAP_SELFILLUM",14) &&
 				IsSpaceOrNewLine(*(this->m_szFile+14)))
 			{
 				this->m_szFile+=15;
@@ -488,7 +488,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				this->ParseLV3MapBlock(mat.sTexEmissive);
 			}
 			// bump map
-			else if (0 == strncmp(this->m_szFile,"*MAP_BUMP",9) &&
+			if (0 == strncmp(this->m_szFile,"*MAP_BUMP",9) &&
 				IsSpaceOrNewLine(*(this->m_szFile+9)))
 			{
 				this->m_szFile+=10;
@@ -498,7 +498,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				this->ParseLV3MapBlock(mat.sTexBump);
 			}
 			// specular/shininess map
-			else if (0 == strncmp(this->m_szFile,"*MAP_SHINE",10) &&
+			if (0 == strncmp(this->m_szFile,"*MAP_SHINE",10) &&
 				IsSpaceOrNewLine(*(this->m_szFile+10)))
 			{
 				this->m_szFile+=11;
@@ -508,7 +508,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				this->ParseLV3MapBlock(mat.sTexShininess);
 			}
 			// number of submaterials
-			else if (0 == strncmp(this->m_szFile,"*NUMSUBMTLS",11) &&
+			if (0 == strncmp(this->m_szFile,"*NUMSUBMTLS",11) &&
 				IsSpaceOrNewLine(*(this->m_szFile+11)))
 			{
 				this->m_szFile+=12;
@@ -518,7 +518,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 				mat.avSubMaterials.resize(iNumSubMaterials);
 			}
 			// submaterial chunks
-			else if (0 == strncmp(this->m_szFile,"*SUBMATERIAL",12) &&
+			if (0 == strncmp(this->m_szFile,"*SUBMATERIAL",12) &&
 				IsSpaceOrNewLine(*(this->m_szFile+12)))
 			{
 				this->m_szFile+=13;
@@ -566,7 +566,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
 // ------------------------------------------------------------------------------------------------
 void Parser::ParseLV3MapBlock(Texture& map)
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	unsigned int iNumSubMaterials = 0;
 	while (true)
 	{
@@ -669,7 +669,7 @@ void Parser::ParseLV3MapBlock(Texture& map)
 // ------------------------------------------------------------------------------------------------
 void Parser::ParseLV1GeometryObjectBlock(ASE::Mesh& mesh)
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -706,14 +706,14 @@ void Parser::ParseLV1GeometryObjectBlock(ASE::Mesh& mesh)
 				this->m_szFile = sz;
 			}
 			// transformation matrix of the node
-			else if (0 == strncmp(this->m_szFile,"*NODE_TM" ,8) &&
+			if (0 == strncmp(this->m_szFile,"*NODE_TM" ,8) &&
 				IsSpaceOrNewLine(*(this->m_szFile+8)))
 			{
 				this->m_szFile+=9;
 				this->ParseLV2NodeTransformBlock(mesh);
 			}
 			// mesh data
-			else if (0 == strncmp(this->m_szFile,"*MESH" ,5) &&
+			if (0 == strncmp(this->m_szFile,"*MESH" ,5) &&
 				IsSpaceOrNewLine(*(this->m_szFile+5)))
 			{
 				this->m_szFile+=6;
@@ -743,7 +743,7 @@ void Parser::ParseLV1GeometryObjectBlock(ASE::Mesh& mesh)
 // ------------------------------------------------------------------------------------------------
 void Parser::ParseLV2NodeTransformBlock(ASE::Mesh& mesh)
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -756,21 +756,21 @@ void Parser::ParseLV2NodeTransformBlock(ASE::Mesh& mesh)
 				this->ParseLV4MeshFloatTriple(mesh.mTransform[0]);
 			}
 			// second row of the transformation matrix
-			else if (0 == strncmp(this->m_szFile,"*TM_ROW1" ,8) &&
+			if (0 == strncmp(this->m_szFile,"*TM_ROW1" ,8) &&
 				IsSpaceOrNewLine(*(this->m_szFile+8)))
 			{
 				this->m_szFile+=9;
 				this->ParseLV4MeshFloatTriple(mesh.mTransform[1]);
 			}
 			// third row of the transformation matrix
-			else if (0 == strncmp(this->m_szFile,"*TM_ROW2" ,8) &&
+			if (0 == strncmp(this->m_szFile,"*TM_ROW2" ,8) &&
 				IsSpaceOrNewLine(*(this->m_szFile+8)))
 			{
 				this->m_szFile+=9;
 				this->ParseLV4MeshFloatTriple(mesh.mTransform[2]);
 			}
 			// fourth row of the transformation matrix
-			else if (0 == strncmp(this->m_szFile,"*TM_ROW3" ,8) &&
+			if (0 == strncmp(this->m_szFile,"*TM_ROW3" ,8) &&
 				IsSpaceOrNewLine(*(this->m_szFile+8)))
 			{
 				this->m_szFile+=9;
@@ -806,7 +806,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
 	unsigned int iNumTFaces = 0;
 	unsigned int iNumCVertices = 0;
 	unsigned int iNumCFaces = 0;
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -819,49 +819,49 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
 				this->ParseLV4MeshLong(iNumVertices);
 			}
 			// Number of texture coordinates in the mesh
-			else if (0 == strncmp(this->m_szFile,"*MESH_NUMTVERTEX" ,16) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_NUMTVERTEX" ,16) &&
 				IsSpaceOrNewLine(*(this->m_szFile+16)))
 			{
 				this->m_szFile+=17;
 				this->ParseLV4MeshLong(iNumTVertices);
 			}
 			// Number of vertex colors in the mesh
-			else if (0 == strncmp(this->m_szFile,"*MESH_NUMCVERTEX" ,16) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_NUMCVERTEX" ,16) &&
 				IsSpaceOrNewLine(*(this->m_szFile+16)))
 			{
 				this->m_szFile+=17;
 				this->ParseLV4MeshLong(iNumCVertices);
 			}
 			// Number of regular faces in the mesh
-			else if (0 == strncmp(this->m_szFile,"*MESH_NUMFACES" ,14) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_NUMFACES" ,14) &&
 				IsSpaceOrNewLine(*(this->m_szFile+14)))
 			{
 				this->m_szFile+=15;
 				this->ParseLV4MeshLong(iNumFaces);
 			}
 			// Number of UVWed faces in the mesh
-			else if (0 == strncmp(this->m_szFile,"*MESH_NUMTVFACES" ,16) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_NUMTVFACES" ,16) &&
 				IsSpaceOrNewLine(*(this->m_szFile+16)))
 			{
 				this->m_szFile+=17;
 				this->ParseLV4MeshLong(iNumTFaces);
 			}
 			// Number of colored faces in the mesh
-			else if (0 == strncmp(this->m_szFile,"*MESH_NUMCVFACES" ,16) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_NUMCVFACES" ,16) &&
 				IsSpaceOrNewLine(*(this->m_szFile+16)))
 			{
 				this->m_szFile+=17;
 				this->ParseLV4MeshLong(iNumCFaces);
 			}
 			// mesh vertex list block
-			else if (0 == strncmp(this->m_szFile,"*MESH_VERTEX_LIST" ,17) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_VERTEX_LIST" ,17) &&
 				IsSpaceOrNewLine(*(this->m_szFile+17)))
 			{
 				this->m_szFile+=18;
 				this->ParseLV3MeshVertexListBlock(iNumVertices,mesh);
 			}
 			// mesh face list block
-			else if (0 == strncmp(this->m_szFile,"*MESH_FACE_LIST" ,15) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_FACE_LIST" ,15) &&
 				IsSpaceOrNewLine(*(this->m_szFile+15)))
 			{
 				this->m_szFile+=16;
@@ -869,7 +869,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
 				this->ParseLV3MeshFaceListBlock(iNumFaces,mesh);
 			}
 			// mesh texture vertex list block
-			else if (0 == strncmp(this->m_szFile,"*MESH_TVERTLIST" ,15) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_TVERTLIST" ,15) &&
 				IsSpaceOrNewLine(*(this->m_szFile+15)))
 			{
 				this->m_szFile+=16;
@@ -877,7 +877,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
 				this->ParseLV3MeshTListBlock(iNumTVertices,mesh);
 			}
 			// mesh texture face block
-			else if (0 == strncmp(this->m_szFile,"*MESH_TFACELIST" ,15) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_TFACELIST" ,15) &&
 				IsSpaceOrNewLine(*(this->m_szFile+15)))
 			{
 				this->m_szFile+=16;
@@ -885,7 +885,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
 				this->ParseLV3MeshTFaceListBlock(iNumTFaces,mesh);
 			}
 			// mesh color vertex list block
-			else if (0 == strncmp(this->m_szFile,"*MESH_CVERTLIST" ,15) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_CVERTLIST" ,15) &&
 				IsSpaceOrNewLine(*(this->m_szFile+15)))
 			{
 				this->m_szFile+=16;
@@ -893,7 +893,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
 				this->ParseLV3MeshCListBlock(iNumCVertices,mesh);
 			}
 			// mesh color face block
-			else if (0 == strncmp(this->m_szFile,"*MESH_CFACELIST" ,15) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_CFACELIST" ,15) &&
 				IsSpaceOrNewLine(*(this->m_szFile+15)))
 			{
 				this->m_szFile+=16;
@@ -901,7 +901,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
 				this->ParseLV3MeshCFaceListBlock(iNumCFaces,mesh);
 			}
 			// another mesh UV channel ...
-			else if (0 == strncmp(this->m_szFile,"*MESH_MAPPINGCHANNEL" ,20) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_MAPPINGCHANNEL" ,20) &&
 				IsSpaceOrNewLine(*(this->m_szFile+20)))
 			{
 				this->m_szFile+=21;
@@ -966,7 +966,7 @@ void Parser::ParseLV3MeshVertexListBlock(
 {
 	// allocate enough storage in the array
 	mesh.mPositions.resize(iNumVertices);
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -1013,7 +1013,7 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
 {
 	// allocate enough storage in the face array
 	mesh.mFaces.resize(iNumFaces);
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -1060,7 +1060,7 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
 {
 	// allocate enough storage in the array
 	mesh.amTexCoords[iChannel].resize(iNumVertices);
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -1112,7 +1112,7 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
 void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
 	ASE::Mesh& mesh, unsigned int iChannel)
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -1166,7 +1166,7 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
 	unsigned int iNumTVertices = 0;
 	unsigned int iNumTFaces = 0;
 
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -1179,14 +1179,14 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
 				this->ParseLV4MeshLong(iNumTVertices);
 			}
 			// Number of UVWed faces in the mesh
-			else if (0 == strncmp(this->m_szFile,"*MESH_NUMTVFACES" ,16) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_NUMTVFACES" ,16) &&
 				IsSpaceOrNewLine(*(this->m_szFile+16)))
 			{
 				this->m_szFile+=17;
 				this->ParseLV4MeshLong(iNumTFaces);
 			}
 			// mesh texture vertex list block
-			else if (0 == strncmp(this->m_szFile,"*MESH_TVERTLIST" ,15) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_TVERTLIST" ,15) &&
 				IsSpaceOrNewLine(*(this->m_szFile+15)))
 			{
 				this->m_szFile+=16;
@@ -1194,7 +1194,7 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
 				this->ParseLV3MeshTListBlock(iNumTVertices,mesh,iChannel);
 			}
 			// mesh texture face block
-			else if (0 == strncmp(this->m_szFile,"*MESH_TFACELIST" ,15) &&
+			if (0 == strncmp(this->m_szFile,"*MESH_TFACELIST" ,15) &&
 				IsSpaceOrNewLine(*(this->m_szFile+15)))
 			{
 				this->m_szFile+=16;
@@ -1227,7 +1227,7 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
 {
 	// allocate enough storage in the array
 	mesh.mVertexColors.resize(iNumVertices);
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -1273,7 +1273,7 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
 // ------------------------------------------------------------------------------------------------
 void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
 {
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 	while (true)
 	{
 		if ('*' == *this->m_szFile)
@@ -1326,7 +1326,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
 {
 	// allocate enough storage for the normals
 	sMesh.mNormals.resize(sMesh.mPositions.size());
-	unsigned int iDepth = 1;
+	int iDepth = 0;
 
 	// we need the *MESH_VERTEXNORMAL blocks, ignore the face normals
 	// if there are only face normals we calculate them outselfes using the SGs

+ 3 - 2
code/ASEParser.h

@@ -109,8 +109,6 @@ struct Face : public Dot3DS::Face
 	static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;
 
 
-	//! Indices into the list of vertices
-	unsigned int mIndices[3];
 
 	//! Indices into each list of texture coordinates
 	unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];
@@ -141,6 +139,9 @@ struct Mesh
 		// use 2 texture vertex components by default
 		for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
 			this->mNumUVComponents[c] = 2;
+
+		// setup the default material index by default
+		iMaterialIndex = Face::DEFAULT_MATINDEX;
 	}
 	std::string mName;
 

+ 1 - 0
code/jAssimp/BuildHeader.bat

@@ -5,3 +5,4 @@ javah -classpath ".\..\..\port\jAssimp\classes" -d "." "assimp.Scene"
 javah -classpath ".\..\..\port\jAssimp\classes" -d "." "assimp.Mesh"
 javah -classpath ".\..\..\port\jAssimp\classes" -d "." "assimp.Texture"
 javah -classpath ".\..\..\port\jAssimp\classes" -d "." "assimp.Animation"
+javah -classpath ".\..\..\port\jAssimp\classes" -d "." "assimp.PostProcessStep"

+ 425 - 9
code/jAssimp/JNICalls.cpp

@@ -136,8 +136,6 @@ Assimp::Importer* jGetValidImporterScenePair (JASSIMP_CONTEXT jvmcontext)
 JNIEXPORT jlong JNICALL Java_assimp_Importer__1NativeInitContext
   (JNIEnv * jvmenv, jobject jvmthis)
 {
-	ai_assert(NULL != jvmenv && NULL != jvmthis);
-
 	// 2^64-1 indicates error
 	JASSIMP_CONTEXT context = 0xffffffffffffffffL;
 
@@ -159,7 +157,6 @@ JNIEXPORT jlong JNICALL Java_assimp_Importer__1NativeInitContext
 JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeFreeContext
   (JNIEnv * jvmenv, jobject jvmthis, jlong jvmcontext)
 {
-	ai_assert(NULL != jvmenv && NULL != jvmthis);
 
 #if (defined _DEBUG)
 	if (!jValidateContext((JASSIMP_CONTEXT)jvmcontext))return AI_JNI_ERROR_RETURN;
@@ -183,7 +180,6 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeFreeContext
 JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
   (JNIEnv *jvmenv, jobject jvmthis, jstring jvmpath, jint jvmflags, jlong jvmcontext)
 {
-	ai_assert(NULL != jvmenv && NULL != jvmthis);
 	jint iRet = 0;
 
 #if (defined _DEBUG)
@@ -214,6 +210,31 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
 	jvmenv->ReleaseStringUTFChars(jvmpath,szPath);
 	return iRet;
 }
+
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_PostProcessStep
+ * Method:    _NativeSetVertexSplitLimit
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_assimp_PostProcessStep__1NativeSetVertexSplitLimit
+  (JNIEnv *jvmenv, jclass jvmthis, jint jvmlimit)
+{
+	aiSetVertexSplitLimit(jvmlimit);
+}
+
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_PostProcessStep
+ * Method:    _NativeSetTriangleSplitLimit
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_assimp_PostProcessStep__1NativeSetTriangleSplitLimit
+  (JNIEnv *jvmenv, jclass jvmthis, jint jvmlimit)
+{
+	aiSetTriangleSplitLimit(jvmlimit);
+}
+
 // ------------------------------------------------------------------------------------------------
 /*
  * Class:     assimp_Scene
@@ -223,7 +244,6 @@ JNIEXPORT jint JNICALL Java_assimp_Importer__1NativeLoad
 JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumMeshes
   (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext)
 {
-	ai_assert(NULL != jvmenv && NULL != jvmthis);
 	// we need a valid scene for this
 	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
 	if (!pcImp)return AI_JNI_ERROR_RETURN;
@@ -238,8 +258,6 @@ JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumMeshes
 JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumAnimations
   (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext)
 {
-	
-	ai_assert(NULL != jvmenv && NULL != jvmthis);
 	// we need a valid scene for this
 	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
 	if (!pcImp)return AI_JNI_ERROR_RETURN;
@@ -254,7 +272,6 @@ JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumAnimations
 JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumTextures
   (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext)
 {
-	ai_assert(NULL != jvmenv && NULL != jvmthis);
 	// we need a valid scene for this
 	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
 	if (!pcImp)return AI_JNI_ERROR_RETURN;
@@ -269,12 +286,411 @@ JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumTextures
 JNIEXPORT jint JNICALL Java_assimp_Scene__1NativeGetNumMaterials
   (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext)
 {
-	ai_assert(NULL != jvmenv && NULL != jvmthis);
 	// we need a valid scene for this
 	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
 	if (!pcImp)return AI_JNI_ERROR_RETURN;
 	return (jint)pcImp->GetScene()->mNumMaterials;
 }
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetPresenceFlags
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetPresenceFlags
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	aiMesh* pcMesh = pcImp->GetScene()->mMeshes[jvmindex];
+
+	// now build the flag list
+	jint iRet = 0;
+	if (pcMesh->HasPositions())
+		iRet |= assimp_Mesh_PF_POSITION;
+	if (pcMesh->HasBones())
+		iRet |= assimp_Mesh_PF_BONES;
+	if (pcMesh->HasNormals())
+		iRet |= assimp_Mesh_PF_NORMAL;
+	if (pcMesh->HasTangentsAndBitangents())
+		iRet |= assimp_Mesh_PF_TANGENTBITANGENT;
+
+	unsigned int i = 0;
+	while (pcMesh->HasTextureCoords(i))
+		iRet |= assimp_Mesh_PF_UVCOORD << i++;
+	i = 0;
+	while (pcMesh->HasVertexColors(i))
+		iRet |= assimp_Mesh_PF_VERTEXCOLOR << i++;
+
+	return iRet;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetNumVertices
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumVertices
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	return pcImp->GetScene()->mMeshes[jvmindex]->mNumVertices;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetNumFaces
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumFaces
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	return pcImp->GetScene()->mMeshes[jvmindex]->mNumFaces;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetNumBones
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumBones
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	return pcImp->GetScene()->mMeshes[jvmindex]->mNumBones;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetMaterialIndex
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetMaterialIndex
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	return pcImp->GetScene()->mMeshes[jvmindex]->mMaterialIndex;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetNumUVComponents
+ * Signature: (JJ[I)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumUVComponents
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jintArray jvmout)
+{
+	ai_assert(AI_MAX_NUMBER_OF_TEXTURECOORDS == jvmenv->GetArrayLength(jvmout) );
+
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	const unsigned int* piArray = pcImp->GetScene()->mMeshes[jvmindex]->mNumUVComponents;
+
+	jint* pArray = jvmenv->GetIntArrayElements(jvmout,NULL);
+	if (NULL == pArray)return AI_JNI_ERROR_RETURN;
+
+	for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
+		pArray[i] = piArray[i];
+
+	jvmenv->ReleaseIntArrayElements(jvmout,pArray,0);
+	return 0;
+}
+// ------------------------------------------------------------------------------------------------
+void CpyVectorToFloatArray(jfloat* pDest, const aiVector3D* pSource, unsigned int iNum)
+{
+	jfloat* pCursor = pDest;
+	const aiVector3D* const pvEnd = pSource + iNum;
+	while (pvEnd != pSource)
+	{
+		*pCursor++ = pSource->x;
+		*pCursor++ = pSource->y;
+		*pCursor++ = pSource->z;
+		++pSource;
+	}
+	return;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapVertices
+ * Signature: (JJ[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapVertices
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jfloatArray jvmout)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	aiMesh* pcMesh =  (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
+	ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices * 3);
+	const aiVector3D* pcData = pcMesh->mVertices;
+
+	// now copy the data to the java array
+	jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
+	CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
+	jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
+
+	// delete the original data
+	delete[] pcMesh->mVertices;
+	pcMesh->mVertices = NULL;
+	return 0;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapNormals
+ * Signature: (JJ[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapNormals
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jfloatArray jvmout)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	aiMesh* pcMesh =  (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
+	ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices * 3);
+	const aiVector3D* pcData = pcMesh->mNormals;
+
+	// now copy the data to the java array
+	jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
+	CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
+	jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
+
+	// delete the original data
+	delete[] pcMesh->mNormals;
+	pcMesh->mNormals = NULL;
+	return 0;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapTangents
+ * Signature: (JJ[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapTangents
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jfloatArray jvmout)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	aiMesh* pcMesh =  (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
+	ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices * 3);
+	const aiVector3D* pcData = pcMesh->mTangents;
+
+	// now copy the data to the java array
+	jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
+	CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
+	jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
+
+	// delete the original data
+	delete[] pcMesh->mNormals;
+	pcMesh->mNormals = NULL;
+	return 0;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapBitangents
+ * Signature: (JJ[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapBitangents
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jfloatArray jvmout)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	aiMesh* pcMesh =  (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
+	ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices * 3);
+	const aiVector3D* pcData = pcMesh->mBitangents;
+
+	// now copy the data to the java array
+	jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
+	CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
+	jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
+
+	// delete the original data
+	delete[] pcMesh->mBitangents;
+	pcMesh->mBitangents = NULL;
+	return 0;
+}
+// ------------------------------------------------------------------------------------------------
+void CpyColorToFloatArray(jfloat* pDest, const aiColor4D* pSource, unsigned int iNum)
+{
+	jfloat* pCursor = pDest;
+	const aiColor4D* const pvEnd = pSource + iNum;
+	while (pvEnd != pSource)
+	{
+		*pCursor++ = pSource->r;
+		*pCursor++ = pSource->g;
+		*pCursor++ = pSource->b;
+		*pCursor++ = pSource->a;
+		++pSource;
+	}
+	return;
+}
+// ------------------------------------------------------------------------------------------------
+void CpyVectorToFloatArray(jfloat* pDest, const aiVector3D* pSource,
+						   unsigned int iNum, unsigned int iNumComponents)
+{
+	jfloat* pCursor = pDest;
+	const aiVector3D* const pvEnd = pSource + iNum;
+	while (pvEnd != pSource)
+	{
+		if (iNumComponents >= 1)*pCursor++ = pSource->x;
+		if (iNumComponents >= 2)*pCursor++ = pSource->y;
+		if (iNumComponents >= 3)*pCursor++ = pSource->z;
+		++pSource;
+	}
+	return;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapUVs
+ * Signature: (JJI[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapUVs
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex,
+  jint jvmchannel, jfloatArray jvmout)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	aiMesh* pcMesh =  (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
+	ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices*pcMesh->mNumUVComponents[jvmchannel]);
+	const aiVector3D* pcData = pcMesh->mTextureCoords[jvmchannel];
+
+	// now copy the data to the java array
+	jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
+	CpyVectorToFloatArray(pArray,pcData,pcMesh->mNumVertices,pcMesh->mNumUVComponents[jvmchannel]);
+	jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
+
+	// delete the original data
+	delete[] pcMesh->mTextureCoords[jvmchannel];
+	pcMesh->mTextureCoords[jvmchannel] = NULL;
+	return 0;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapColors
+ * Signature: (JJI[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapColors
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, 
+  jint jvmchannel, jfloatArray jvmout)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	aiMesh* pcMesh =  (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
+	ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumVertices*4);
+	const aiColor4D* pcData = pcMesh->mColors[jvmchannel];
+
+	// now copy the data to the java array
+	jfloat* pArray = jvmenv->GetFloatArrayElements(jvmout,NULL);
+	CpyColorToFloatArray(pArray,pcData,pcMesh->mNumVertices);
+	jvmenv->ReleaseFloatArrayElements(jvmout,pArray,0);
+
+	// delete the original data
+	delete[] pcMesh->mColors[jvmchannel];
+	pcMesh->mColors[jvmchannel] = NULL;
+	return 0;
+}
+// ------------------------------------------------------------------------------------------------
+void CpyFacesToIntArray(jint* pDest, const aiFace* pSource, unsigned int iNum)
+{
+	// assume that all faces are triangles
+	jint* pCursor = pDest;
+	const aiFace* const pvEnd = pSource + iNum;
+	while (pvEnd != pSource)
+	{
+		*pCursor++ = pSource->mIndices[0];
+		*pCursor++ = pSource->mIndices[1];
+		*pCursor++ = pSource->mIndices[2];
+		++pSource;
+	}
+	return;
+}
+// ------------------------------------------------------------------------------------------------
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapFaces
+ * Signature: (JJ[I)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapFaces
+  (JNIEnv *jvmenv, jobject jvmthis, jlong jvmcontext, jlong jvmindex, jintArray jvmout)
+{
+	// we need a valid scene for this
+	Assimp::Importer* pcImp = jGetValidImporterScenePair(jvmcontext);
+	if (!pcImp)return AI_JNI_ERROR_RETURN;
+
+	// get the corresponding mesh
+	ai_assert(jvmindex < pcImp->GetScene()->mNumMeshes);
+	aiMesh* pcMesh =  (aiMesh*)pcImp->GetScene()->mMeshes[jvmindex];
+	ai_assert(jvmenv->GetArrayLength(jvmout) == pcMesh->mNumFaces*3);
+	const aiFace* pcData = pcMesh->mFaces;
+
+	// now copy the data to the java array
+	jint* pArray = jvmenv->GetIntArrayElements(jvmout,NULL);
+	CpyFacesToIntArray(pArray,pcData,pcMesh->mNumFaces);
+	jvmenv->ReleaseIntArrayElements(jvmout,pArray,0);
+
+	// delete the original data
+	for (unsigned int i = 0; i < pcMesh->mNumFaces;++i)
+		delete[] pcMesh->mFaces[i].mIndices;
+	delete[] pcMesh->mFaces;
+	pcMesh->mFaces = NULL;
+	return 0;
+}
+
 
 }; //! namespace JNIBridge
 }; //! namespace Assimp

+ 116 - 0
code/jAssimp/assimp_Mesh.h

@@ -11,6 +11,122 @@ extern "C" {
 #define assimp_Mesh_MAX_NUMBER_OF_TEXTURECOORDS 4L
 #undef assimp_Mesh_MAX_NUMBER_OF_COLOR_SETS
 #define assimp_Mesh_MAX_NUMBER_OF_COLOR_SETS 4L
+#undef assimp_Mesh_PF_POSITION
+#define assimp_Mesh_PF_POSITION 1L
+#undef assimp_Mesh_PF_NORMAL
+#define assimp_Mesh_PF_NORMAL 2L
+#undef assimp_Mesh_PF_TANGENTBITANGENT
+#define assimp_Mesh_PF_TANGENTBITANGENT 4L
+#undef assimp_Mesh_PF_BONES
+#define assimp_Mesh_PF_BONES 8L
+#undef assimp_Mesh_PF_VERTEXCOLOR
+#define assimp_Mesh_PF_VERTEXCOLOR 4096L
+#undef assimp_Mesh_PF_UVCOORD
+#define assimp_Mesh_PF_UVCOORD 65536L
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetPresenceFlags
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetPresenceFlags
+  (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetNumVertices
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumVertices
+  (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetNumFaces
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumFaces
+  (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetNumBones
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumBones
+  (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetMaterialIndex
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetMaterialIndex
+  (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeGetNumUVComponents
+ * Signature: (JJ[I)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeGetNumUVComponents
+  (JNIEnv *, jobject, jlong, jlong, jintArray);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapVertices
+ * Signature: (JJ[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapVertices
+  (JNIEnv *, jobject, jlong, jlong, jfloatArray);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapNormals
+ * Signature: (JJ[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapNormals
+  (JNIEnv *, jobject, jlong, jlong, jfloatArray);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapTangents
+ * Signature: (JJ[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapTangents
+  (JNIEnv *, jobject, jlong, jlong, jfloatArray);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapBitangents
+ * Signature: (JJ[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapBitangents
+  (JNIEnv *, jobject, jlong, jlong, jfloatArray);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapUVs
+ * Signature: (JJI[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapUVs
+  (JNIEnv *, jobject, jlong, jlong, jint, jfloatArray);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapColors
+ * Signature: (JJI[F)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapColors
+  (JNIEnv *, jobject, jlong, jlong, jint, jfloatArray);
+
+/*
+ * Class:     assimp_Mesh
+ * Method:    _NativeMapFaces
+ * Signature: (JJ[I)I
+ */
+JNIEXPORT jint JNICALL Java_assimp_Mesh__1NativeMapFaces
+  (JNIEnv *, jobject, jlong, jlong, jintArray);
+
 #ifdef __cplusplus
 }
 #endif

+ 33 - 0
code/jAssimp/assimp_PostProcessStep.h

@@ -0,0 +1,33 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class assimp_PostProcessStep */
+
+#ifndef _Included_assimp_PostProcessStep
+#define _Included_assimp_PostProcessStep
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef assimp_PostProcessStep_DEFAULT_VERTEX_SPLIT_LIMIT
+#define assimp_PostProcessStep_DEFAULT_VERTEX_SPLIT_LIMIT 1000000L
+#undef assimp_PostProcessStep_DEFAULT_TRIANGLE_SPLIT_LIMIT
+#define assimp_PostProcessStep_DEFAULT_TRIANGLE_SPLIT_LIMIT 1000000L
+/*
+ * Class:     assimp_PostProcessStep
+ * Method:    _NativeSetVertexSplitLimit
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_assimp_PostProcessStep__1NativeSetVertexSplitLimit
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     assimp_PostProcessStep
+ * Method:    _NativeSetTriangleSplitLimit
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_assimp_PostProcessStep__1NativeSetTriangleSplitLimit
+  (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 10 - 2
code/jAssimp/assimp_Texture.h

@@ -10,10 +10,18 @@ extern "C" {
 /*
  * Class:     assimp_Texture
  * Method:    _NativeMapColorData
- * Signature: ([B)I
+ * Signature: (JJ[B)I
  */
 JNIEXPORT jint JNICALL Java_assimp_Texture__1NativeMapColorData
-  (JNIEnv *, jobject, jbyteArray);
+  (JNIEnv *, jobject, jlong, jlong, jbyteArray);
+
+/*
+ * Class:     assimp_Texture
+ * Method:    _NativeGetTextureInfo
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_assimp_Texture__1NativeGetTextureInfo
+  (JNIEnv *, jobject, jlong, jlong);
 
 #ifdef __cplusplus
 }

+ 121 - 4
doc/dox.h

@@ -10,9 +10,45 @@ storing it in a engine-specific format for easy and fast every-day-loading. ASSI
 processing steps to the imported data such as conversion to indexed meshes, calculation of normals or tangents/bitangents
 or conversion from right-handed to left-handed coordinate systems.
 
-At the moment ASSIMP is able to read Lightwave Object files (.obj), Milkshape3D scene (.ms3d), DirectX scenes (.x), 
-old 3D Studio Max scene files (.3ds), Doom/Quake model files (.md1 to .md7), 3D Game Studio models (.mdl) and 
-PLY files (.ply). ASSIMP is independent of the Operating System by nature, providing a C++ interface for easy integration 
+ASSIMP is able to import the following file formats into your application:
+
+<b>AutoDesk 3D Studio 4/5 (.3ds).</b> The old native format of 3DS max, now still supported and
+widely used.
+<br>
+<b>AutoDesk 3D Studio ASCII Export (.ase).</b> Text format used by 3DS max. Supports bone animations
+and highly complex materials.
+<br>
+<b>DirectX (.x)</b> A file format that can easily be read by D3DX and that is supported 
+as export format by most 3D modellers. ASSIMP supports both binary and ASCII X-Files.
+<br>
+<b>Stanford Polygon (.ply)</b> File format developed by the university of
+stanford. Thanks to its flexibility it often used for scientific purposes. Supported by ASSIMP
+are ASCII and binary PLY files, both LittleEndian and BigEndian.
+<br>
+<b>WaveFront Object (.obj)</b> File format that is widely used to exchange asset data
+between different applications.
+<br>
+<b>Milkshape 3D (.ms3d)</b> Native file format of the well-known modeller Milkshape 3D. 
+ASSIMP provides full support for bone animations contained in ms3d files.
+<br>
+<b>Quake I (.mdl)</b> The file format that was once used by the first part of the
+quake series. ASSIMP provides full support for loading embedded textures from Quake models.
+<br>
+<b>3D GameStudio (.mdl)</b> The file format of Conitecs 3D GameStudio tool suite.
+Used by the freeware modelling tool MED. ASSIMP provides full support for all types of
+3D GameStudio MDL files: <i>MDL3, MDL4, MDL5, MDL6, MDL7</i>. Bone animations are supported.
+<br>
+<b>Half-Life/CS:S (.mdl, .smd)</b> The file formats used in half life.
+<b>Quake II (.md2)/ Quake III (.md3)</b> Used by many free models on the web, support for
+Quake 2's and Quake 3's file formats is a must-have for each game engine. Quake 4 is
+existing but not widely used. However, it is supported by ASSIMP (and RavenSoft .mdr is supported, too)
+<br>
+<b>Doom 3 (.md5)</b> The well-known native file format of the Doom 3 engine, used in
+many games. Supports bone animation and advanced material settings.
+
+
+
+ASSIMP is independent of the Operating System by nature, providing a C++ interface for easy integration 
 with game engines and a C interface to allow bindings to other programming languages. At the moment the library runs 
 on any little-endian platform including X86/Windows/Linux/Mac and X64/Windows/Linux/Mac. Big endian systems such as 
 PPC-Macs or PPC-Linux systems are not supported at the moment, but this might change later on. Special attention 
@@ -443,7 +479,8 @@ properties are defined. In this file there are also various functions defined to
 presence of certain properties in a material and retrieve their values.
 
 Example to convert from an Assimp material to a Direct3D 9 material for use with the fixed 
-function pipeline. Textures are not handled, only colors and the specular power:
+function pipeline. Textures are not handled, only colors and the specular power, sometimes
+also refered to as "shininess":
 @code
 
 void ConvertColor ( const aiColor4D& clrIn, D3DCOLORVALUE& clrOut )
@@ -484,6 +521,86 @@ void ConvertMaterial( aiMaterial* matIn, D3DMATERIAL9* matOut )
 }
 @endcode
 
+Textures:
+
+Textures can have various types and purposes. Sometimes ASSIMP is not able to
+determine the exact purpose of a texture. Normally it will assume diffuse as default
+purpose. Possible purposes for a texture:
+
+<b>1. Diffuse textures.</b> Diffuse textures are combined with the result of the diffuse lighting term.
+<br>
+<b>2. Specular textures.</b> Specular textures are combined with the result of the specular lighting term.
+Generally speaking, they can be used to map a texture onto specular highlights.
+<br>
+<b>3. Ambient textures.</b> Ambient textures are combined with the result of the ambient lighting term. 
+<br>
+<b>4. Emissive textures.</b> Emissive textures are combined with the emissive base color of the material. 
+The result is then added to the final pixel color. Emissive textures are sometimes called
+"Self ilumination maps".
+<br>
+<b>5. Opacity textures.</b> Opacity textures specify the opacity of a texel. They are 
+normally grayscale images, black stands for fully transparent, white for fully opaque.
+<br>
+<b>6. Height maps.</b> Height maps specify the relative height of a point on a triangle on a
+per-texel base. Normally height maps (sometimes called "Bump maps") are converted to normal
+maps before rendering. Height maps are normally grayscale textures. Height maps could also
+be used as displacement maps on a highly tesselated surface.
+<br>
+<b>7. Normal maps.</b> Normal maps contain normal vectors for a single texel, in tangent space.
+They are not bound to an object. However, all lighting omputations must be done in tangent space. 
+There are many resources on Normal Mapping on the internet.
+<br>
+<b>8. Shininess maps</b> Shininess maps (sometimes called "Gloss" or "SpecularMap") specify
+the shininess of a texel mapped on a surface. They are normally used together with normal maps
+to make flat surfaces look as if they were real 3d objects.
+<br>
+
+Textures are generally defined by a set of parameters, including
+<br>
+<b>1. The path to the texture.</b>  This property is always set. If it is not set, a texture 
+is not existing. This can either be a valid path (beware, sometimes
+it could be a 8.3 file name!) or an asterisk (*) suceeded by a zero-based index, the latter being
+a reference to an embedded texture (@link textures more details @endlink). I suggest using code
+like this to find out whether a texture is embedded:
+@code
+aiString path; // contains the path obtained via aiGetMaterialString()
+const aiScene* scene; // valid aiScene instance
+
+const char* szData = path.data;
+if ('*' == *szData)
+{
+   int index = atoi(szData+1);
+   ai_assert(index < scene->mNumTextures);
+
+   // your loading code for loading from aiTexture's ...
+}
+else // your loading code to load from a path ...
+@endcode
+<br>
+<b>2. An UV coordinate index.</b> This is an index into the UV coordinate set list of the
+corresponding mesh. Note: Some formats don't define this, so beware, it could be that
+a second diffuse texture in a mesh was originally intended to use a second UV channel although
+ASSIMP states it uses the first one. UV coordinate source indices are defined by the
+<i>AI_MATKEY_UVWSRC_<textype>(<texindex>)</i> material property. Assume 0 as default value if
+this property is not set.
+<br>
+<b>3. A blend factor.</b> This is used if multiple textures are assigned to a slot, e.g. two
+or more textures on the diffuse channel. A texture's color value is multiplied with its
+blend factor before it is combined with the previous color value (from the last texture) using
+a specific blend operation (see 4.). Blend factor are defined by the
+<i>AI_MATKEY_TEXBLEND_<textype>(<texindex>)</i> material property. Assume 1.0f as default value 
+if this property is not set.
+<br>
+<b>4. A blend operation.</b> This is used if multiple textures are assigned to a slot, e.g. two
+or more textures on the diffuse channel. After a texture's color value has been multiplied
+with its blend factor, the blend operation is used to combine it with the previous color value.
+Blend operations are stored as integer property, however their type is aiTextureOp.
+Blend factor are defined by the <i>AI_TEXOP_BLEND_<textype>(<texindex>)</i> material property. Assume
+aiTextureOp_Multiply as default value if this property is not set. The blend operation for
+the first texture in a texture slot (e.g. diffuse 0) specifies how the diffuse base color/
+vertex color have to be combined with the texture color value.
+<br>
+
 @section bones Bones
 
 A mesh may have a set of bones in the form of aiBone structures.. Bones are a means to deform a mesh 

+ 4 - 0
include/aiMatrix4x4.h

@@ -53,6 +53,10 @@ struct aiMatrix4x4
 
 	float* operator[](unsigned int p_iIndex);
 	const float* operator[](unsigned int p_iIndex) const;
+
+	inline bool operator== (const aiMatrix4x4 m) const;
+	inline bool operator!= (const aiMatrix4x4 m) const;
+
 #endif // __cplusplus
 
 	float a1, a2, a3, a4;

+ 13 - 0
include/aiMatrix4x4.inl

@@ -131,6 +131,19 @@ inline const float* aiMatrix4x4::operator[](unsigned int p_iIndex) const
 {
 	return &this->a1 + p_iIndex * 4;
 }
+// ---------------------------------------------------------------------------
+inline bool aiMatrix4x4::operator== (const aiMatrix4x4 m) const
+{
+	return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
+		b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
+		c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
+		d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4);
+}
+// ---------------------------------------------------------------------------
+inline bool aiMatrix4x4::operator!= (const aiMatrix4x4 m) const
+{
+	return !(*this == m);
+}
 
 #endif // __cplusplus
 #endif // AI_MATRIX4x4_INL_INC

+ 6 - 1
port/jAssimp/assimp.iml

@@ -1,7 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module version="4" relativePaths="true" type="JAVA_MODULE">
   <component name="BuildJarSettings">
-    <containerInfo />
+    <containerInfo>
+      <containerElement type="module" name="assimp">
+        <attribute name="method" value="1" />
+        <attribute name="URI" value="/" />
+      </containerElement>
+    </containerInfo>
     <setting name="jarPath" value="J:\Programmieren\ASSIMP\assimp2\port\jAssimp\assimp.jar" />
     <setting name="buildJar" value="true" />
     <setting name="mainClass" value="" />

+ 1 - 2
port/jAssimp/src/assimp/Importer.java

@@ -202,13 +202,12 @@ public class Importer {
         // need to build a list of postprocess step as bitflag combination
         // Of course, this could have been implemented directly. However,
         // I've used the PostProcessStep enumeration to make debugging easier.
-        int flags = 0;
+        int flags = 0x8; // always apply the triangulation step
 
         for (PostProcessStep step : m_vPPSteps) {
             if (step.equals(PostProcessStep.CalcTangentSpace)) flags |= 0x1;
             else if (step.equals(PostProcessStep.JoinIdenticalVertices)) flags |= 0x2;
             else if (step.equals(PostProcessStep.ConvertToLeftHanded)) flags |= 0x4;
-            else if (step.equals(PostProcessStep.Triangulate)) flags |= 0x8;
             else if (step.equals(PostProcessStep.KillNormals)) flags |= 0x10;
             else if (step.equals(PostProcessStep.GenFaceNormals)) flags |= 0x20;
             else if (step.equals(PostProcessStep.GenSmoothNormals)) flags |= 0x40;

+ 336 - 21
port/jAssimp/src/assimp/Mesh.java

@@ -42,6 +42,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 package assimp;
 
+import java.lang.ref.Reference;
+import java.awt.*;
+
 
 /**
  * A mesh represents a geometry or model with a single material.
@@ -86,6 +89,7 @@ public class Mesh extends IMappable {
     private static final int PF_POSITION = 0x1;
     private static final int PF_NORMAL = 0x2;
     private static final int PF_TANGENTBITANGENT = 0x4;
+    private static final int PF_BONES = 0x8;
     private static final int PF_VERTEXCOLOR = 0x1000;
     private static final int PF_UVCOORD = 0x10000;
 
@@ -141,11 +145,32 @@ public class Mesh extends IMappable {
      */
     private float[][] m_avColors = new float[MAX_NUMBER_OF_COLOR_SETS][];
 
+    /**
+     * Contains a list of all faces of the mesh. each face consists of
+     * three indices into the vertex buffer.
+     */
+    private int[] m_vFaces = null;
+
     /**
      * Number of vertices in the mesh
      */
     private int m_iNumVertices;
 
+    /**
+     * Number of faces in the mesh
+     */
+    private int m_iNumFaces;
+
+    /**
+     * Number of bones in the mesh
+     */
+    private int m_iNumBones;
+
+    /**
+     * Material index of the mesh
+     */
+    private int m_iMaterialIndex;
+
 
     /**
      * Construction from a given parent object and array index
@@ -160,15 +185,27 @@ public class Mesh extends IMappable {
 
         Scene sc = (Scene) parent;
         if (0xffffffff == (this.m_iPresentFlags = this._NativeGetPresenceFlags(
-                sc.getImporter().getContext()))) {
+                sc.getImporter().getContext(), this.getArrayIndex()))) {
             throw new NativeError("Unable to obtain a list of vertex presence flags");
         }
         if (0xffffffff == (this.m_iNumVertices = this._NativeGetNumVertices(
-                sc.getImporter().getContext()))) {
+                sc.getImporter().getContext(), this.getArrayIndex()))) {
             throw new NativeError("Unable to obtain the number of vertices in the mesh");
         }
+        if (0xffffffff == (this.m_iNumFaces = this._NativeGetNumFaces(
+                sc.getImporter().getContext(), this.getArrayIndex()))) {
+            throw new NativeError("Unable to obtain the number of faces in the mesh");
+        }
+        if (0xffffffff == (this.m_iNumBones = this._NativeGetNumBones(
+                sc.getImporter().getContext(), this.getArrayIndex()))) {
+            throw new NativeError("Unable to obtain the number of bones in the mesh");
+        }
+        if (0xffffffff == (this.m_iMaterialIndex = this._NativeGetMaterialIndex(
+                sc.getImporter().getContext(), this.getArrayIndex()))) {
+            throw new NativeError("Unable to obtain the material index of the mesh");
+        }
         if (0xffffffff == this._NativeGetNumUVComponents(
-                sc.getImporter().getContext(), this.m_aiNumUVComponents)) {
+                sc.getImporter().getContext(), this.getArrayIndex(), this.m_aiNumUVComponents)) {
             throw new NativeError("Unable to obtain the number of UV components");
         }
     }
@@ -193,6 +230,16 @@ public class Mesh extends IMappable {
         return 0 != (this.m_iPresentFlags & PF_NORMAL);
     }
 
+    /**
+     * Check whether there are bones in the model
+     * <code>getBone()</code> will assert this.
+     *
+     * @return true if vertex normals are available.
+     */
+    public boolean hasBones() {
+        return 0 != (this.m_iPresentFlags & PF_BONES);
+    }
+
     /**
      * Check whether there are tangents/bitangents in the model
      * <code>getTangent()</code> and <code>GetBitangent()</code> will assert this.
@@ -229,13 +276,42 @@ public class Mesh extends IMappable {
     /**
      * Get the number of vertices in the model
      *
-     * @return Number of vertices in the asset. This could be 0 in some
+     * @return Number of vertices in the model. This could be 0 in some
      *         extreme cases although loaders should filter such cases out
      */
     public int getNumVertices() {
         return m_iNumVertices;
     }
 
+
+    /**
+     * Get the number of faces in the model
+     *
+     * @return Number of faces in the model. This could be 0 in some
+     *         extreme cases although loaders should filter such cases out
+     */
+    public int getNumFaces() {
+        return m_iNumFaces;
+    }
+
+    /**
+     * Get the number of bones in the model
+     *
+     * @return Number of bones in the model.
+     */
+    public int getNumBones() {
+        return m_iNumBones;
+    }
+
+    /**
+     * Get the material index of the mesh
+     *
+     * @return Zero-based material index
+     */
+    public int getMaterialIndex() {
+        return m_iMaterialIndex;
+    }
+
     /**
      * Get a vertex position in the mesh
      *
@@ -456,14 +532,15 @@ public class Mesh extends IMappable {
         return this.m_vBitangents;
     }
 
+
     /**
      * Get a vertex texture coordinate in the mesh
      *
      * @param channel Texture coordinate channel
      * @param iIndex  Zero-based index of the vertex
      * @param afOut   Output array, size must at least be equal to the value
-     * <code>getNumUVComponents</code> returns for <code>channel</code>
-     * Receives the vertex texture coordinate, components are in u,v,w order
+     *                <code>getNumUVComponents</code> returns for <code>channel</code>
+     *                Receives the vertex texture coordinate, components are in u,v,w order
      */
     public void getTexCoord(int channel, int iIndex, float[] afOut) {
         assert(this.hasUVCoords(channel));
@@ -473,19 +550,19 @@ public class Mesh extends IMappable {
         if (null == this.m_avUVs[channel]) this.mapUVs(channel);
 
         iIndex *= this.m_aiNumUVComponents[channel];
-        for (int i = 0; i < this.m_aiNumUVComponents[channel];++i) {
-            afOut[i] = this.m_avUVs[channel][iIndex+i];
+        for (int i = 0; i < this.m_aiNumUVComponents[channel]; ++i) {
+            afOut[i] = this.m_avUVs[channel][iIndex + i];
         }
     }
 
     /**
      * Get a vertex texture coordinate in the mesh
      *
-     * @param channel Texture coordinate channel
-     * @param iIndex  Zero-based index of the vertex
-     * @param afOut   Output array, size must at least be equal to the value
-     * <code>getNumUVComponents</code> returns for <code>channel</code>
-     * Receives the vertex texture coordinate, components are in u,v,w order
+     * @param channel  Texture coordinate channel
+     * @param iIndex   Zero-based index of the vertex
+     * @param afOut    Output array, size must at least be equal to the value
+     *                 <code>getNumUVComponents</code> returns for <code>channel</code>
+     *                 Receives the vertex texture coordinate, components are in u,v,w order
      * @param iOutBase Start index in the output array
      */
     public void getTexCoord(int channel, int iIndex, float[] afOut, int iOutBase) {
@@ -497,8 +574,8 @@ public class Mesh extends IMappable {
         if (null == this.m_avUVs[channel]) this.mapUVs(channel);
 
         iIndex *= this.m_aiNumUVComponents[channel];
-        for (int i = 0; i < this.m_aiNumUVComponents[channel];++i) {
-            afOut[i+iOutBase] = this.m_avUVs[channel][iIndex+i];
+        for (int i = 0; i < this.m_aiNumUVComponents[channel]; ++i) {
+            afOut[i + iOutBase] = this.m_avUVs[channel][iIndex + i];
         }
     }
 
@@ -507,7 +584,7 @@ public class Mesh extends IMappable {
      * This is the recommended way of accessing the data.
      *
      * @return Array of floats, size is numverts * <code>getNumUVComponents
-     * (channel)</code>. Component ordering is uvw.
+     *         (channel)</code>. Component ordering is uvw.
      */
     public float[] getTexCoordArray(int channel) {
         assert(this.hasUVCoords(channel));
@@ -515,11 +592,221 @@ public class Mesh extends IMappable {
         return this.m_avUVs[channel];
     }
 
+    /**
+     * Get a vertex color in the mesh
+     *
+     * @param channel Vertex color channel
+     * @param iIndex  Zero-based index of the vertex
+     * @param afOut   Output array, size must at least be 4
+     *                Receives the vertex color components in r,g,b,a order
+     */
+    public void getVertexColor(int channel, int iIndex, float[] afOut) {
+        assert(this.hasVertexColors(channel));
+        assert(afOut.length >= 4);
+        assert(iIndex < this.getNumVertices()); // explicitly assert here, no AIOOBE
+
+        if (null == this.m_avColors[channel]) this.mapColors(channel);
+
+        iIndex *= 4;   // RGBA order
+        afOut[0] = this.m_avColors[channel][iIndex];
+        afOut[1] = this.m_avColors[channel][iIndex + 1];
+        afOut[2] = this.m_avColors[channel][iIndex + 2];
+        afOut[3] = this.m_avColors[channel][iIndex + 3];
+    }
+
+    /**
+     * Get a vertex color as <code>java.awt.Color</code> in the mesh
+     *
+     * @param channel Vertex color channel
+     * @param iIndex  Zero-based index of the vertex
+     * @return Vertex color value packed as <code>java.awt.Color</code>
+     */
+    public Color getVertexColor(int channel, int iIndex) {
+
+        float[] afColor = new float[4];
+        this.getVertexColor(channel, iIndex, afColor);
+        return new Color(afColor[0], afColor[1], afColor[2], afColor[3]);
+    }
+
+    /**
+     * Get a vertex color in the mesh
+     *
+     * @param channel  Vertex color channel
+     * @param iIndex   Zero-based index of the vertex
+     * @param afOut    Output array, size must at least be 4
+     *                 Receives the vertex color components in r,g,b,a order
+     * @param iOutBase Start index in the output array
+     */
+    public void getVertexColor(int channel, int iIndex, float[] afOut, int iOutBase) {
+        assert(this.hasVertexColors(channel));
+        assert(afOut.length >= 4);
+        assert(iOutBase + 4 <= afOut.length);
+        assert(iIndex < this.getNumVertices()); // explicitly assert here, no AIOOBE
+
+        if (null == this.m_avColors[channel]) this.mapColors(channel);
+
+        iIndex *= 4;   // RGBA order
+        afOut[iOutBase] = this.m_avColors[channel][iIndex];
+        afOut[iOutBase + 1] = this.m_avColors[channel][iIndex + 1];
+        afOut[iOutBase + 2] = this.m_avColors[channel][iIndex + 2];
+        afOut[iOutBase + 3] = this.m_avColors[channel][iIndex + 3];
+    }
+
+    /**
+     * Provides direct access to the vertex bitangent array of the mesh
+     * This is the recommended way of accessing the data.
+     *
+     * @return Array of floats, size is numverts * 3. Component ordering
+     *         is xyz.
+     */
+    public float[] getVertexColorArray(int channel) {
+        assert(this.hasVertexColors(channel));
+        if (null == this.m_avColors[channel]) this.mapColors(channel);
+        return this.m_avColors[channel];
+    }
+
+
+    /**
+     * Get a single face of the mesh
+     *
+     * @param iIndex Index of the face. Must be smaller than the value
+     *               returned by <code>getNumFaces()</code>
+     * @param aiOut  Output array, size must at least be 3
+     */
+    public void getFace(int iIndex, int[] aiOut) {
+        assert(aiOut.length >= 3);
+        if (null == this.m_vFaces) this.mapFaces();
+        iIndex *= 3;
+        aiOut[0] = this.m_vFaces[iIndex];
+        aiOut[1] = this.m_vFaces[iIndex + 1];
+        aiOut[2] = this.m_vFaces[iIndex + 2];
+    }
+
+    /**
+     * Get a single face of the mesh
+     *
+     * @param iIndex   Index of the face. Must be smaller than the value
+     *                 returned by <code>getNumFaces()</code>
+     * @param aiOut    Output array, size must at least be 3
+     * @param iOutBase Start index in the output array
+     */
+    public void getFace(int iIndex, int[] aiOut, int iOutBase) {
+        assert(aiOut.length >= 3);
+        if (null == this.m_vFaces) this.mapFaces();
+        iIndex *= 3;
+        aiOut[0] = this.m_vFaces[iIndex];
+        aiOut[iOutBase + 1] = this.m_vFaces[iIndex + 1];
+        aiOut[iOutBase + 2] = this.m_vFaces[iIndex + 2];
+    }
+
+
+    /**
+     * Provides direct access to the face array of the mesh
+     * This is the recommended way of accessing the data.
+     *
+     * @return Array of ints, size is numfaces * 3. Each face consists
+     *         of three indices (higher level polygons are automatically
+     *         triangulated by the library)
+     */
+    public int[] getFaceArray() {
+        if (null == this.m_vFaces) this.mapFaces();
+        return this.m_vFaces;
+    }
+
 
     protected void OnMap() throws NativeError {
+        // map all vertex component arrays into JVM memory
+        if (this.hasPositions()) this.mapVertices();
+        if (this.hasNormals()) this.mapNormals();
+        if (this.hasTangentsAndBitangents()) {
+            this.mapTangents();
+            this.mapBitangents();
+        }
+        for (int i = 0; i < MAX_NUMBER_OF_COLOR_SETS; ++i) {
+            if (this.hasVertexColors(i)) this.mapColors(i);
+        }
+        for (int i = 0; i < MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
+            if (this.hasUVCoords(i)) this.mapUVs(i);
+        }
+        // LOG
+    }
 
-        // map all vertex component arrays into our memory
 
+    private void mapVertices() {
+        this.m_vVertices = new float[this.getNumVertices() * 3];
+        if (0xffffffff == this._NativeMapVertices(((Scene) this.getParent()).
+                getImporter().getContext(), this.getArrayIndex(),
+                this.m_vVertices)) {
+            // this should occur rarely. No need to throw an exception,
+            // simply write to log and let the array at 0.0f
+            // LOG
+        }
+    }
+
+    private void mapNormals() {
+        this.m_vNormals = new float[this.getNumVertices() * 3];
+        if (0xffffffff == this._NativeMapNormals(((Scene) this.getParent()).
+                getImporter().getContext(), this.getArrayIndex(),
+                this.m_vNormals)) {
+            // this should occur rarely. No need to throw an exception,
+            // simply write to log and let the array at 0.0f
+            // LOG
+        }
+    }
+
+    private void mapTangents() {
+        this.m_vTangents = new float[this.getNumVertices() * 3];
+        if (0xffffffff == this._NativeMapTangents(((Scene) this.getParent()).
+                getImporter().getContext(), this.getArrayIndex(),
+                this.m_vTangents)) {
+            // this should occur rarely. No need to throw an exception,
+            // simply write to log and let the array at 0.0f
+            // LOG
+        }
+    }
+
+    private void mapBitangents() {
+        this.m_vBitangents = new float[this.getNumVertices() * 3];
+        if (0xffffffff == this._NativeMapBitangents(((Scene) this.getParent()).
+                getImporter().getContext(), this.getArrayIndex(),
+                this.m_vBitangents)) {
+            // this should occur rarely. No need to throw an exception,
+            // simply write to log and let the array at 0.0f
+            // LOG
+        }
+    }
+
+    private void mapFaces() {
+        this.m_vFaces = new int[this.getNumFaces() * 3];
+        if (0xffffffff == this._NativeMapFaces(((Scene) this.getParent()).
+                getImporter().getContext(), this.getArrayIndex(),
+                this.m_vFaces)) {
+            // this should occur rarely. No need to throw an exception,
+            // simply write to log and let the array at 0
+            // LOG
+        }
+    }
+
+    private void mapUVs(int channel) {
+        this.m_avUVs[channel] = new float[this.getNumVertices() * this.m_aiNumUVComponents[channel]];
+        if (0xffffffff == this._NativeMapUVs(((Scene) this.getParent()).
+                getImporter().getContext(), this.getArrayIndex(),
+                channel, this.m_avUVs[channel])) {
+            // this should occur rarely. No need to throw an exception,
+            // simply write to log and let the array at 0.0f
+            // LOG
+        }
+    }
+
+    private void mapColors(int channel) {
+        this.m_avColors[channel] = new float[this.getNumVertices() * 4];
+        if (0xffffffff == this._NativeMapColors(((Scene) this.getParent()).
+                getImporter().getContext(), this.getArrayIndex(),
+                channel, this.m_avColors[channel])) {
+            // this should occur rarely. No need to throw an exception,
+            // simply write to log and let the array at 0.0f
+            // LOG
+        }
     }
 
 
@@ -531,7 +818,7 @@ public class Mesh extends IMappable {
      * @param context Current importer context (imp.hashCode)
      * @return Combination of the PF_XXX constants
      */
-    private native int _NativeGetPresenceFlags(long context);
+    private native int _NativeGetPresenceFlags(long context, long index);
 
     /**
      * JNI bridge function - for internal use only
@@ -540,15 +827,43 @@ public class Mesh extends IMappable {
      * @param context Current importer context (imp.hashCode)
      * @return Number of vertices in the mesh
      */
-    private native int _NativeGetNumVertices(long context);
+    private native int _NativeGetNumVertices(long context, long index);
+
+    private native int _NativeGetNumFaces(long context, long index);
+
+    private native int _NativeGetNumBones(long context, long index);
+
+    private native int _NativeGetMaterialIndex(long context, long index);
 
     /**
      * JNI bridge function - for internal use only
      * Retrieve the number of uvw components for a channel
      *
      * @param context Current importer context (imp.hashCode)
-     * @param out Output array. Size must be MAX_NUMBER_OF_TEXTURECOORDS.
+     * @param out     Output array. Size must be MAX_NUMBER_OF_TEXTURECOORDS.
      * @return 0xffffffff if an error occured
      */
-     private native int _NativeGetNumUVComponents(long context, int[] out);
+    private native int _NativeGetNumUVComponents(long context, long index, int[] out);
+
+    /**
+     * JNI bridge function - for internal use only
+     * Map the position component of the mesh's vertices into memory
+     *
+     * @param context Current importer context (imp.hashCode)
+     * @param out     Output array. Must be large enough
+     * @return 0xffffffff if an error occured
+     */
+    private native int _NativeMapVertices(long context, long index, float[] out);
+
+    private native int _NativeMapNormals(long context, long index, float[] out);
+
+    private native int _NativeMapTangents(long context, long index, float[] out);
+
+    private native int _NativeMapBitangents(long context, long index, float[] out);
+
+    private native int _NativeMapUVs(long context, long index, int channel, float[] out);
+
+    private native int _NativeMapColors(long context, long index, int channel, float[] out);
+
+    private native int _NativeMapFaces(long context, long index, int[] out);
 }

+ 6 - 13
port/jAssimp/src/assimp/PostProcessStep.java

@@ -63,17 +63,6 @@ public class PostProcessStep {
     private static int s_iVertexSplitLimit = DEFAULT_VERTEX_SPLIT_LIMIT;
     private static int s_iTriangleSplitLimit = DEFAULT_TRIANGLE_SPLIT_LIMIT;
 
-
-    /**
-     * Triangulates all faces of all meshes. By default the imported
-     * mesh data might contain faces with more than 3 indices. For
-     * rendering a mesh you usually need all faces to be triangles. This
-     * post processing step splits up all higher faces to triangles.
-     */
-    public static final PostProcessStep Triangulate =
-            new PostProcessStep("Triangulate");
-
-
     /**
      * Identifies and joins identical vertex data sets within all imported
      * meshes. After this step is run each mesh does contain only unique
@@ -155,7 +144,9 @@ public class PostProcessStep {
      * Set the vertex split limit for the "SplitLargeMeshes" process
      * If a mesh exceeds this limit it will be splitted
      *
-     * @param limit New vertex split limit
+     * @param limit New vertex split limit. Pass 0xffffffff to disable
+     * a vertex split limit. However, splitting by triangles is still active
+     * then.
      * @return Old vertex split limit
      */
     public static synchronized int setVertexSplitLimit(int limit) {
@@ -171,7 +162,9 @@ public class PostProcessStep {
      * Set the triangle split limit for the "SplitLargeMeshes" process
      * If a mesh exceeds this limit it will be splitted
      *
-     * @param limit new triangle split limit
+     * @param limit new triangle split limit. Pass 0xffffffff to disable
+     * a triangle split limit. However, splitting by vertices is still active
+     * then.
      * @return Old triangle split limit
      */
     public static synchronized int setTriangleSplitLimit(int limit) {

+ 0 - 2
port/jAssimp/src/assimp/Scene.java

@@ -124,8 +124,6 @@ public class Scene {
     /**
      * Used to initialize the class instance. Called by Importer. Will maybe
      * be replaced with a RAII solution ...
-     *
-     * @return true if we're successful
      */
     protected void construct() throws NativeError {
 

+ 43 - 3
port/jAssimp/src/assimp/Texture.java

@@ -69,8 +69,16 @@ public class Texture extends IMappable {
      * @param parent Must be valid, null is not allowed
      * @param index  Valied index in the parent's list
      */
-    public Texture(Object parent, int index) {
+    public Texture(Object parent, int index) throws NativeError {
         super(parent, index);
+
+        long lTemp;
+        if (0x0 == (lTemp = this._NativeGetTextureInfo(((Scene)this.getParent()).
+                getImporter().getContext(),this.getArrayIndex()))) {
+            throw new NativeError("Unable to get the width and height of the texture");
+        }
+        this.width = (int)(lTemp);
+        this.height = (int)(lTemp >> 32);
     }
 
 
@@ -114,6 +122,23 @@ public class Texture extends IMappable {
         return data[y * width + x];
     }
 
+    /**
+     * Get a pointer to the color buffer of the texture
+     * @return Array of <code>java.awt.Color</code>, size: width * height
+     */
+    public Color[] getColorArray() {
+
+         // map the color data in memory if required ...
+        if (null == data) {
+            try {
+                this.OnMap();
+            } catch (NativeError nativeError) {
+                return null;
+            }
+        }
+        return data;
+    }
+
     /**
      * Internal helper function to map the native texture data into
      * a <code>java.awt.Color</code> array
@@ -129,7 +154,8 @@ public class Texture extends IMappable {
         byte[] temp = new byte[(iNumPixels) << 2];
 
         // and copy the native color data to it
-        if (0xffffffff == this._NativeMapColorData(temp)) {
+        if (0xffffffff == this._NativeMapColorData(((Scene)this.getParent()).getImporter().getContext(),
+                this.getArrayIndex(),temp)) {
            throw new NativeError("Unable to map aiTexture into the Java-VM");
         }
 
@@ -146,8 +172,22 @@ public class Texture extends IMappable {
      * The method maps the contents of the native aiTexture object into memory
      * the native memory area will be deleted afterwards.
      *
+     * @param context Current importer context (imp.hashCode)
+     * @param index Index of the texture in the scene
      * @param temp Output array. Assumed to be width * height * 4 in size
      * @return 0xffffffff if an error occured
      */
-    private native int _NativeMapColorData(byte[] temp);
+    private native int _NativeMapColorData(long context, long index, byte[] temp);
+
+    /**
+     * JNI bridge call. For internal use only
+     * The method retrieves information on the underlying texture
+     *
+     * @param context Current importer context (imp.hashCode)
+     * @param index Index of the texture in the scene
+     * @return 0x0 if an error occured, otherwise the width in the lower 32 bits
+     * and the height in the higher 32 bits
+     *
+     */
+    private native long _NativeGetTextureInfo(long context, long index);
 }

+ 3 - 6
tools/assimp_view/MeshRenderer.cpp

@@ -93,7 +93,7 @@ int CMeshRenderer::DrawSorted(unsigned int iIndex,const aiMatrix4x4& mWorld)
 			// well ... this is really funny now. We must compute their distance
 			// from the camera. We take the average distance of a face and add it 
 			// to a map which sorts it
-			std::map<float,unsigned int, std::greater_equal<float> > smap;
+			std::map<float,unsigned int, std::greater<float> > smap;
 
 			for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace)
 			{
@@ -105,9 +105,6 @@ int CMeshRenderer::DrawSorted(unsigned int iIndex,const aiMatrix4x4& mWorld)
 					vPos -= vLocalCamera;
 					fDist += vPos.SquareLength();
 				}
-				// SOMETIMES THIS THROWS AWESOME EXCEPTIONS
-				// don't know why, and the first who comes here with the debugger
-				// has the honorous task to find out!
 				smap.insert(std::pair<float, unsigned int>(fDist,iFace));
 			}
 
@@ -120,7 +117,7 @@ int CMeshRenderer::DrawSorted(unsigned int iIndex,const aiMatrix4x4& mWorld)
 				uint16_t* aiIndices;
 				pcHelper->piIB->Lock(0,0,(void**)&aiIndices,D3DLOCK_DISCARD);
 
-				for (std::map<float,unsigned int, std::greater_equal<float> >::const_iterator
+				for (std::map<float,unsigned int, std::greater<float> >::const_iterator
 					i =  smap.begin();
 					i != smap.end();++i)
 				{
@@ -135,7 +132,7 @@ int CMeshRenderer::DrawSorted(unsigned int iIndex,const aiMatrix4x4& mWorld)
 				uint32_t* aiIndices;
 				pcHelper->piIB->Lock(0,0,(void**)&aiIndices,D3DLOCK_DISCARD);
 
-				for (std::map<float,unsigned int, std::greater_equal<float> >::const_iterator
+				for (std::map<float,unsigned int, std::greater<float> >::const_iterator
 					i =  smap.begin();
 					i != smap.end();++i)
 				{

+ 4 - 0
workspaces/vc8/assimp.vcproj

@@ -779,6 +779,10 @@
 					RelativePath="..\..\code\jAssimp\assimp_Node.h"
 					>
 				</File>
+				<File
+					RelativePath="..\..\code\jAssimp\assimp_PostProcessStep.h"
+					>
+				</File>
 				<File
 					RelativePath="..\..\code\jAssimp\assimp_Scene.h"
 					>