[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30166] branches/soc-2010-nicks/source/ gameengine/Ketsji: Work on conversion of the navigation mesh: we build navmesh directly from blender mesh using custom face data, when no custom data provided we use RAS_MeshObject interface

Nick Samarin nicks1987 at bigmir.net
Sat Jul 10 00:22:51 CEST 2010


Revision: 30166
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30166
Author:   nicks
Date:     2010-07-10 00:22:51 +0200 (Sat, 10 Jul 2010)

Log Message:
-----------
Work on conversion of the navigation mesh: we build navmesh directly from blender mesh using custom face data, when no custom data provided we use RAS_MeshObject interface

Modified Paths:
--------------
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_GameObject.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_GameObject.h
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.h
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_ObstacleSimulation.h

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_GameObject.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_GameObject.cpp	2010-07-09 22:16:52 UTC (rev 30165)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_GameObject.cpp	2010-07-09 22:22:51 UTC (rev 30166)
@@ -102,7 +102,7 @@
 	m_pGraphicController(NULL),
 	m_xray(false),
 	m_pHitObject(NULL),
-	m_pObstacle(NULL),
+	m_pObstacleSimulation(NULL),
 	m_isDeformable(false)
 #ifndef DISABLE_PYTHON
 	, m_attr_dict(NULL)
@@ -151,11 +151,9 @@
 		delete m_pGraphicController;
 	}
 
-	if (m_pObstacle)
+	if (m_pObstacleSimulation)
 	{
-		KX_Scene *scene = KX_GetActiveScene();
-		KX_ObstacleSimulation* obstacleSimulation = scene->GetObstacleSimulation();
-		obstacleSimulation->DestroyObstacle(m_pObstacle);
+		m_pObstacleSimulation->DestroyObstacleForObj(this);
 	}
 
 #ifndef DISABLE_PYTHON

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_GameObject.h
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_GameObject.h	2010-07-09 22:16:52 UTC (rev 30165)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_GameObject.h	2010-07-09 22:22:51 UTC (rev 30166)
@@ -59,7 +59,7 @@
 class PHY_IGraphicController;
 class PHY_IPhysicsEnvironment;
 struct Object;
-struct KX_Obstacle;
+class KX_ObstacleSimulation;
 
 #ifndef DISABLE_PYTHON
 /* utility conversion function */
@@ -109,7 +109,7 @@
 
 	MT_CmMatrix4x4						m_OpenGL_4x4Matrix;
 
-	KX_Obstacle*						m_pObstacle;
+	KX_ObstacleSimulation*				m_pObstacleSimulation;
 	
 public:
 	bool								m_isDeformable;
@@ -794,14 +794,14 @@
 		m_bSuspendDynamics = false;
 	}
 
-	void RegisterObstacle(KX_Obstacle* obstacle)
+	void RegisterObstacle(KX_ObstacleSimulation* obstacleSimulation)
 	{
-		m_pObstacle = obstacle;
+		m_pObstacleSimulation = obstacleSimulation;
 	}
 	
 	void UnregisterObstacle()
 	{
-		m_pObstacle = NULL;
+		m_pObstacleSimulation = NULL;
 	}
 		
 

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp	2010-07-09 22:16:52 UTC (rev 30165)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp	2010-07-09 22:22:51 UTC (rev 30166)
@@ -36,6 +36,7 @@
 #include "BKE_customdata.h"
 #include "BKE_cdderivedmesh.h"
 #include "BKE_DerivedMesh.h"
+#include "BLI_math_vector.h"
 }
 #include "KX_PythonInit.h"
 #include "KX_PyMath.h"
@@ -102,66 +103,316 @@
 }
 
 bool KX_NavMeshObject::BuildVertIndArrays(RAS_MeshObject* meshobj, float *&vertices, int& nverts,
-									   unsigned short* &faces, int& npolys)
+									   unsigned short* &polys, int& npolys, unsigned short *&dmeshes,
+									   float *&dvertices, int &ndvertsuniq, unsigned short *&dtris, 
+									   int& ndtris, int &vertsPerPoly)
 {
 	if (!meshobj) 
 	{
 		return false;
 	}
 
-	DerivedMesh* dm = CDDM_from_mesh(meshobj->GetMesh(), NULL);
+	DerivedMesh* dm = mesh_create_derived_no_virtual(KX_GetActiveScene()->GetBlenderScene(), GetBlenderObject(), 
+													NULL, CD_MASK_MESH);
+	int* recastData = (int*) dm->getFaceDataArray(dm, CD_PROP_INT);
+	if (recastData)
+	{
+		//create from blender mesh using recast data to build navigation 
+		//polygon mesh from detailed triangle mesh
+		MVert *mvert = dm->getVertArray(dm);
+		MFace *mface = dm->getFaceArray(dm);
+		int numfaces = dm->getNumFaces(dm);
+		int numverts = dm->getNumVerts(dm);
 
-	MVert *mvert = dm->getVertArray(dm);
-	MFace *mface = dm->getFaceArray(dm);
-	int numpolys = dm->getNumFaces(dm);
-	int numverts = dm->getNumVerts(dm);
+		if (numfaces==0)
+		{
+			return true;
+		}
 
-	nverts = numverts;
-	if (nverts >= 0xffff)
-		return false;
-	//calculate count of tris
-	npolys = numpolys;
-	for (int p2=0; p2<numpolys; p2++)
-	{
-		MFace* mf = &mface[p2];
-		if (mf->v4)
-			npolys+=1;
-	}
+		//build detailed mesh adjacency
+		ndtris = numfaces;
+		dtris = new unsigned short[numfaces*3*2];
+		memset(dtris, 0xffff, sizeof(unsigned short)*3*2*numfaces);
+		for (int i=0; i<numfaces;i++)
+		{
+			MFace* mf = &mface[i];
+			dtris[i*3*2+0] = mf->v1;
+			dtris[i*3*2+1] = mf->v2;
+			dtris[i*3*2+2] = mf->v3;
+			
+		}
+		buildMeshAdjacency(dtris, numfaces, numverts, 3);
 
-	//create verts
-	vertices = new float[nverts*3];
-	for (int vi=0; vi<nverts; vi++)
-	{
-		MVert *v = &mvert[vi];
-		for (int j=0; j<3; j++)
-			vertices[3*vi+j] = v->co[j];
+
+		//assumption: detailed mesh triangles are sorted by polygon idx
+		npolys = recastData[numfaces-1] + 1;
+		
+		dmeshes = new unsigned short[npolys*4];
+		memset(dmeshes, 0, npolys*4*sizeof(unsigned short));
+		unsigned short *dmesh = NULL;
+		int prevpolyidx = -1;
+		for (int i=0; i<numfaces; i++)
+		{
+			int curpolyidx = recastData[i];
+			if (curpolyidx!=prevpolyidx)
+			{
+				if (curpolyidx!=prevpolyidx+1)
+				{
+					//error - wrong order of detailed mesh faces
+					return false;
+				}
+				dmesh = dmesh==NULL ? dmeshes : dmesh+4;
+				dmesh[2] = i;	//tbase
+				dmesh[3] = 0;	//tnum
+				prevpolyidx = curpolyidx;
+			}
+			dmesh[3]++;
+		}
+
+		vertsPerPoly = 6;
+		polys = new unsigned short[npolys*vertsPerPoly*2];
+		memset(polys, 0xff, sizeof(unsigned short)*vertsPerPoly*2*npolys);
+		
+		int curpolytri = 0;
+		
+		for (int polyidx=0; polyidx<npolys; polyidx++)
+		{
+			vector<int> poly;
+			//search border 
+			int btri = -1;
+			int bedge = -1;
+			
+			for (int j=0; j<dmeshes[polyidx*4+3] && btri==-1;j++)
+			{
+				int curpolytri = dmeshes[polyidx*4+2]+j;
+				for (int k=0; k<3; k++)
+				{
+					unsigned short neighbortri = dtris[curpolytri*3*2+3+k];
+					if ( neighbortri==0xffff || recastData[neighbortri]!=polyidx)
+					{
+						btri = curpolytri;
+						bedge = k;
+						break;
+					}
+				}							
+			}
+			if (btri==-1 || bedge==-1)
+			{
+				//can't find triangle with border edge
+				return false;
+			}
+
+			poly.push_back(dtris[btri*3*2+bedge]);
+			//poly.push_back(detailedpolys[btri*3*2+(bedge+1)%3]);
+
+			int tri = btri;
+			int edge = (bedge+1)%3;
+			while (tri!=btri || edge!=bedge)
+			{
+				int neighbortri = dtris[tri*3*2+3+edge];
+				if (neighbortri==0xffff || recastData[neighbortri]!=polyidx)
+				{
+					//add vertex to current edge
+					poly.push_back(dtris[tri*3*2+edge]);
+					//move to next edge					
+					edge = (edge+1)%3;
+				}
+				else
+				{
+					//move to next tri
+					int twinedge = -1;
+					for (int k=0; k<3; k++)
+					{
+						if (dtris[neighbortri*3*2+3+k] == tri)
+						{
+							twinedge = k;
+							break;
+						}
+					}
+					if (twinedge==-1)
+					{
+						//can't find neighbor edge - invalid adjacency info
+						return false;
+					}
+					tri = neighbortri;
+					edge = (twinedge+1)%3;
+				}
+			}
+			
+			//.todo: process poly to remove degenerate vertices
+			if (poly.size()>=vertsPerPoly)
+			{
+				printf("Error! Polygon size exceeds max verts count");
+				return false;
+			}
+
+			for (int i=0; i<poly.size(); i++)
+			{
+				polys[polyidx*vertsPerPoly*2+i] = poly[i];
+			}
+		}
+
+		//assumption: vertices in mesh are stored in following order: 
+		//navigation mesh vertices - unique detailed mesh vertex
+		
+		unsigned short  maxidx = 0;
+		for (int polyidx=0; polyidx<npolys; polyidx++)
+		{
+			for (int i=0; i<vertsPerPoly; i++)
+			{
+				unsigned short idx = polys[polyidx*vertsPerPoly*2+i];
+				if (idx==0xffff)
+					break;
+				if (idx>maxidx)
+					maxidx=idx;
+			}
+		}
+		
+		//create navigation mesh verts
+		nverts = maxidx+1;
+		vertices = new float[nverts*3];
+		for (int vi=0; vi<nverts; vi++)
+		{
+			MVert *v = &mvert[vi];
+			copy_v3_v3(&vertices[3*vi], v->co);
+		}
+		
+		//create unique detailed mesh verts
+		ndvertsuniq = numverts - nverts;
+		if (ndvertsuniq>0)
+		{
+			dvertices = new float[ndvertsuniq*3];
+			for (int vi=0; vi<ndvertsuniq; vi++)
+			{
+				MVert *v = &mvert[nverts+vi];
+				copy_v3_v3(&dvertices[3*vi], v->co);
+			}
+		}
+
+		for (int polyIdx=0; polyIdx<npolys; polyIdx++)
+		{
+			unsigned short *dmesh = &dmeshes[4*polyIdx];
+			unsigned short minvert = 0xffff, maxvert = 0;
+			for (int j=0; j<dmesh[3]; j++)
+			{
+				unsigned short* dtri = &dtris[dmesh[2]*3*2+j];
+				for (int k=0; k<3; k++)
+				{
+					if (dtri[k]<nverts)
+						continue;
+					minvert = std::min(minvert, dtri[k]);
+					maxvert = std::max(maxvert, dtri[k]);
+				}
+			}
+			dmesh[0] = minvert; //vbase
+			dmesh[1] = minvert != 0xffff ? maxvert - minvert + 1 : 0; //vnum
+		}
+
+		//recalculate detailed mesh indices (it must be local)
+		for (int polyIdx=0; polyIdx<npolys; polyIdx++)
+		{
+			unsigned short * poly = &polys[polyIdx*vertsPerPoly*2];
+			int nv=0;
+			for (int vi=0; vi<vertsPerPoly; vi++)
+			{
+				if (poly[vi]==0xffff)
+					break;
+				nv++;
+			}
+			unsigned short *dmesh = &dmeshes[4*polyIdx];
+			for (int j=0; j<dmesh[3]; j++)
+			{
+				unsigned short* dtri = &dtris[(dmesh[2]+j)*3*2];
+				for (int k=0; k<3; k++)
+				{
+					if (dtri[k]<nverts)
+					{
+						//shared vertex from polygon
+						unsigned short idx = 0xffff;
+						for (int vi=0; vi<nv; vi++)
+						{
+							if (poly[vi]==dtri[k])
+							{
+								idx = vi;
+								break;
+							}
+						}
+						if (idx==0xffff)
+						{
+							printf("Can't find vertex in navigation polygon");
+							return false;
+						}
+						dtri[k] = idx;
+					}
+					else
+					{
+						dtri[k] = dtri[k]-dmesh[0]+nv;
+					}
+				}
+			}
+		}
 	}
-	//create tris
-	faces = new unsigned short[npolys*3*2];
-	memset(faces,0xff,sizeof(unsigned short)*3*2*npolys);
-	unsigned short *face = faces;
-	for (int p2=0; p2<numpolys; p2++)
+	else
 	{
-		MFace* mf = &mface[p2];
-		face[0]= mf->v1;
-		face[1]= mf->v2;
-		face[2]= mf->v3;
-		face += 6;
-		if (mf->v4)
+		//create from RAS_MeshObject (detailed mesh is fake)
+		vertsPerPoly = 3;
+		nverts = meshobj->m_sharedvertex_map.size();
+		if (nverts >= 0xffff)
+			return false;
+		//calculate count of tris
+		int nmeshpolys = meshobj->NumPolygons();
+		npolys = nmeshpolys;
+		for (int p=0; p<nmeshpolys; p++)
 		{
-			face[0]= mf->v1;
-			face[1]= mf->v3;
-			face[2]= mf->v4;
-			face += 6;
+			int vertcount = meshobj->GetPolygon(p)->VertexCount();
+			npolys+=vertcount-3;
 		}
+
+		//create verts
+		vertices = new float[nverts*3];
+		float* vert = vertices;
+		for (int vi=0; vi<nverts; vi++)
+		{
+			const float* pos = !meshobj->m_sharedvertex_map[vi].empty() ? meshobj->GetVertexLocation(vi) : NULL;
+			if (pos)
+				copy_v3_v3(vert, pos);
+			else

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list