navmesh: convert object_navmesh.cpp to plain c.
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 27 Sep 2011 09:09:43 +0000 (09:09 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 27 Sep 2011 09:09:43 +0000 (09:09 +0000)
extern/recastnavigation/recast-capi.cpp
extern/recastnavigation/recast-capi.h
source/blender/editors/object/CMakeLists.txt
source/blender/editors/object/SConscript
source/blender/editors/object/object_navmesh.c [moved from source/blender/editors/object/object_navmesh.cpp with 70% similarity]
source/blender/editors/space_view3d/view3d_edit.c
source/blender/windowmanager/intern/wm_event_system.c

index 52c4cdc..2348497 100644 (file)
@@ -35,3 +35,218 @@ int recast_buildMeshAdjacency(unsigned short* polys, const int npolys,
 {
        return (int) buildMeshAdjacency(polys, npolys, nverts, vertsPerPoly);
 }
+
+void recast_calcBounds(const float *verts, int nv, float *bmin, float *bmax)
+{
+       rcCalcBounds(verts, nv, bmin, bmax);
+}
+
+void recast_calcGridSize(const float *bmin, const float *bmax, float cs, int *w, int *h)
+{
+       rcCalcGridSize(bmin, bmax, cs, w, h);
+}
+
+struct recast_heightfield *recast_newHeightfield(void)
+{
+       return (struct recast_heightfield *) (new rcHeightfield);
+}
+
+void recast_destroyHeightfield(struct recast_heightfield *heightfield)
+{
+       delete (rcHeightfield *) heightfield;
+}
+
+int recast_createHeightfield(struct recast_heightfield *hf, int width, int height,
+                       const float *bmin, const float* bmax, float cs, float ch)
+{
+       return rcCreateHeightfield(*(rcHeightfield *)hf, width, height, bmin, bmax, cs, ch);
+}
+
+void recast_markWalkableTriangles(const float walkableSlopeAngle,const float *verts, int nv,
+                       const int *tris, int nt, unsigned char *flags)
+{
+       rcMarkWalkableTriangles(walkableSlopeAngle, verts, nv, tris, nt, flags);
+}
+
+void recast_rasterizeTriangles(const float *verts, int nv, const int *tris,
+                       const unsigned char *flags, int nt, struct recast_heightfield *solid)
+{
+       rcRasterizeTriangles(verts, nv, tris, flags, nt, *(rcHeightfield *) solid);
+}
+
+void recast_filterLedgeSpans(const int walkableHeight, const int walkableClimb,
+                       struct recast_heightfield *solid)
+{
+       rcFilterLedgeSpans(walkableHeight, walkableClimb, *(rcHeightfield *) solid);
+}
+
+void recast_filterWalkableLowHeightSpans(int walkableHeight, struct recast_heightfield *solid)
+{
+       rcFilterWalkableLowHeightSpans(walkableHeight, *(rcHeightfield *) solid);
+}
+
+struct recast_compactHeightfield *recast_newCompactHeightfield(void)
+{
+       return (struct recast_compactHeightfield *) (new rcCompactHeightfield);
+}
+
+void recast_destroyCompactHeightfield(struct recast_compactHeightfield *compactHeightfield)
+{
+       delete (rcCompactHeightfield *) compactHeightfield;
+}
+
+int recast_buildCompactHeightfield(const int walkableHeight, const int walkableClimb,
+                       unsigned char flags, struct recast_heightfield *hf, struct recast_compactHeightfield *chf)
+{
+       int rcFlags = 0;
+
+       if(flags & RECAST_WALKABLE)
+               rcFlags |= RC_WALKABLE;
+
+       if(flags & RECAST_REACHABLE)
+               rcFlags |= RC_REACHABLE;
+
+       return rcBuildCompactHeightfield(walkableHeight, walkableClimb, rcFlags,
+                       *(rcHeightfield *) hf, *(rcCompactHeightfield *) chf);
+}
+
+int recast_buildDistanceField(struct recast_compactHeightfield *chf)
+{
+       return rcBuildDistanceField(*(rcCompactHeightfield *) chf);
+}
+
+int recast_buildRegions(struct recast_compactHeightfield *chf, int walkableRadius, int borderSize,
+       int minRegionSize, int mergeRegionSize)
+{
+       return rcBuildRegions(*(rcCompactHeightfield *) chf, walkableRadius, borderSize,
+                               minRegionSize, mergeRegionSize);
+}
+
+struct recast_contourSet *recast_newContourSet(void)
+{
+       return (struct recast_contourSet *) (new rcContourSet);
+}
+
+void recast_destroyContourSet(struct recast_contourSet *contourSet)
+{
+       delete (rcContourSet *) contourSet;
+}
+
+int recast_buildContours(struct recast_compactHeightfield *chf,
+                       const float maxError, const int maxEdgeLen, struct recast_contourSet *cset)
+{
+       return rcBuildContours(*(rcCompactHeightfield *) chf, maxError, maxEdgeLen, *(rcContourSet *) cset);
+}
+
+struct recast_polyMesh *recast_newPolyMesh(void)
+{
+       return (recast_polyMesh *) (new rcPolyMesh);
+}
+
+void recast_destroyPolyMesh(struct recast_polyMesh *polyMesh)
+{
+       delete (rcPolyMesh *) polyMesh;
+}
+
+int recast_buildPolyMesh(struct recast_contourSet *cset, int nvp, struct recast_polyMesh *mesh)
+{
+       return rcBuildPolyMesh(*(rcContourSet *) cset, nvp, * (rcPolyMesh *) mesh);
+}
+
+unsigned short *recast_polyMeshGetVerts(struct recast_polyMesh *mesh, int *nverts)
+{
+       rcPolyMesh *pmesh = (rcPolyMesh *)mesh;
+
+       if (nverts)
+               *nverts = pmesh->nverts;
+
+       return pmesh->verts;
+}
+
+void recast_polyMeshGetBoundbox(struct recast_polyMesh *mesh, float *bmin, float *bmax)
+{
+       rcPolyMesh *pmesh = (rcPolyMesh *)mesh;
+
+       if (bmin) {
+               bmin[0] = pmesh->bmin[0];
+               bmin[1] = pmesh->bmin[1];
+               bmin[2] = pmesh->bmin[2];
+       }
+
+       if (bmax) {
+               bmax[0] = pmesh->bmax[0];
+               bmax[1] = pmesh->bmax[1];
+               bmax[2] = pmesh->bmax[2];
+       }
+}
+
+void recast_polyMeshGetCell(struct recast_polyMesh *mesh, float *cs, float *ch)
+{
+       rcPolyMesh *pmesh = (rcPolyMesh *)mesh;
+
+       if (cs)
+               *cs = pmesh->cs;
+
+       if (ch)
+               *ch = pmesh->ch;
+}
+
+unsigned short *recast_polyMeshGetPolys(struct recast_polyMesh *mesh, int *npolys, int *nvp)
+{
+       rcPolyMesh *pmesh = (rcPolyMesh *)mesh;
+
+       if (npolys)
+               *npolys = pmesh->npolys;
+
+       if (nvp)
+               *nvp = pmesh->nvp;
+
+       return pmesh->polys;
+}
+
+struct recast_polyMeshDetail *recast_newPolyMeshDetail(void)
+{
+       return (struct recast_polyMeshDetail *) (new rcPolyMeshDetail);
+}
+
+void recast_destroyPolyMeshDetail(struct recast_polyMeshDetail *polyMeshDetail)
+{
+       delete (rcPolyMeshDetail *) polyMeshDetail;
+}
+
+int recast_buildPolyMeshDetail(const struct recast_polyMesh *mesh, const struct recast_compactHeightfield *chf,
+                       const float sampleDist, const float sampleMaxError, struct recast_polyMeshDetail *dmesh)
+{
+       return rcBuildPolyMeshDetail(*(rcPolyMesh *) mesh, *(rcCompactHeightfield *) chf,
+                       sampleDist, sampleMaxError, *(rcPolyMeshDetail *) dmesh);
+}
+
+float *recast_polyMeshDetailGetVerts(struct recast_polyMeshDetail *mesh, int *nverts)
+{
+       rcPolyMeshDetail *dmesh = (rcPolyMeshDetail *)mesh;
+
+       if (nverts)
+               *nverts = dmesh->nverts;
+
+       return dmesh->verts;
+}
+
+unsigned char *recast_polyMeshDetailGetTris(struct recast_polyMeshDetail *mesh, int *ntris)
+{
+       rcPolyMeshDetail *dmesh = (rcPolyMeshDetail *)mesh;
+
+       if (ntris)
+               *ntris = dmesh->ntris;
+
+       return dmesh->tris;
+}
+
+unsigned short *recast_polyMeshDetailGetMeshes(struct recast_polyMeshDetail *mesh, int *nmeshes)
+{
+       rcPolyMeshDetail *dmesh = (rcPolyMeshDetail *)mesh;
+
+       if (nmeshes)
+               *nmeshes = dmesh->nmeshes;
+
+       return dmesh->meshes;
+}
index 0d20fdf..58fe08e 100644 (file)
 extern "C" {
 #endif
 
+struct recast_polyMesh;
+struct recast_polyMeshDetail;
+struct recast_heightfield;
+struct recast_compactHeightfield;
+struct recast_contourSet;
+
+enum recast_SpanFlags
+{
+       RECAST_WALKABLE = 0x01,
+       RECAST_REACHABLE = 0x02
+};
+
 int recast_buildMeshAdjacency(unsigned short* polys, const int npolys,
                        const int nverts, const int vertsPerPoly);
 
+void recast_calcBounds(const float *verts, int nv, float *bmin, float *bmax);
+
+void recast_calcGridSize(const float *bmin, const float *bmax, float cs, int *w, int *h);
+
+struct recast_heightfield *recast_newHeightfield(void);
+
+void recast_destroyHeightfield(struct recast_heightfield *heightfield);
+
+int recast_createHeightfield(struct recast_heightfield *hf, int width, int height,
+                       const float *bmin, const float* bmax, float cs, float ch);
+
+void recast_markWalkableTriangles(const float walkableSlopeAngle,const float *verts, int nv,
+                       const int *tris, int nt, unsigned char *flags);
+
+void recast_rasterizeTriangles(const float *verts, int nv, const int *tris,
+                       const unsigned char *flags, int nt, struct recast_heightfield *solid);
+
+void recast_filterLedgeSpans(const int walkableHeight, const int walkableClimb,
+                       struct recast_heightfield *solid);
+
+void recast_filterWalkableLowHeightSpans(int walkableHeight, struct recast_heightfield *solid);
+
+struct recast_compactHeightfield *recast_newCompactHeightfield(void);
+
+void recast_destroyCompactHeightfield(struct recast_compactHeightfield *compactHeightfield);
+
+int recast_buildCompactHeightfield(const int walkableHeight, const int walkableClimb,
+                       unsigned char flags, struct recast_heightfield *hf, struct recast_compactHeightfield *chf);
+
+int recast_buildDistanceField(struct recast_compactHeightfield *chf);
+
+int recast_buildRegions(struct recast_compactHeightfield *chf, int walkableRadius, int borderSize,
+       int minRegionSize, int mergeRegionSize);
+
+/* Contour set */
+
+struct recast_contourSet *recast_newContourSet(void);
+
+void recast_destroyContourSet(struct recast_contourSet *contourSet);
+
+int recast_buildContours(struct recast_compactHeightfield *chf,
+                       const float maxError, const int maxEdgeLen, struct recast_contourSet *cset);
+
+/* Poly mesh */
+
+struct recast_polyMesh *recast_newPolyMesh(void);
+
+void recast_destroyPolyMesh(struct recast_polyMesh *polyMesh);
+
+int recast_buildPolyMesh(struct recast_contourSet *cset, int nvp, struct recast_polyMesh *mesh);
+
+unsigned short *recast_polyMeshGetVerts(struct recast_polyMesh *mesh, int *nverts);
+
+void recast_polyMeshGetBoundbox(struct recast_polyMesh *mesh, float *bmin, float *bmax);
+
+void recast_polyMeshGetCell(struct recast_polyMesh *mesh, float *cs, float *ch);
+
+unsigned short *recast_polyMeshGetPolys(struct recast_polyMesh *mesh, int *npolys, int *nvp);
+
+/* Poly mesh detail */
+
+struct recast_polyMeshDetail *recast_newPolyMeshDetail(void);
+
+void recast_destroyPolyMeshDetail(struct recast_polyMeshDetail *polyMeshDetail);
+
+int recast_buildPolyMeshDetail(const struct recast_polyMesh *mesh, const struct recast_compactHeightfield *chf,
+                       const float sampleDist, const float sampleMaxError, struct recast_polyMeshDetail *dmesh);
+
+float *recast_polyMeshDetailGetVerts(struct recast_polyMeshDetail *mesh, int *nverts);
+
+unsigned char *recast_polyMeshDetailGetTris(struct recast_polyMeshDetail *mesh, int *ntris);
+
+unsigned short *recast_polyMeshDetailGetMeshes(struct recast_polyMeshDetail *mesh, int *nmeshes);
+
 #ifdef __cplusplus
 }
 #endif
index b9b8ddc..b0b4f9d 100644 (file)
@@ -60,11 +60,11 @@ set(SRC
 
 if(WITH_GAMEENGINE)
        list(APPEND INC
-               ../../../../extern/recastnavigation/Recast/Include
+               ../../../../extern/recastnavigation
        )
 
        list(APPEND SRC
-               object_navmesh.cpp
+               object_navmesh.c
        )
 endif()
 
index cdda165..d473923 100644 (file)
@@ -1,13 +1,13 @@
 #!/usr/bin/python
 Import ('env')
 
-sources = env.Glob('*.c') + env.Glob('*.cpp')
+sources = env.Glob('*.c')
 
 incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
 incs += ' ../../windowmanager #/intern/guardedalloc ../../blenloader'
 incs += ' ../../makesrna ../../python ../../ikplugin'
 incs += ' ../../render/extern/include ../../gpu' # for object_bake.c
-incs += ' #extern/recastnavigation/Recast/Include'
+incs += ' #extern/recastnavigation'
 
 defs = []
 
 */
 
 #include <math.h>
-#include "Recast.h"
 
-extern "C"
-{
 #include "MEM_guardedalloc.h"
 
 #include "DNA_scene_types.h"
@@ -43,20 +40,27 @@ extern "C"
 #include "BKE_library.h"
 #include "BKE_depsgraph.h"
 #include "BKE_context.h"
+#include "BKE_main.h"
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_scene.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_cdderivedmesh.h"
+
 #include "BLI_editVert.h"
 #include "BLI_listbase.h"
 #include "BLI_utildefines.h"
-#include "ED_object.h"
 #include "BLI_math_vector.h"
 
+#include "ED_object.h"
+#include "ED_mesh.h"
+
 #include "RNA_access.h"
 
-#include "ED_mesh.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "recast-capi.h"
 
 /*mesh/mesh_intern.h */
 extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example);
@@ -65,10 +69,7 @@ extern void free_vertlist(EditMesh *em, ListBase *edve);
 extern void free_edgelist(EditMesh *em, ListBase *lb);
 extern void free_facelist(EditMesh *em, ListBase *lb);
 
-#include "WM_api.h"
-#include "WM_types.h"
-
-static void createVertsTrisData(bContext *C, LinkNode* obs, int& nverts, float*& verts, int &ntris, int*& tris)
+static void createVertsTrisData(bContext *C, LinkNode* obs, int *nverts_r, float **verts_r, int *ntris_r, int **tris_r)
 {
        MVert *mvert;
        int nfaces = 0, *tri, i, curnverts, basenverts, curnfaces;
@@ -80,13 +81,16 @@ static void createVertsTrisData(bContext *C, LinkNode* obs, int& nverts, float*&
        Scene* scene = CTX_data_scene(C);
        LinkNode* dms = NULL;
 
+       int nverts, ntris, *tris;
+       float *verts;
+
        nverts = 0;
        ntris = 0;
        //calculate number of verts and tris
        for (oblink = obs; oblink; oblink = oblink->next) 
        {
                ob = (Object*) oblink->link;    
-               DerivedMesh *dm = mesh_create_derived_no_virtual(scene, ob, NULL, CD_MASK_MESH);
+               dm = mesh_create_derived_no_virtual(scene, ob, NULL, CD_MASK_MESH);
                BLI_linklist_append(&dms, (void*)dm);
 
                nverts += dm->getNumVerts(dm);
@@ -104,8 +108,8 @@ static void createVertsTrisData(bContext *C, LinkNode* obs, int& nverts, float*&
        }
 
        //create data
-       verts = (float*) MEM_mallocN(sizeof(float)*3*nverts, "verts");
-       tris = (int*) MEM_mallocN(sizeof(int)*3*ntris, "faces");
+       verts = MEM_mallocN(sizeof(float)*3*nverts, "verts");
+       tris = MEM_mallocN(sizeof(int)*3*ntris, "faces");
 
        basenverts = 0;
        tri = tris;
@@ -152,24 +156,30 @@ static void createVertsTrisData(bContext *C, LinkNode* obs, int& nverts, float*&
                dm->release(dm);
        }
        BLI_linklist_free(dms, NULL);
+
+       *nverts_r= nverts;
+       *verts_r= verts;
+       *ntris_r= ntris;
+       *tris_r= tris;
 }
 
-static bool buildNavMesh(const RecastData& recastParams, int nverts, float* verts, int ntris, int* tris,
-                                                                rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh)
+static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts, int ntris, int *tris,
+                                                                struct recast_polyMesh **pmesh, struct recast_polyMeshDetail **dmesh)
 {
        float bmin[3], bmax[3];
-       rcHeightfield* solid;
+       struct recast_heightfield *solid;
        unsigned char *triflags;
-       rcCompactHeightfield* chf;
-       rcContourSet *cset;
+       struct recast_compactHeightfield* chf;
+       struct recast_contourSet *cset;
+       int width, height, walkableHeight, walkableClimb, walkableRadius;
+       int minRegionSize, mergeRegionSize, maxEdgeLen;
+       float detailSampleDist, detailSampleMaxError;
 
-       rcCalcBounds(verts, nverts, bmin, bmax);
+       recast_calcBounds(verts, nverts, bmin, bmax);
 
        //
        // Step 1. Initialize build config.
        //
-       rcConfig cfg;
-       memset(&cfg, 0, sizeof(cfg));
        {
 /*
                float cellsize = 0.3f;
@@ -199,6 +209,7 @@ static bool buildNavMesh(const RecastData& recastParams, int nverts, float* vert
                cfg.detailSampleDist = detailsampledist< 0.9f ? 0 : cellsize * detailsampledist;
                cfg.detailSampleMaxError = cellheight * detailsamplemaxerror;
 */
+#if 0
                cfg.cs = recastParams.cellsize;
                cfg.ch = recastParams.cellheight;
                cfg.walkableSlopeAngle = recastParams.agentmaxslope/((float)M_PI)*180.f;
@@ -213,102 +224,123 @@ static bool buildNavMesh(const RecastData& recastParams, int nverts, float* vert
                cfg.detailSampleDist = recastParams.detailsampledist< 0.9f ? 0 : 
                                                                recastParams.cellsize * recastParams.detailsampledist;
                cfg.detailSampleMaxError = recastParams.cellheight * recastParams.detailsamplemaxerror;
-
+#endif
        }
 
+       walkableHeight = (int)ceilf(recastParams->agentheight/ recastParams->cellheight);
+       walkableClimb = (int)floorf(recastParams->agentmaxclimb / recastParams->cellheight);
+       walkableRadius = (int)ceilf(recastParams->agentradius / recastParams->cellsize);
+       minRegionSize = (int)(recastParams->regionminsize * recastParams->regionminsize);
+       mergeRegionSize = (int)(recastParams->regionmergesize * recastParams->regionmergesize);
+       maxEdgeLen = (int)(recastParams->edgemaxlen/recastParams->cellsize);
+       detailSampleDist = recastParams->detailsampledist< 0.9f ? 0 : 
+                       recastParams->cellsize * recastParams->detailsampledist;
+       detailSampleMaxError = recastParams->cellheight * recastParams->detailsamplemaxerror;
+
        // Set the area where the navigation will be build.
-       vcopy(cfg.bmin, bmin);
-       vcopy(cfg.bmax, bmax);
-       rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height);
+       recast_calcGridSize(bmin, bmax, recastParams->cellsize, &width, &height);
 
        //
        // Step 2. Rasterize input polygon soup.
        //
        // Allocate voxel heightfield where we rasterize our input data to.
-       solid = new rcHeightfield;
-       if (!solid)
-               return false;
+       solid = recast_newHeightfield();
+
+       if (!recast_createHeightfield(solid, width, height, bmin, bmax, recastParams->cellsize, recastParams->cellheight)) {
+               recast_destroyHeightfield(solid);
 
-       if (!rcCreateHeightfield(*solid, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch))
-               return false;
+               return 0;
+       }
 
        // Allocate array that can hold triangle flags.
-       triflags = (unsigned char*) MEM_mallocN(sizeof(unsigned char)*ntris, "triflags");
-       if (!triflags)
-               return false;
+       triflags = MEM_callocN(sizeof(unsigned char)*ntris, "triflags");
+
        // Find triangles which are walkable based on their slope and rasterize them.
-       memset(triflags, 0, ntris*sizeof(unsigned char));
-       rcMarkWalkableTriangles(cfg.walkableSlopeAngle, verts, nverts, tris, ntris, triflags);
-       rcRasterizeTriangles(verts, nverts, tris, triflags, ntris, *solid);
+       recast_markWalkableTriangles(RAD2DEG(recastParams->agentmaxslope), verts, nverts, tris, ntris, triflags);
+       recast_rasterizeTriangles(verts, nverts, tris, triflags, ntris, solid);
        MEM_freeN(triflags);
-       MEM_freeN(verts);
-       MEM_freeN(tris);
 
        //
        // Step 3. Filter walkables surfaces.
        //
-       rcFilterLedgeSpans(cfg.walkableHeight, cfg.walkableClimb, *solid);
-       rcFilterWalkableLowHeightSpans(cfg.walkableHeight, *solid);
+       recast_filterLedgeSpans(walkableHeight, walkableClimb, solid);
+       recast_filterWalkableLowHeightSpans(walkableHeight, solid);
 
        //
        // Step 4. Partition walkable surface to simple regions.
        //
 
-       chf = new rcCompactHeightfield;
-       if (!chf)
-               return false;
-       if (!rcBuildCompactHeightfield(cfg.walkableHeight, cfg.walkableClimb, RC_WALKABLE, *solid, *chf))
-               return false;
+       chf = recast_newCompactHeightfield();
+       if (!recast_buildCompactHeightfield(walkableHeight, walkableClimb, RECAST_WALKABLE, solid, chf)) {
+               recast_destroyHeightfield(solid);
+               recast_destroyCompactHeightfield(chf);
+
+               return 0;
+       }
 
-       delete solid; 
+       recast_destroyHeightfield(solid);
 
        // Prepare for region partitioning, by calculating distance field along the walkable surface.
-       if (!rcBuildDistanceField(*chf))
-               return false;
+       if (!recast_buildDistanceField(chf)) {
+               recast_destroyCompactHeightfield(chf);
+
+               return 0;
+       }
 
        // Partition the walkable surface into simple regions without holes.
-       if (!rcBuildRegions(*chf, cfg.walkableRadius, cfg.borderSize, cfg.minRegionSize, cfg.mergeRegionSize))
-               return false;
+       if (!recast_buildRegions(chf, walkableRadius, 0, minRegionSize, mergeRegionSize)) {
+               recast_destroyCompactHeightfield(chf);
+
+               return 0;
+       }
 
        //
        // Step 5. Trace and simplify region contours.
        //
        // Create contours.
-       cset = new rcContourSet;
-       if (!cset)
-               return false;
+       cset = recast_newContourSet();
 
-       if (!rcBuildContours(*chf, cfg.maxSimplificationError, cfg.maxEdgeLen, *cset))
-               return false;
+       if (!recast_buildContours(chf, recastParams->edgemaxerror, maxEdgeLen, cset)) {
+               recast_destroyCompactHeightfield(chf);
+               recast_destroyContourSet(cset);
+
+               return 0;
+       }
 
        //
        // Step 6. Build polygons mesh from contours.
        //
-       pmesh = new rcPolyMesh;
-       if (!pmesh)
-               return false;
-       if (!rcBuildPolyMesh(*cset, cfg.maxVertsPerPoly, *pmesh))
-               return false;
+       *pmesh = recast_newPolyMesh();
+       if (!recast_buildPolyMesh(cset, recastParams->vertsperpoly, *pmesh)) {
+               recast_destroyCompactHeightfield(chf);
+               recast_destroyContourSet(cset);
+               recast_destroyPolyMesh(*pmesh);
+
+               return 0;
+       }
 
 
        //
        // Step 7. Create detail mesh which allows to access approximate height on each polygon.
        //
 
-       dmesh = new rcPolyMeshDetail;
-       if (!dmesh)
-               return false;
+       *dmesh = recast_newPolyMeshDetail();
+       if (!recast_buildPolyMeshDetail(*pmesh, chf, detailSampleDist, detailSampleMaxError, *dmesh)) {
+               recast_destroyCompactHeightfield(chf);
+               recast_destroyContourSet(cset);
+               recast_destroyPolyMesh(*pmesh);
+               recast_destroyPolyMeshDetail(*dmesh);
 
-       if (!rcBuildPolyMeshDetail(*pmesh, *chf, cfg.detailSampleDist, cfg.detailSampleMaxError, *dmesh))
-               return false;
+               return 0;
+       }
 
-       delete chf;
-       delete cset;
+       recast_destroyCompactHeightfield(chf);
+       recast_destroyContourSet(cset);
 
-       return true;
+       return 1;
 }
 
-static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh, Base* base)
+static Object* createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh, Base* base)
 {
        float co[3], rot[3];
        EditMesh *em;
@@ -319,8 +351,15 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
        Scene *scene= CTX_data_scene(C);
        Object* obedit;
        int createob = base==NULL;
+       int nverts, nmeshes, nvp;
+       unsigned short *verts, *meshes, *polys;
+       float bmin[3], cs, ch, *dverts;
+       unsigned char *tris;
+       ModifierData *md;
+
        zero_v3(co);
        zero_v3(rot);
+
        if (createob)
        {
                //create new object
@@ -347,11 +386,15 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
        }
 
        //create verts for polygon mesh
-       for(i = 0; i < pmesh->nverts; i++) {
-               v = &pmesh->verts[3*i];
-               co[0] = pmesh->bmin[0] + v[0]*pmesh->cs;
-               co[1] = pmesh->bmin[1] + v[1]*pmesh->ch;
-               co[2] = pmesh->bmin[2] + v[2]*pmesh->cs;
+       verts = recast_polyMeshGetVerts(pmesh, &nverts);
+       recast_polyMeshGetBoundbox(pmesh, bmin, NULL);
+       recast_polyMeshGetCell(pmesh, &cs, &ch);
+
+       for(i = 0; i < nverts; i++) {
+               v = &verts[3*i];
+               co[0] = bmin[0] + v[0]*cs;
+               co[1] = bmin[1] + v[1]*ch;
+               co[2] = bmin[2] + v[2]*cs;
                SWAP(float, co[1], co[2]);
                addvertlist(em, co, NULL);
        }
@@ -360,16 +403,21 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
        CustomData_add_layer_named(&em->fdata, CD_RECAST, CD_CALLOC, NULL, 0, "recastData");
 
        //create verts and faces for detailed mesh
-       for (i=0; i<dmesh->nmeshes; i++)
+       meshes = recast_polyMeshDetailGetMeshes(dmesh, &nmeshes);
+       polys = recast_polyMeshGetPolys(pmesh, NULL, &nvp);
+       dverts = recast_polyMeshDetailGetVerts(dmesh, NULL);
+       tris = recast_polyMeshDetailGetTris(dmesh, NULL);
+
+       for (i=0; i<nmeshes; i++)
        {
                int uniquevbase = em->totvert;
-               unsigned short vbase = dmesh->meshes[4*i+0];
-               unsigned short ndv = dmesh->meshes[4*i+1];
-               unsigned short tribase = dmesh->meshes[4*i+2];
-               unsigned short trinum = dmesh->meshes[4*i+3];
-               const unsigned short* p = &pmesh->polys[i*pmesh->nvp*2];
+               unsigned short vbase = meshes[4*i+0];
+               unsigned short ndv = meshes[4*i+1];
+               unsigned short tribase = meshes[4*i+2];
+               unsigned short trinum = meshes[4*i+3];
+               const unsigned short* p = &polys[i*nvp*2];
                int nv = 0;
-               for (j = 0; j < pmesh->nvp; ++j)
+               for (j = 0; j < nvp; ++j)
                {
                        if (p[j] == 0xffff) break;
                        nv++;
@@ -377,7 +425,7 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
                //create unique verts 
                for (j=nv; j<ndv; j++)
                {
-                       copy_v3_v3(co, &dmesh->verts[3*(vbase + j)]);
+                       copy_v3_v3(co, &dverts[3*(vbase + j)]);
                        SWAP(float, co[1], co[2]);
                        addvertlist(em, co, NULL);
                }
@@ -387,8 +435,10 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
                //create faces
                for (j=0; j<trinum; j++)
                {
-                       unsigned char* tri = &dmesh->tris[4*(tribase+j)];
+                       unsigned char* tri = &tris[4*(tribase+j)];
                        EditFace* newFace;
+                       int* polygonIdx;
+
                        for (k=0; k<3; k++)
                        {
                                if (tri[k]<nv)
@@ -400,15 +450,15 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
                                                                        EM_get_vert_for_index(face[1]), NULL, NULL, NULL);
 
                        //set navigation polygon idx to the custom layer
-                       int* polygonIdx = (int*)CustomData_em_get(&em->fdata, newFace->data, CD_RECAST);
+                       polygonIdx = (int*)CustomData_em_get(&em->fdata, newFace->data, CD_RECAST);
                        *polygonIdx = i+1; //add 1 to avoid zero idx
                }
                
                EM_free_index_arrays();
        }
 
-       delete pmesh; pmesh = NULL;
-       delete dmesh; dmesh = NULL;
+       recast_destroyPolyMesh(pmesh);
+       recast_destroyPolyMeshDetail(dmesh);
 
        BKE_mesh_end_editmesh((Mesh*)obedit->data, em);
        
@@ -427,7 +477,7 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
                rename_id((ID *)obedit, "Navmesh");
        }
        
-       ModifierData *md= modifiers_findByType(obedit, eModifierType_NavMesh);
+       md= modifiers_findByType(obedit, eModifierType_NavMesh);
        if (!md)
        {
                ED_object_modifier_add(NULL, bmain, scene, obedit, NULL, eModifierType_NavMesh);
@@ -436,16 +486,17 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
        return obedit;
 }
 
-static int create_navmesh_exec(bContext *C, wmOperator *op)
+static int create_navmesh_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Scene* scene = CTX_data_scene(C);
        int nverts, ntris;
        float* verts;
        int* tris;
-       rcPolyMesh* pmesh;
-       rcPolyMeshDetail* dmesh;
+       struct recast_polyMesh *pmesh;
+       struct recast_polyMeshDetail *dmesh;
        LinkNode* obs = NULL;
        Base* navmeshBase = NULL;
+
        //CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) //expand macros to avoid error in convertion from void*
        {
                ListBase ctx_data_list;
@@ -464,9 +515,9 @@ static int create_navmesh_exec(bContext *C, wmOperator *op)
                        BLI_linklist_append(&obs, (void*)base->object);
        }
        CTX_DATA_END;
-       createVertsTrisData(C, obs, nverts, verts, ntris, tris);
+       createVertsTrisData(C, obs, &nverts, &verts, &ntris, &tris);
        BLI_linklist_free(obs, NULL);
-       buildNavMesh(scene->gm.recastData, nverts, verts, ntris, tris, pmesh, dmesh);
+       buildNavMesh(&scene->gm.recastData, nverts, verts, ntris, tris, &pmesh, &dmesh);
        createRepresentation(C, pmesh, dmesh, navmeshBase);
 
        return OPERATOR_FINISHED;
@@ -494,7 +545,7 @@ static int assign_navpolygon_poll(bContext *C)
        return (((Mesh*)ob->data)->edit_mesh != NULL);
 }
 
-static int assign_navpolygon_exec(bContext *C, wmOperator *op)
+static int assign_navpolygon_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -551,13 +602,15 @@ void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot)
 static int compare(const void * a, const void * b){  
        return ( *(int*)a - *(int*)b );
 }
+
 static int findFreeNavPolyIndex(EditMesh* em)
 {
        //construct vector of indices
        int numfaces = em->totface;
-       int* indices = new int[numfaces];
+       int* indices = MEM_callocN(sizeof(int)*numfaces, "findFreeNavPolyIndex(indices)");
        EditFace* ef = (EditFace*)em->faces.last;
-       int idx = 0;
+       int i, idx = 0, freeIdx = 1;
+
        while(ef) 
        {
                int polyIdx = *(int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST);
@@ -565,21 +618,25 @@ static int findFreeNavPolyIndex(EditMesh* em)
                idx++;
                ef = ef->prev;
        }
+
        qsort(indices, numfaces, sizeof(int), compare);
+
        //search first free index
-       int freeIdx = 1;
-       for (int i=0; i<numfaces; i++)
+       freeIdx = 1;
+       for (i=0; i<numfaces; i++)
        {
                if (indices[i]==freeIdx)
                        freeIdx++;
                else if (indices[i]>freeIdx)
                        break;
        }
-       delete [] indices;
+
+       MEM_freeN(indices);
+
        return freeIdx;
 }
 
-static int assign_new_navpolygon_exec(bContext *C, wmOperator *op)
+static int assign_new_navpolygon_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -625,4 +682,3 @@ void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
-}
index 0854f9f..d3d7b1b 100644 (file)
@@ -3226,7 +3226,7 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *eve
        else
                WM_event_add_notifier(C, NC_SCENE|NA_EDITED, scene);
 
-       return OPERATOR_FINISHED;
+       return OPERATOR_PASS_THROUGH;
 }
 
 void VIEW3D_OT_cursor3d(wmOperatorType *ot)
index dad43b4..cfeaee1 100644 (file)
@@ -1270,10 +1270,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
                if(ot)
                        retval= wm_operator_invoke(C, ot, event, properties, NULL, FALSE);
        }
-
        /* Finished and pass through flag as handled */
-       if(retval == (OPERATOR_FINISHED|OPERATOR_PASS_THROUGH))
-               return WM_HANDLER_HANDLED;
 
        /* Modal unhandled, break */
        if(retval == (OPERATOR_PASS_THROUGH|OPERATOR_RUNNING_MODAL))