diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-09-20 20:24:50 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-09-20 20:24:50 +0400 |
commit | 0169079bd1c3ce69690153321fb09c3647b9d930 (patch) | |
tree | f0ff89e8acdabe3d6e64dde5a7475aeddb55118e | |
parent | 219eeb3e54741340065bcef7188aa83ca5953fa3 (diff) |
Get rid of c++ in blenkernel and modifiers
Also use guarded allocations for navmesh stuff.
-rw-r--r-- | extern/recastnavigation/CMakeLists.txt | 12 | ||||
-rw-r--r-- | extern/recastnavigation/recast-capi.cpp | 37 | ||||
-rw-r--r-- | extern/recastnavigation/recast-capi.h | 42 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_navmesh_conversion.h | 38 | ||||
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/SConscript | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/navmesh_conversion.c (renamed from source/blender/blenkernel/intern/navmesh_conversion.cpp) | 244 | ||||
-rw-r--r-- | source/blender/modifiers/CMakeLists.txt | 6 | ||||
-rw-r--r-- | source/blender/modifiers/SConscript | 4 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_navmesh.c (renamed from source/blender/modifiers/intern/MOD_navmesh.cpp) | 87 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_NavMeshObject.cpp | 19 |
11 files changed, 326 insertions, 173 deletions
diff --git a/extern/recastnavigation/CMakeLists.txt b/extern/recastnavigation/CMakeLists.txt index 1af01b1b427..660b881dd07 100644 --- a/extern/recastnavigation/CMakeLists.txt +++ b/extern/recastnavigation/CMakeLists.txt @@ -25,7 +25,7 @@ # ***** END GPL LICENSE BLOCK ***** set(INC - Recast/Include + Recast/Include Detour/Include ) @@ -34,6 +34,10 @@ set(INC_SYS ) set(SRC + recast-capi.cpp + recast-capi.h + + Detour/Source/DetourCommon.cpp Detour/Source/DetourNode.cpp Detour/Source/DetourStatNavMesh.cpp @@ -47,7 +51,7 @@ set(SRC Detour/Include/DetourStatNavMeshBuilder.h Detour/Include/DetourTileNavMesh.h Detour/Include/DetourTileNavMeshBuilder.h - + Recast/Source/Recast.cpp Recast/Source/RecastContour.cpp Recast/Source/RecastFilter.cpp @@ -57,10 +61,10 @@ set(SRC Recast/Source/RecastRasterization.cpp Recast/Source/RecastRegion.cpp Recast/Source/RecastTimer.cpp - + Recast/Include/Recast.h Recast/Include/RecastLog.h - Recast/Include/RecastTimer.h + Recast/Include/RecastTimer.h ) blender_add_lib(extern_recastnavigation "${SRC}" "${INC}" "${INC_SYS}") diff --git a/extern/recastnavigation/recast-capi.cpp b/extern/recastnavigation/recast-capi.cpp new file mode 100644 index 00000000000..52c4cdc90ed --- /dev/null +++ b/extern/recastnavigation/recast-capi.cpp @@ -0,0 +1,37 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "recast-capi.h" + +#include <math.h> +#include "Recast.h" + +int recast_buildMeshAdjacency(unsigned short* polys, const int npolys, + const int nverts, const int vertsPerPoly) +{ + return (int) buildMeshAdjacency(polys, npolys, nverts, vertsPerPoly); +} diff --git a/extern/recastnavigation/recast-capi.h b/extern/recastnavigation/recast-capi.h new file mode 100644 index 00000000000..0d20fdf9981 --- /dev/null +++ b/extern/recastnavigation/recast-capi.h @@ -0,0 +1,42 @@ +/* + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef RECAST_C_API_H +#define RECAST_C_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +int recast_buildMeshAdjacency(unsigned short* polys, const int npolys, + const int nverts, const int vertsPerPoly); + +#ifdef __cplusplus +} +#endif + +#endif // RECAST_C_API_H diff --git a/source/blender/blenkernel/BKE_navmesh_conversion.h b/source/blender/blenkernel/BKE_navmesh_conversion.h index acb3c2963a9..5f8359d1e3d 100644 --- a/source/blender/blenkernel/BKE_navmesh_conversion.h +++ b/source/blender/blenkernel/BKE_navmesh_conversion.h @@ -32,32 +32,32 @@ struct DerivedMesh; -/* navmesh_conversion.cpp */ -bool buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int& vertsPerPoly, - int &nverts, float *&verts, - int &ndtris, unsigned short *&dtris, - int& npolys, unsigned short *&dmeshes, - unsigned short*& polys, int *&dtrisToPolysMap, - int *&dtrisToTrisMap, int *&trisToFacesMap); +/* navmesh_conversion.c */ +int buildNavMeshDataByDerivedMesh(struct DerivedMesh *dm, int *vertsPerPoly, + int *nverts, float **verts, + int *ndtris, unsigned short **dtris, + int *npolys, unsigned short **dmeshes, + unsigned short **polys, int **dtrisToPolysMap, + int **dtrisToTrisMap, int **trisToFacesMap); -bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, - int &ntris, unsigned short *&tris, int *&trisToFacesMap, - int *&recastData); +int buildRawVertIndicesData(struct DerivedMesh* dm, int *nverts, float **verts, + int *ntris, unsigned short **tris, int **trisToFacesMap, + int **recastData); -bool buildNavMeshData(const int nverts, const float* verts, - const int ntris, const unsigned short *tris, +int buildNavMeshData(const int nverts, const float* verts, + const int ntris, const unsigned short *tris, const int* recastData, const int* trisToFacesMap, - int &ndtris, unsigned short *&dtris, - int &npolys, unsigned short *&dmeshes, unsigned short *&polys, - int &vertsPerPoly, int *&dtrisToPolysMap, int *&dtrisToTrisMap); + int *ndtris, unsigned short **dtris, + int *npolys, unsigned short **dmeshes, unsigned short **polys, + int *vertsPerPoly, int **dtrisToPolysMap, int **dtrisToTrisMap); -bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, - unsigned short* polys, const unsigned short* dmeshes, - const float* verts, const unsigned short* dtris, +int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, + unsigned short* polys, const unsigned short* dmeshes, + const float* verts, const unsigned short* dtris, const int* dtrisToPolysMap); int polyNumVerts(const unsigned short* p, const int vertsPerPoly); -bool polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* verts); +int polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* verts); int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx); float distPointToSegmentSq(const float* point, const float* a, const float* b); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 09b38195ef3..93ab29c5f49 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -353,10 +353,10 @@ endif() if(WITH_GAMEENGINE) list(APPEND INC_SYS - ../../../extern/recastnavigation/Recast/Include + ../../../extern/recastnavigation ) list(APPEND SRC - intern/navmesh_conversion.cpp + intern/navmesh_conversion.c BKE_navmesh_conversion.h ) endif() diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 56de8afc0da..7d7ab56ec3f 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -2,7 +2,7 @@ Import ('env') import os -sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp') +sources = env.Glob('intern/*.c') incs = '. #/intern/guardedalloc #/intern/memutil' incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager' @@ -92,10 +92,10 @@ if env['WITH_BF_LZMA']: defs.append('WITH_LZMA') if env['WITH_BF_GAMEENGINE']: - incs += ' #/extern/recastnavigation/Recast/Include' + incs += ' #/extern/recastnavigation' defs.append('WITH_GAMEENGINE') else: - sources.remove('intern' + os.sep + 'navmesh_conversion.cpp') + sources.remove('intern' + os.sep + 'navmesh_conversion.c') if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] diff --git a/source/blender/blenkernel/intern/navmesh_conversion.cpp b/source/blender/blenkernel/intern/navmesh_conversion.c index fbc4775cf34..eefc24ee8c6 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.cpp +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -29,30 +29,32 @@ #include <math.h> #include <stdlib.h> -#include "Recast.h" -extern "C"{ -#include "BKE_navmesh_conversion.h" +#include "MEM_guardedalloc.h" #include "DNA_meshdata_types.h" + +#include "BKE_navmesh_conversion.h" #include "BKE_cdderivedmesh.h" + #include "BLI_math.h" -} + +#include "recast-capi.h" inline float area2(const float* a, const float* b, const float* c) { return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]); } -inline bool left(const float* a, const float* b, const float* c) +inline int left(const float* a, const float* b, const float* c) { return area2(a, b, c) < 0; } int polyNumVerts(const unsigned short* p, const int vertsPerPoly) { - int nv = 0; - for (int i=0; i<vertsPerPoly; i++) + int i, nv = 0; + for (i=0; i<vertsPerPoly; i++) { if (p[i]==0xffff) break; @@ -61,28 +63,28 @@ int polyNumVerts(const unsigned short* p, const int vertsPerPoly) return nv; } -bool polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* verts) +int polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* verts) { - int nv = polyNumVerts(p, vertsPerPoly); + int j, nv = polyNumVerts(p, vertsPerPoly); if (nv<3) - return false; - for (int j=0; j<nv; j++) + return 0; + for (j=0; j<nv; j++) { const float* v = &verts[3*p[j]]; const float* v_next = &verts[3*p[(j+1)%nv]]; const float* v_prev = &verts[3*p[(nv+j-1)%nv]]; if (!left(v_prev, v, v_next)) - return false; + return 0; } - return true; + return 1; } float distPointToSegmentSq(const float* point, const float* a, const float* b) { float abx[3], dx[3]; - vsub(abx, b,a); - vsub(dx, point,a); + sub_v3_v3v3(abx, b,a); + sub_v3_v3v3(dx, point,a); float d = abx[0]*abx[0]+abx[2]*abx[2]; float t = abx[0]*dx[0]+abx[2]*dx[2]; if (d > 0) @@ -96,21 +98,27 @@ float distPointToSegmentSq(const float* point, const float* a, const float* b) return dx[0]*dx[0] + dx[2]*dx[2]; } -bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, - int &ntris, unsigned short *&tris, int *&trisToFacesMap, - int *&recastData) +int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, + int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, + int **recastData) { + int vi, fi, triIdx; + int nverts, ntris; + int *trisToFacesMap; + float *verts; + unsigned short *tris, *tri; + nverts = dm->getNumVerts(dm); if (nverts>=0xffff) { printf("Converting navmesh: Error! Too many vertices. Max number of vertices %d\n", 0xffff); - return false; + return 0; } - verts = new float[3*nverts]; + verts = MEM_callocN(sizeof(float)*3*nverts, "buildRawVertIndicesData verts"); dm->getVertCos(dm, (float(*)[3])verts); //flip coordinates - for (int vi=0; vi<nverts; vi++) + for (vi=0; vi<nverts; vi++) { SWAP(float, verts[3*vi+1], verts[3*vi+2]); } @@ -119,7 +127,7 @@ bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, int nfaces = dm->getNumFaces(dm); MFace *faces = dm->getFaceArray(dm); ntris = nfaces; - for (int fi=0; fi<nfaces; fi++) + for (fi=0; fi<nfaces; fi++) { MFace* face = &faces[fi]; if (face->v4) @@ -127,11 +135,11 @@ bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, } //copy and transform to triangles (reorder on the run) - trisToFacesMap = new int[ntris]; - tris = new unsigned short[3*ntris]; - unsigned short* tri = tris; - int triIdx = 0; - for (int fi=0; fi<nfaces; fi++) + trisToFacesMap = MEM_callocN(sizeof(int)*ntris, "buildRawVertIndicesData trisToFacesMap"); + tris = MEM_callocN(sizeof(unsigned short)*3*ntris, "buildRawVertIndicesData tris"); + tri = tris; + triIdx = 0; + for (fi=0; fi<nfaces; fi++) { MFace* face = &faces[fi]; tri[3*triIdx+0] = (unsigned short) face->v1; @@ -148,32 +156,46 @@ bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, } //carefully, recast data is just reference to data in derived mesh - recastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); - return true; + *recastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); + + *nverts_r = nverts; + *verts_r = verts; + *ntris_r = ntris; + *tris_r = tris; + *trisToFacesMap_r = trisToFacesMap; + + return 1; } -bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, +int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, unsigned short* polys, const unsigned short* dmeshes, const float* verts, const unsigned short* dtris, const int* dtrisToPolysMap) { + int polyidx; int capacity = vertsPerPoly; - unsigned short* newPoly = new unsigned short[capacity]; + unsigned short* newPoly = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPoly"); memset(newPoly, 0xff, sizeof(unsigned short)*capacity); - for (int polyidx=0; polyidx<npolys; polyidx++) + + for (polyidx=0; polyidx<npolys; polyidx++) { + size_t i; + int j, k; int nv = 0; //search border - int btri = -1; - int bedge = -1; + int tri, btri = -1; + int edge, bedge = -1; int dtrisNum = dmeshes[polyidx*4+3]; int dtrisBase = dmeshes[polyidx*4+2]; - unsigned char *traversedTris = new unsigned char[dtrisNum]; - memset(traversedTris, 0, dtrisNum*sizeof(unsigned char)); - for (int j=0; j<dtrisNum && btri==-1;j++) + unsigned char *traversedTris = MEM_callocN(sizeof(unsigned char)*dtrisNum, "buildPolygonsByDetailedMeshes traversedTris"); + unsigned short* adjustedPoly; + int adjustedNv; + int allBorderTraversed; + + for (j=0; j<dtrisNum && btri==-1;j++) { int curpolytri = dtrisBase+j; - for (int k=0; k<3; k++) + for (k=0; k<3; k++) { unsigned short neighbortri = dtris[curpolytri*3*2+3+k]; if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) @@ -187,12 +209,15 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, if (btri==-1 || bedge==-1) { //can't find triangle with border edge - return false; + MEM_freeN(traversedTris); + MEM_freeN(newPoly); + + return 0; } newPoly[nv++] = dtris[btri*3*2+bedge]; - int tri = btri; - int edge = (bedge+1)%3; + tri = btri; + edge = (bedge+1)%3; traversedTris[tri-dtrisBase] = 1; while (tri!=btri || edge!=bedge) { @@ -202,10 +227,10 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, if (nv==capacity) { capacity += vertsPerPoly; - unsigned short* newPolyBig = new unsigned short[capacity]; + unsigned short* newPolyBig = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPolyBig"); memset(newPolyBig, 0xff, sizeof(unsigned short)*capacity); memcpy(newPolyBig, newPoly, sizeof(unsigned short)*nv); - delete newPoly; + MEM_freeN(newPoly); newPoly = newPolyBig; } newPoly[nv++] = dtris[tri*3*2+edge]; @@ -216,7 +241,7 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, { //move to next tri int twinedge = -1; - for (int k=0; k<3; k++) + for (k=0; k<3; k++) { if (dtris[neighbortri*3*2+3+k] == tri) { @@ -227,7 +252,8 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, if (twinedge==-1) { printf("Converting navmesh: Error! Can't find neighbor edge - invalid adjacency info\n"); - goto returnLabel; + MEM_freeN(traversedTris); + goto returnLabel; } tri = neighbortri; edge = (twinedge+1)%3; @@ -235,9 +261,9 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, } } - unsigned short* adjustedPoly = new unsigned short[nv]; - int adjustedNv = 0; - for (size_t i=0; i<(size_t)nv; i++) + adjustedPoly = MEM_callocN(sizeof(unsigned short)*nv, "buildPolygonsByDetailedMeshes adjustedPoly"); + adjustedNv = 0; + for (i=0; i<nv; i++) { unsigned short prev = newPoly[(nv+i-1)%nv]; unsigned short cur = newPoly[i]; @@ -248,22 +274,22 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, adjustedPoly[adjustedNv++] = cur; } memcpy(newPoly, adjustedPoly, adjustedNv*sizeof(unsigned short)); - delete adjustedPoly; + MEM_freeN(adjustedPoly); nv = adjustedNv; - bool allBorderTraversed = true; - for (size_t i=0; i<(size_t)dtrisNum; i++) + allBorderTraversed = 1; + for (i=0; i<dtrisNum; i++) { if (traversedTris[i]==0) { //check whether it has border edges int curpolytri = dtrisBase+i; - for (int k=0; k<3; k++) + for (k=0; k<3; k++) { unsigned short neighbortri = dtris[curpolytri*3*2+3+k]; if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) { - allBorderTraversed = false; + allBorderTraversed = 0; break; } } @@ -272,16 +298,19 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, if (nv<=vertsPerPoly && allBorderTraversed) { - for (int i=0; i<nv; i++) + for (i=0; i<nv; i++) { polys[polyidx*vertsPerPoly*2+i] = newPoly[i]; } } + + MEM_freeN(traversedTris); } returnLabel: - delete newPoly; - return true; + MEM_freeN(newPoly); + + return 1; } struct SortContext @@ -292,7 +321,7 @@ struct SortContext /* XXX: not thread-safe, but it's called only from modifiers stack which isn't threaded. Anyway, better to avoid this in the future */ -static SortContext *_qsort_context; +static struct SortContext *_qsort_context; static int compareByData(const void * a, const void * b) { @@ -300,32 +329,41 @@ static int compareByData(const void * a, const void * b) _qsort_context->recastData[_qsort_context->trisToFacesMap[*(int*)b]] ); } -bool buildNavMeshData(const int nverts, const float* verts, +int buildNavMeshData(const int nverts, const float* verts, const int ntris, const unsigned short *tris, const int* recastData, const int* trisToFacesMap, - int &ndtris, unsigned short *&dtris, - int &npolys, unsigned short *&dmeshes, unsigned short *&polys, - int &vertsPerPoly, int *&dtrisToPolysMap, int *&dtrisToTrisMap) + int *ndtris_r, unsigned short **dtris_r, + int *npolys_r, unsigned short **dmeshes_r, unsigned short **polys_r, + int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r) { + int *trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping"); + int i; + struct SortContext context; + int validTriStart, prevPolyIdx, curPolyIdx, newPolyIdx, prevpolyidx; + unsigned short *dmesh; + + int ndtris, npolys, vertsPerPoly; + unsigned short *dtris, *dmeshes, *polys; + int *dtrisToPolysMap, *dtrisToTrisMap; + if (!recastData) { printf("Converting navmesh: Error! Can't find recast custom data\n"); - return false; + return 0; } //sort the triangles by polygon idx - int* trisMapping = new int[ntris]; - for (int i=0; i<ntris; i++) + for (i=0; i<ntris; i++) trisMapping[i]=i; - SortContext context; context.recastData = recastData; context.trisToFacesMap = trisToFacesMap; _qsort_context = &context; qsort(trisMapping, ntris, sizeof(int), compareByData); + //search first valid triangle - triangle of convex polygon - int validTriStart = -1; - for (int i=0; i< ntris; i++) + validTriStart = -1; + for (i=0; i< ntris; i++) { if (recastData[trisToFacesMap[trisMapping[i]]]>0) { @@ -337,28 +375,30 @@ bool buildNavMeshData(const int nverts, const float* verts, if (validTriStart<0) { printf("Converting navmesh: Error! No valid polygons in mesh\n"); - delete trisMapping; - return false; + MEM_freeN(trisMapping); + return 0; } ndtris = ntris-validTriStart; //fill dtris to faces mapping - dtrisToTrisMap = new int[ndtris]; + dtrisToTrisMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToTrisMap"); memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris*sizeof(int)); - delete trisMapping; trisMapping=NULL; + MEM_freeN(trisMapping); //create detailed mesh triangles - copy only valid triangles //and reserve memory for adjacency info - dtris = new unsigned short[3*2*ndtris]; + dtris = MEM_callocN(sizeof(unsigned short)*3*2*ndtris, "buildNavMeshData dtris"); memset(dtris, 0xffff, sizeof(unsigned short)*3*2*ndtris); - for (int i=0; i<ndtris; i++) + for (i=0; i<ndtris; i++) { memcpy(dtris+3*2*i, tris+3*dtrisToTrisMap[i], sizeof(unsigned short)*3); } + //create new recast data corresponded to dtris and renumber for continuous indices - int prevPolyIdx=-1, curPolyIdx, newPolyIdx=0; - dtrisToPolysMap = new int[ndtris]; - for (int i=0; i<ndtris; i++) + prevPolyIdx = -1; + newPolyIdx = 0; + dtrisToPolysMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToPolysMap"); + for (i=0; i<ndtris; i++) { curPolyIdx = recastData[trisToFacesMap[dtrisToTrisMap[i]]]; if (curPolyIdx!=prevPolyIdx) @@ -371,15 +411,15 @@ bool buildNavMeshData(const int nverts, const float* verts, //build adjacency info for detailed mesh triangles - buildMeshAdjacency(dtris, ndtris, nverts, 3); + recast_buildMeshAdjacency(dtris, ndtris, nverts, 3); //create detailed mesh description for each navigation polygon npolys = dtrisToPolysMap[ndtris-1]; - dmeshes = new unsigned short[npolys*4]; + dmeshes = MEM_callocN(sizeof(unsigned short)*npolys*4, "buildNavMeshData dmeshes"); memset(dmeshes, 0, npolys*4*sizeof(unsigned short)); - unsigned short *dmesh = NULL; - int prevpolyidx = 0; - for (int i=0; i<ndtris; i++) + dmesh = NULL; + prevpolyidx = 0; + for (i=0; i<ndtris; i++) { int curpolyidx = dtrisToPolysMap[i]; if (curpolyidx!=prevpolyidx) @@ -387,7 +427,7 @@ bool buildNavMeshData(const int nverts, const float* verts, if (curpolyidx!=prevpolyidx+1) { printf("Converting navmesh: Error! Wrong order of detailed mesh faces\n"); - return false; + return 0; } dmesh = dmesh==NULL ? dmeshes : dmesh+4; dmesh[2] = (unsigned short)i; //tbase @@ -399,33 +439,43 @@ bool buildNavMeshData(const int nverts, const float* verts, //create navigation polygons vertsPerPoly = 6; - polys = new unsigned short[npolys*vertsPerPoly*2]; + polys = MEM_callocN(sizeof(unsigned short)*npolys*vertsPerPoly*2, "buildNavMeshData polys"); memset(polys, 0xff, sizeof(unsigned short)*vertsPerPoly*2*npolys); buildPolygonsByDetailedMeshes(vertsPerPoly, npolys, polys, dmeshes, verts, dtris, dtrisToPolysMap); - return true; + *ndtris_r = ndtris; + *npolys_r = npolys; + *vertsPerPoly_r = vertsPerPoly; + *dtris_r = dtris; + *dmeshes_r = dmeshes; + *polys_r = polys; + *dtrisToPolysMap_r = dtrisToPolysMap; + *dtrisToTrisMap_r = dtrisToTrisMap; + + return 1; } -bool buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int& vertsPerPoly, - int &nverts, float *&verts, - int &ndtris, unsigned short *&dtris, - int& npolys, unsigned short *&dmeshes, - unsigned short*& polys, int *&dtrisToPolysMap, - int *&dtrisToTrisMap, int *&trisToFacesMap) +int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly, + int *nverts, float **verts, + int *ndtris, unsigned short **dtris, + int *npolys, unsigned short **dmeshes, + unsigned short **polys, int **dtrisToPolysMap, + int **dtrisToTrisMap, int **trisToFacesMap) { - bool res = true; - int ntris =0, *recastData=NULL; + int res = 1; + int ntris = 0, *recastData=NULL; unsigned short *tris=NULL; - res = buildRawVertIndicesData(dm, nverts, verts, ntris, tris, trisToFacesMap, recastData); + + res = buildRawVertIndicesData(dm, nverts, verts, &ntris, &tris, trisToFacesMap, &recastData); if (!res) { printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n"); goto exit; } - res = buildNavMeshData(nverts, verts, ntris, tris, recastData, trisToFacesMap, + res = buildNavMeshData(*nverts, *verts, ntris, tris, recastData, *trisToFacesMap, ndtris, dtris, npolys, dmeshes,polys, vertsPerPoly, dtrisToPolysMap, dtrisToTrisMap); if (!res) @@ -436,15 +486,15 @@ bool buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int& vertsPerPoly, exit: if (tris) - delete tris; + MEM_freeN(tris); return res; } int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx) { - int res = -1; - for(int i=0; i<vertsPerPoly; i++) + int i, res = -1; + for(i=0; i<vertsPerPoly; i++) { if (p[i]==0xffff) break; diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index d8344a9e19b..fb4aa4ca4a5 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -65,7 +65,7 @@ set(SRC intern/MOD_meshdeform.c intern/MOD_mirror.c intern/MOD_multires.c - intern/MOD_navmesh.cpp + intern/MOD_navmesh.c intern/MOD_none.c intern/MOD_particleinstance.c intern/MOD_particlesystem.c @@ -117,11 +117,11 @@ if(NOT WITH_MOD_FLUID) endif() if(WITH_GAMEENGINE) - # for MOD_navmesh.cpp + # for MOD_navmesh.c add_definitions(-DWITH_GAMEENGINE) list(APPEND INC ../gpu - ../../../extern/recastnavigation/Recast/Include + ../../../extern/recastnavigation ) endif() diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index da37539e950..77a2d577fb5 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/SConscript @@ -1,7 +1,7 @@ #!/usr/bin/python Import ('env') -sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp') +sources = env.Glob('intern/*.c') incs = '. ./intern' incs += ' #/intern/guardedalloc #/intern/decimation/extern #/intern/bsp/extern #/intern/elbeem/extern #/extern/glew/include' @@ -21,7 +21,7 @@ if env['BF_NO_ELBEEM']: defs.append('DISABLE_ELBEEM') if env['WITH_BF_GAMEENGINE']: - incs += ' #/extern/recastnavigation/Recast/Include' + incs += ' #/extern/recastnavigation' defs.append('WITH_GAMEENGINE') env.BlenderLib ( libname = 'bf_modifiers', sources = sources, diff --git a/source/blender/modifiers/intern/MOD_navmesh.cpp b/source/blender/modifiers/intern/MOD_navmesh.c index 927085033fc..e05f91058f3 100644 --- a/source/blender/modifiers/intern/MOD_navmesh.cpp +++ b/source/blender/modifiers/intern/MOD_navmesh.c @@ -27,22 +27,17 @@ */ #include <math.h> -#ifdef WITH_GAMEENGINE -# include "Recast.h" -#endif - -extern "C"{ +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #ifdef WITH_GAMEENGINE +# include "recast-capi.h" # include "BKE_navmesh_conversion.h" # include "GL/glew.h" # include "GPU_buffers.h" # include "GPU_draw.h" #endif -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" - #include "BLI_math.h" #include "BLI_utildefines.h" @@ -53,12 +48,12 @@ extern "C"{ #include "BKE_customdata.h" #include "MEM_guardedalloc.h" -inline int bit(int a, int b) +static inline int bit(int a, int b) { return (a & (1 << b)) >> b; } -inline void intToCol(int i, float* col) +static inline void intToCol(int i, float* col) { int r = bit(i, 0) + bit(i, 3) * 2 + 1; int g = bit(i, 1) + bit(i, 4) * 2 + 1; @@ -69,12 +64,12 @@ inline void intToCol(int i, float* col) } -static void initData(ModifierData *md) +static void initData(ModifierData *UNUSED(md)) { /* NavMeshModifierData *nmmd = (NavMeshModifierData*) md; */ /* UNUSED */ } -static void copyData(ModifierData *md, ModifierData *target) +static void copyData(ModifierData *UNUSED(md), ModifierData *UNUSED(target)) { /* NavMeshModifierData *nmmd = (NavMeshModifierData*) md; */ /* NavMeshModifierData *tnmmd = (NavMeshModifierData*) target; */ @@ -94,10 +89,12 @@ static void drawNavMeshColored(DerivedMesh *dm) MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT); MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE); int* polygonIdx = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); - if (!polygonIdx) - return; const float BLACK_COLOR[3] = {0.f, 0.f, 0.f}; float col[3]; + + if (!polygonIdx) + return; + /* //UI_ThemeColor(TH_WIRE); glDisable(GL_LIGHTING); @@ -138,23 +135,34 @@ static void drawNavMeshColored(DerivedMesh *dm) static void navDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr)) { + (void) setDrawOptions; + drawNavMeshColored(dm); } static void navDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], - int fast, int (*setMaterial)(int, void *attribs)) + int UNUSED(fast), int (*setMaterial)(int, void *attribs)) { + (void) partial_redraw_planes; + (void) setMaterial; + //drawFacesSolid_original(dm, partial_redraw_planes, fast, setMaterial); drawNavMeshColored(dm); } #endif /* WITH_GAMEENGINE */ -static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,DerivedMesh *dm) +static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *UNUSED(mmd), DerivedMesh *dm) { #ifdef WITH_GAMEENGINE DerivedMesh *result; int maxFaces = dm->getNumFaces(dm); + int *recastData; + int vertsPerPoly=0, nverts=0, ndtris=0, npolys=0; + float* verts=NULL; + unsigned short *dtris=NULL, *dmeshes=NULL, *polys=NULL; + int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL; + int res; result = CDDM_copy(dm); if (!CustomData_has_layer(&result->faceData, CD_RECAST)) @@ -163,24 +171,21 @@ static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,Deriv CustomData_add_layer_named(&result->faceData, CD_RECAST, CD_DUPLICATE, sourceRecastData, maxFaces, "recastData"); } - int *recastData = (int*)CustomData_get_layer(&result->faceData, CD_RECAST); + recastData = (int*)CustomData_get_layer(&result->faceData, CD_RECAST); result->drawFacesTex = navDM_drawFacesTex; result->drawFacesSolid = navDM_drawFacesSolid; //process mesh - int vertsPerPoly=0, nverts=0, ndtris=0, npolys=0; - float* verts=NULL; - unsigned short *dtris=NULL, *dmeshes=NULL, *polys=NULL; - int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL; - - bool res = buildNavMeshDataByDerivedMesh(dm, vertsPerPoly, nverts, verts, ndtris, dtris, - npolys, dmeshes, polys, dtrisToPolysMap, dtrisToTrisMap, - trisToFacesMap); + res = buildNavMeshDataByDerivedMesh(dm, &vertsPerPoly, &nverts, &verts, &ndtris, &dtris, + &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, + &trisToFacesMap); if (res) { + size_t polyIdx; + //invalidate concave polygon - for (size_t polyIdx=0; polyIdx<(size_t)npolys; polyIdx++) + for (polyIdx=0; polyIdx<(size_t)npolys; polyIdx++) { unsigned short* poly = &polys[polyIdx*2*vertsPerPoly]; if (!polyIsConvex(poly, vertsPerPoly, verts)) @@ -189,7 +194,9 @@ static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,Deriv unsigned short *dmesh = &dmeshes[4*polyIdx]; unsigned short tbase = dmesh[2]; unsigned short tnum = dmesh[3]; - for (unsigned short ti=0; ti<tnum; ti++) + unsigned short ti; + + for (ti=0; ti<tnum; ti++) { unsigned short triidx = dtrisToTrisMap[tbase+ti]; unsigned short faceidx = trisToFacesMap[triidx]; @@ -207,19 +214,19 @@ static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,Deriv //clean up if (verts!=NULL) - delete verts; + MEM_freeN(verts); if (dtris!=NULL) - delete dtris; + MEM_freeN(dtris); if (dmeshes!=NULL) - delete dmeshes; + MEM_freeN(dmeshes); if (polys!=NULL) - delete polys; + MEM_freeN(polys); if (dtrisToPolysMap!=NULL) - delete dtrisToPolysMap; + MEM_freeN(dtrisToPolysMap); if (dtrisToTrisMap!=NULL) - delete dtrisToTrisMap; + MEM_freeN(dtrisToTrisMap); if (trisToFacesMap!=NULL) - delete trisToFacesMap; + MEM_freeN(trisToFacesMap); return result; #else // WITH_GAMEENGINE @@ -237,11 +244,11 @@ static int isDisabled(ModifierData *md, int useRenderParams) static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, - int useRenderParams, int isFinalCalc) + int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { DerivedMesh *result = NULL; NavMeshModifierData *nmmd = (NavMeshModifierData*) md; - bool hasRecastData = CustomData_has_layer(&derivedData->faceData, CD_RECAST)>0; + int hasRecastData = CustomData_has_layer(&derivedData->faceData, CD_RECAST)>0; if (ob->body_type!=OB_BODY_TYPE_NAVMESH || !hasRecastData ) { //convert to nav mesh object: @@ -255,10 +262,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der Mesh* obmesh = (Mesh *)ob->data; if (obmesh) { + int i; int numFaces = obmesh->totface; + int* recastData; CustomData_add_layer_named(&obmesh->fdata, CD_RECAST, CD_CALLOC, NULL, numFaces, "recastData"); - int* recastData = (int*)CustomData_get_layer(&obmesh->fdata, CD_RECAST); - for (int i=0; i<numFaces; i++) + recastData = (int*)CustomData_get_layer(&obmesh->fdata, CD_RECAST); + for (i=0; i<numFaces; i++) { recastData[i] = i+1; } @@ -296,5 +305,3 @@ ModifierTypeInfo modifierType_NavMesh = { /* foreachObjectLink */ 0, /* foreachIDLink */ 0, }; - -}; diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp index f72c98fb4bf..5747d8641d0 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.cpp +++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp @@ -26,6 +26,8 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include "MEM_guardedalloc.h" + #include "BLI_math_vector.h" #include "KX_NavMeshObject.h" #include "RAS_MeshObject.h" @@ -117,8 +119,12 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL; int nAllVerts = 0; float *allVerts = NULL; - buildNavMeshDataByDerivedMesh(dm, vertsPerPoly, nAllVerts, allVerts, ndtris, dtris, - npolys, dmeshes, polys, dtrisToPolysMap, dtrisToTrisMap, trisToFacesMap); + buildNavMeshDataByDerivedMesh(dm, &vertsPerPoly, &nAllVerts, &allVerts, &ndtris, &dtris, + &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, &trisToFacesMap); + + MEM_freeN(dtrisToPolysMap); + MEM_freeN(dtrisToTrisMap); + MEM_freeN(trisToFacesMap); unsigned short *verticesMap = new unsigned short[nAllVerts]; memset(verticesMap, 0xffff, sizeof(unsigned short)*nAllVerts); @@ -207,6 +213,8 @@ bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts, } } } + + MEM_freeN(allVerts); } else { @@ -445,7 +453,12 @@ bool KX_NavMeshObject::BuildNavMesh() m_navMesh->init(data, dataSize, true); delete [] vertices; - delete [] polys; + + /* navmesh conversion is using C guarded alloc for memory allocaitons */ + MEM_freeN(polys); + if (dmeshes) MEM_freeN(dmeshes); + if (dtris) MEM_freeN(dtris); + if (dvertices) { delete [] dvertices; |