[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