svn merge ^/trunk/blender -r40395:40405

This commit is contained in:
Campbell Barton 2011-09-23 10:58:20 +00:00
commit 161c3861bc
23 changed files with 393 additions and 204 deletions

@ -522,11 +522,13 @@ if env['OURPLATFORM']!='darwin':
dn.remove('_svn') dn.remove('_svn')
for f in df: for f in df:
# This files aren't used anymore
if f in ['.Blanguages', '.bfont.ttf']:
continue
if not env['WITH_BF_INTERNATIONAL']: if not env['WITH_BF_INTERNATIONAL']:
if 'locale' in dp: if 'locale' in dp:
continue continue
if f == '.Blanguages':
continue
if not env['WITH_BF_FREETYPE']: if not env['WITH_BF_FREETYPE']:
if f.endswith('.ttf'): if f.endswith('.ttf'):
continue continue

@ -96,7 +96,7 @@ BF_ZLIB_INC = '${BF_ZLIB}/include'
BF_ZLIB_LIB = 'libz' BF_ZLIB_LIB = 'libz'
BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib' BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
WITH_BF_INTERNATIONAL = False WITH_BF_INTERNATIONAL = True
BF_GETTEXT = LIBDIR + '/gettext' BF_GETTEXT = LIBDIR + '/gettext'
BF_GETTEXT_INC = '${BF_GETTEXT}/include' BF_GETTEXT_INC = '${BF_GETTEXT}/include'

@ -564,11 +564,11 @@ def AppIt(target=None, source=None, env=None):
# print cmd # print cmd
commands.getoutput(cmd) commands.getoutput(cmd)
cmd = installdir + '/%s.app/Contents/MacOS/%s'%(binary,VERSION) cmd = installdir + '/%s.app/Contents/MacOS/%s'%(binary,VERSION)
shutil.copy(bldroot + '/release/bin/.blender/.bfont.ttf', cmd) cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/datafiles'%(installdir, binary, VERSION)
shutil.copy(bldroot + '/release/bin/.blender/.Blanguages', cmd)
cmd = 'cp -R %s/release/bin/%s/locale %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary)
commands.getoutput(cmd) commands.getoutput(cmd)
cmd = 'cp -R %s/release/bin/%s/locale %s/%s.app/Contents/MacOS/%s/'%(bldroot,VERSION,installdir,binary,VERSION) cmd = 'cp -R %s/release/bin/.blender/locale %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'cp -R %s/release/bin/.blender/fonts %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd) commands.getoutput(cmd)
cmd = 'cp %s/release/bin/%s/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary) cmd = 'cp %s/release/bin/%s/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary)
commands.getoutput(cmd) commands.getoutput(cmd)
@ -581,10 +581,6 @@ def AppIt(target=None, source=None, env=None):
if binary == 'blender':#not copy everything for blenderplayer if binary == 'blender':#not copy everything for blenderplayer
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION) cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd) commands.getoutput(cmd)
cmd = 'cp -R %s/release/ui %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'cp -R %s/release/io %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(installdir,binary, binary) cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(installdir,binary, binary)
commands.getoutput(cmd) commands.getoutput(cmd)

@ -34,6 +34,10 @@ set(INC_SYS
) )
set(SRC set(SRC
recast-capi.cpp
recast-capi.h
Detour/Source/DetourCommon.cpp Detour/Source/DetourCommon.cpp
Detour/Source/DetourNode.cpp Detour/Source/DetourNode.cpp
Detour/Source/DetourStatNavMesh.cpp Detour/Source/DetourStatNavMesh.cpp

@ -3,6 +3,7 @@
Import('env') Import('env')
sources = env.Glob('Recast/Source/*.cpp') + env.Glob('Detour/Source/*.cpp') sources = env.Glob('Recast/Source/*.cpp') + env.Glob('Detour/Source/*.cpp')
sources += ['recast-capi.cpp']
incs = 'Recast/Include Detour/Include' incs = 'Recast/Include Detour/Include'

37
extern/recastnavigation/recast-capi.cpp vendored Normal file

@ -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);
}

42
extern/recastnavigation/recast-capi.h vendored Normal file

@ -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

@ -53,7 +53,7 @@ extern "C" {
/* can be left blank, otherwise a,b,c... etc with no quotes */ /* can be left blank, otherwise a,b,c... etc with no quotes */
#define BLENDER_VERSION_CHAR #define BLENDER_VERSION_CHAR
/* alpha/beta/rc/release, docs use this */ /* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE alpha #define BLENDER_VERSION_CYCLE beta
struct ListBase; struct ListBase;
struct MemFile; struct MemFile;

@ -32,32 +32,32 @@
struct DerivedMesh; struct DerivedMesh;
/* navmesh_conversion.cpp */ /* navmesh_conversion.c */
bool buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int& vertsPerPoly, int buildNavMeshDataByDerivedMesh(struct DerivedMesh *dm, int *vertsPerPoly,
int &nverts, float *&verts, int *nverts, float **verts,
int &ndtris, unsigned short *&dtris, int *ndtris, unsigned short **dtris,
int& npolys, unsigned short *&dmeshes, int *npolys, unsigned short **dmeshes,
unsigned short*& polys, int *&dtrisToPolysMap, unsigned short **polys, int **dtrisToPolysMap,
int *&dtrisToTrisMap, int *&trisToFacesMap); int **dtrisToTrisMap, int **trisToFacesMap);
bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, int buildRawVertIndicesData(struct DerivedMesh* dm, int *nverts, float **verts,
int &ntris, unsigned short *&tris, int *&trisToFacesMap, int *ntris, unsigned short **tris, int **trisToFacesMap,
int *&recastData); int **recastData);
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 ntris, const unsigned short *tris,
const int* recastData, const int* trisToFacesMap, const int* recastData, const int* trisToFacesMap,
int &ndtris, unsigned short *&dtris, int *ndtris, unsigned short **dtris,
int &npolys, unsigned short *&dmeshes, unsigned short *&polys, int *npolys, unsigned short **dmeshes, unsigned short **polys,
int &vertsPerPoly, int *&dtrisToPolysMap, int *&dtrisToTrisMap); int *vertsPerPoly, int **dtrisToPolysMap, int **dtrisToTrisMap);
bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
unsigned short* polys, const unsigned short* dmeshes, unsigned short* polys, const unsigned short* dmeshes,
const float* verts, const unsigned short* dtris, const float* verts, const unsigned short* dtris,
const int* dtrisToPolysMap); const int* dtrisToPolysMap);
int polyNumVerts(const unsigned short* p, const int vertsPerPoly); 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); int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx);
float distPointToSegmentSq(const float* point, const float* a, const float* b); float distPointToSegmentSq(const float* point, const float* a, const float* b);

@ -357,10 +357,10 @@ endif()
if(WITH_GAMEENGINE) if(WITH_GAMEENGINE)
list(APPEND INC_SYS list(APPEND INC_SYS
../../../extern/recastnavigation/Recast/Include ../../../extern/recastnavigation
) )
list(APPEND SRC list(APPEND SRC
intern/navmesh_conversion.cpp intern/navmesh_conversion.c
BKE_navmesh_conversion.h BKE_navmesh_conversion.h
) )
endif() endif()

@ -2,7 +2,7 @@
Import ('env') Import ('env')
import os import os
sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp') sources = env.Glob('intern/*.c')
incs = '. #/intern/guardedalloc #/intern/memutil' incs = '. #/intern/guardedalloc #/intern/memutil'
incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager' incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager'
@ -93,10 +93,10 @@ if env['WITH_BF_LZMA']:
defs.append('WITH_LZMA') defs.append('WITH_LZMA')
if env['WITH_BF_GAMEENGINE']: if env['WITH_BF_GAMEENGINE']:
incs += ' #/extern/recastnavigation/Recast/Include' incs += ' #/extern/recastnavigation'
defs.append('WITH_GAMEENGINE') defs.append('WITH_GAMEENGINE')
else: 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'): if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC'] incs += ' ' + env['BF_PTHREADS_INC']

@ -29,30 +29,32 @@
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include "Recast.h"
extern "C"{ #include "MEM_guardedalloc.h"
#include "BKE_navmesh_conversion.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "BKE_navmesh_conversion.h"
#include "BKE_cdderivedmesh.h" #include "BKE_cdderivedmesh.h"
#include "BLI_math.h" #include "BLI_math.h"
}
#include "recast-capi.h"
inline float area2(const float* a, const float* b, const float* c) 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]); 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; return area2(a, b, c) < 0;
} }
int polyNumVerts(const unsigned short* p, const int vertsPerPoly) int polyNumVerts(const unsigned short* p, const int vertsPerPoly)
{ {
int nv = 0; int i, nv = 0;
for (int i=0; i<vertsPerPoly; i++) for (i=0; i<vertsPerPoly; i++)
{ {
if (p[i]==0xffff) if (p[i]==0xffff)
break; break;
@ -61,30 +63,34 @@ int polyNumVerts(const unsigned short* p, const int vertsPerPoly)
return nv; 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) if (nv<3)
return false; return 0;
for (int j=0; j<nv; j++) for (j=0; j<nv; j++)
{ {
const float* v = &verts[3*p[j]]; const float* v = &verts[3*p[j]];
const float* v_next = &verts[3*p[(j+1)%nv]]; const float* v_next = &verts[3*p[(j+1)%nv]];
const float* v_prev = &verts[3*p[(nv+j-1)%nv]]; const float* v_prev = &verts[3*p[(nv+j-1)%nv]];
if (!left(v_prev, v, v_next)) 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 distPointToSegmentSq(const float* point, const float* a, const float* b)
{ {
float abx[3], dx[3]; float abx[3], dx[3];
vsub(abx, b,a); float d, t;
vsub(dx, point,a);
float d = abx[0]*abx[0]+abx[2]*abx[2]; sub_v3_v3v3(abx, b,a);
float t = abx[0]*dx[0]+abx[2]*dx[2]; sub_v3_v3v3(dx, point,a);
d = abx[0]*abx[0]+abx[2]*abx[2];
t = abx[0]*dx[0]+abx[2]*dx[2];
if (d > 0) if (d > 0)
t /= d; t /= d;
if (t < 0) if (t < 0)
@ -93,33 +99,42 @@ float distPointToSegmentSq(const float* point, const float* a, const float* b)
t = 1; t = 1;
dx[0] = a[0] + t*abx[0] - point[0]; dx[0] = a[0] + t*abx[0] - point[0];
dx[2] = a[2] + t*abx[2] - point[2]; dx[2] = a[2] + t*abx[2] - point[2];
return dx[0]*dx[0] + dx[2]*dx[2]; return dx[0]*dx[0] + dx[2]*dx[2];
} }
bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts, int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r,
int &ntris, unsigned short *&tris, int *&trisToFacesMap, int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r,
int *&recastData) int **recastData)
{ {
int vi, fi, triIdx;
int nverts, ntris;
int *trisToFacesMap;
float *verts;
unsigned short *tris, *tri;
int nfaces;
MFace *faces;
nverts = dm->getNumVerts(dm); nverts = dm->getNumVerts(dm);
if (nverts>=0xffff) if (nverts>=0xffff)
{ {
printf("Converting navmesh: Error! Too many vertices. Max number of vertices %d\n", 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); dm->getVertCos(dm, (float(*)[3])verts);
//flip coordinates //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]); SWAP(float, verts[3*vi+1], verts[3*vi+2]);
} }
//calculate number of tris //calculate number of tris
int nfaces = dm->getNumFaces(dm); nfaces = dm->getNumFaces(dm);
MFace *faces = dm->getFaceArray(dm); faces = dm->getFaceArray(dm);
ntris = nfaces; ntris = nfaces;
for (int fi=0; fi<nfaces; fi++) for (fi=0; fi<nfaces; fi++)
{ {
MFace* face = &faces[fi]; MFace* face = &faces[fi];
if (face->v4) if (face->v4)
@ -127,11 +142,11 @@ bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts,
} }
//copy and transform to triangles (reorder on the run) //copy and transform to triangles (reorder on the run)
trisToFacesMap = new int[ntris]; trisToFacesMap = MEM_callocN(sizeof(int)*ntris, "buildRawVertIndicesData trisToFacesMap");
tris = new unsigned short[3*ntris]; tris = MEM_callocN(sizeof(unsigned short)*3*ntris, "buildRawVertIndicesData tris");
unsigned short* tri = tris; tri = tris;
int triIdx = 0; triIdx = 0;
for (int fi=0; fi<nfaces; fi++) for (fi=0; fi<nfaces; fi++)
{ {
MFace* face = &faces[fi]; MFace* face = &faces[fi];
tri[3*triIdx+0] = (unsigned short) face->v1; tri[3*triIdx+0] = (unsigned short) face->v1;
@ -148,32 +163,46 @@ bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float *&verts,
} }
//carefully, recast data is just reference to data in derived mesh //carefully, recast data is just reference to data in derived mesh
recastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); *recastData = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST);
return true;
*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, unsigned short* polys, const unsigned short* dmeshes,
const float* verts, const unsigned short* dtris, const float* verts, const unsigned short* dtris,
const int* dtrisToPolysMap) const int* dtrisToPolysMap)
{ {
int polyidx;
int capacity = vertsPerPoly; 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); 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; int nv = 0;
//search border //search border
int btri = -1; int tri, btri = -1;
int bedge = -1; int edge, bedge = -1;
int dtrisNum = dmeshes[polyidx*4+3]; int dtrisNum = dmeshes[polyidx*4+3];
int dtrisBase = dmeshes[polyidx*4+2]; int dtrisBase = dmeshes[polyidx*4+2];
unsigned char *traversedTris = new unsigned char[dtrisNum]; unsigned char *traversedTris = MEM_callocN(sizeof(unsigned char)*dtrisNum, "buildPolygonsByDetailedMeshes traversedTris");
memset(traversedTris, 0, dtrisNum*sizeof(unsigned char)); unsigned short* adjustedPoly;
for (int j=0; j<dtrisNum && btri==-1;j++) int adjustedNv;
int allBorderTraversed;
for (j=0; j<dtrisNum && btri==-1;j++)
{ {
int curpolytri = dtrisBase+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]; unsigned short neighbortri = dtris[curpolytri*3*2+3+k];
if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1)
@ -187,12 +216,15 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
if (btri==-1 || bedge==-1) if (btri==-1 || bedge==-1)
{ {
//can't find triangle with border edge //can't find triangle with border edge
return false; MEM_freeN(traversedTris);
MEM_freeN(newPoly);
return 0;
} }
newPoly[nv++] = dtris[btri*3*2+bedge]; newPoly[nv++] = dtris[btri*3*2+bedge];
int tri = btri; tri = btri;
int edge = (bedge+1)%3; edge = (bedge+1)%3;
traversedTris[tri-dtrisBase] = 1; traversedTris[tri-dtrisBase] = 1;
while (tri!=btri || edge!=bedge) while (tri!=btri || edge!=bedge)
{ {
@ -201,11 +233,12 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
{ {
if (nv==capacity) if (nv==capacity)
{ {
unsigned short* newPolyBig;
capacity += vertsPerPoly; capacity += vertsPerPoly;
unsigned short* newPolyBig = new unsigned short[capacity]; newPolyBig = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPolyBig");
memset(newPolyBig, 0xff, sizeof(unsigned short)*capacity); memset(newPolyBig, 0xff, sizeof(unsigned short)*capacity);
memcpy(newPolyBig, newPoly, sizeof(unsigned short)*nv); memcpy(newPolyBig, newPoly, sizeof(unsigned short)*nv);
delete newPoly; MEM_freeN(newPoly);
newPoly = newPolyBig; newPoly = newPolyBig;
} }
newPoly[nv++] = dtris[tri*3*2+edge]; newPoly[nv++] = dtris[tri*3*2+edge];
@ -216,7 +249,7 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
{ {
//move to next tri //move to next tri
int twinedge = -1; int twinedge = -1;
for (int k=0; k<3; k++) for (k=0; k<3; k++)
{ {
if (dtris[neighbortri*3*2+3+k] == tri) if (dtris[neighbortri*3*2+3+k] == tri)
{ {
@ -227,6 +260,7 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
if (twinedge==-1) if (twinedge==-1)
{ {
printf("Converting navmesh: Error! Can't find neighbor edge - invalid adjacency info\n"); printf("Converting navmesh: Error! Can't find neighbor edge - invalid adjacency info\n");
MEM_freeN(traversedTris);
goto returnLabel; goto returnLabel;
} }
tri = neighbortri; tri = neighbortri;
@ -235,9 +269,9 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
} }
} }
unsigned short* adjustedPoly = new unsigned short[nv]; adjustedPoly = MEM_callocN(sizeof(unsigned short)*nv, "buildPolygonsByDetailedMeshes adjustedPoly");
int adjustedNv = 0; adjustedNv = 0;
for (size_t i=0; i<(size_t)nv; i++) for (i=0; i<nv; i++)
{ {
unsigned short prev = newPoly[(nv+i-1)%nv]; unsigned short prev = newPoly[(nv+i-1)%nv];
unsigned short cur = newPoly[i]; unsigned short cur = newPoly[i];
@ -248,22 +282,22 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
adjustedPoly[adjustedNv++] = cur; adjustedPoly[adjustedNv++] = cur;
} }
memcpy(newPoly, adjustedPoly, adjustedNv*sizeof(unsigned short)); memcpy(newPoly, adjustedPoly, adjustedNv*sizeof(unsigned short));
delete adjustedPoly; MEM_freeN(adjustedPoly);
nv = adjustedNv; nv = adjustedNv;
bool allBorderTraversed = true; allBorderTraversed = 1;
for (size_t i=0; i<(size_t)dtrisNum; i++) for (i=0; i<dtrisNum; i++)
{ {
if (traversedTris[i]==0) if (traversedTris[i]==0)
{ {
//check whether it has border edges //check whether it has border edges
int curpolytri = dtrisBase+i; 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]; unsigned short neighbortri = dtris[curpolytri*3*2+3+k];
if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1)
{ {
allBorderTraversed = false; allBorderTraversed = 0;
break; break;
} }
} }
@ -272,16 +306,19 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
if (nv<=vertsPerPoly && allBorderTraversed) if (nv<=vertsPerPoly && allBorderTraversed)
{ {
for (int i=0; i<nv; i++) for (i=0; i<nv; i++)
{ {
polys[polyidx*vertsPerPoly*2+i] = newPoly[i]; polys[polyidx*vertsPerPoly*2+i] = newPoly[i];
} }
} }
MEM_freeN(traversedTris);
} }
returnLabel: returnLabel:
delete newPoly; MEM_freeN(newPoly);
return true;
return 1;
} }
struct SortContext struct SortContext
@ -292,7 +329,7 @@ struct SortContext
/* XXX: not thread-safe, but it's called only from modifiers stack /* XXX: not thread-safe, but it's called only from modifiers stack
which isn't threaded. Anyway, better to avoid this in the future */ 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) static int compareByData(const void * a, const void * b)
{ {
@ -300,32 +337,41 @@ static int compareByData(const void * a, const void * b)
_qsort_context->recastData[_qsort_context->trisToFacesMap[*(int*)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 ntris, const unsigned short *tris,
const int* recastData, const int* trisToFacesMap, const int* recastData, const int* trisToFacesMap,
int &ndtris, unsigned short *&dtris, int *ndtris_r, unsigned short **dtris_r,
int &npolys, unsigned short *&dmeshes, unsigned short *&polys, int *npolys_r, unsigned short **dmeshes_r, unsigned short **polys_r,
int &vertsPerPoly, int *&dtrisToPolysMap, int *&dtrisToTrisMap) 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) if (!recastData)
{ {
printf("Converting navmesh: Error! Can't find recast custom data\n"); printf("Converting navmesh: Error! Can't find recast custom data\n");
return false; return 0;
} }
//sort the triangles by polygon idx //sort the triangles by polygon idx
int* trisMapping = new int[ntris]; for (i=0; i<ntris; i++)
for (int i=0; i<ntris; i++)
trisMapping[i]=i; trisMapping[i]=i;
SortContext context;
context.recastData = recastData; context.recastData = recastData;
context.trisToFacesMap = trisToFacesMap; context.trisToFacesMap = trisToFacesMap;
_qsort_context = &context; _qsort_context = &context;
qsort(trisMapping, ntris, sizeof(int), compareByData); qsort(trisMapping, ntris, sizeof(int), compareByData);
//search first valid triangle - triangle of convex polygon //search first valid triangle - triangle of convex polygon
int validTriStart = -1; validTriStart = -1;
for (int i=0; i< ntris; i++) for (i=0; i< ntris; i++)
{ {
if (recastData[trisToFacesMap[trisMapping[i]]]>0) if (recastData[trisToFacesMap[trisMapping[i]]]>0)
{ {
@ -337,28 +383,30 @@ bool buildNavMeshData(const int nverts, const float* verts,
if (validTriStart<0) if (validTriStart<0)
{ {
printf("Converting navmesh: Error! No valid polygons in mesh\n"); printf("Converting navmesh: Error! No valid polygons in mesh\n");
delete trisMapping; MEM_freeN(trisMapping);
return false; return 0;
} }
ndtris = ntris-validTriStart; ndtris = ntris-validTriStart;
//fill dtris to faces mapping //fill dtris to faces mapping
dtrisToTrisMap = new int[ndtris]; dtrisToTrisMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToTrisMap");
memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris*sizeof(int)); memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris*sizeof(int));
delete trisMapping; trisMapping=NULL; MEM_freeN(trisMapping);
//create detailed mesh triangles - copy only valid triangles //create detailed mesh triangles - copy only valid triangles
//and reserve memory for adjacency info //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); 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); 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 //create new recast data corresponded to dtris and renumber for continuous indices
int prevPolyIdx=-1, curPolyIdx, newPolyIdx=0; prevPolyIdx = -1;
dtrisToPolysMap = new int[ndtris]; newPolyIdx = 0;
for (int i=0; i<ndtris; i++) dtrisToPolysMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToPolysMap");
for (i=0; i<ndtris; i++)
{ {
curPolyIdx = recastData[trisToFacesMap[dtrisToTrisMap[i]]]; curPolyIdx = recastData[trisToFacesMap[dtrisToTrisMap[i]]];
if (curPolyIdx!=prevPolyIdx) if (curPolyIdx!=prevPolyIdx)
@ -371,15 +419,15 @@ bool buildNavMeshData(const int nverts, const float* verts,
//build adjacency info for detailed mesh triangles //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 //create detailed mesh description for each navigation polygon
npolys = dtrisToPolysMap[ndtris-1]; 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)); memset(dmeshes, 0, npolys*4*sizeof(unsigned short));
unsigned short *dmesh = NULL; dmesh = NULL;
int prevpolyidx = 0; prevpolyidx = 0;
for (int i=0; i<ndtris; i++) for (i=0; i<ndtris; i++)
{ {
int curpolyidx = dtrisToPolysMap[i]; int curpolyidx = dtrisToPolysMap[i];
if (curpolyidx!=prevpolyidx) if (curpolyidx!=prevpolyidx)
@ -387,7 +435,7 @@ bool buildNavMeshData(const int nverts, const float* verts,
if (curpolyidx!=prevpolyidx+1) if (curpolyidx!=prevpolyidx+1)
{ {
printf("Converting navmesh: Error! Wrong order of detailed mesh faces\n"); printf("Converting navmesh: Error! Wrong order of detailed mesh faces\n");
return false; return 0;
} }
dmesh = dmesh==NULL ? dmeshes : dmesh+4; dmesh = dmesh==NULL ? dmeshes : dmesh+4;
dmesh[2] = (unsigned short)i; //tbase dmesh[2] = (unsigned short)i; //tbase
@ -399,33 +447,43 @@ bool buildNavMeshData(const int nverts, const float* verts,
//create navigation polygons //create navigation polygons
vertsPerPoly = 6; 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); memset(polys, 0xff, sizeof(unsigned short)*vertsPerPoly*2*npolys);
buildPolygonsByDetailedMeshes(vertsPerPoly, npolys, polys, dmeshes, verts, dtris, dtrisToPolysMap); 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 buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly,
int &nverts, float *&verts, int *nverts, float **verts,
int &ndtris, unsigned short *&dtris, int *ndtris, unsigned short **dtris,
int& npolys, unsigned short *&dmeshes, int *npolys, unsigned short **dmeshes,
unsigned short*& polys, int *&dtrisToPolysMap, unsigned short **polys, int **dtrisToPolysMap,
int *&dtrisToTrisMap, int *&trisToFacesMap) int **dtrisToTrisMap, int **trisToFacesMap)
{ {
bool res = true; int res = 1;
int ntris =0, *recastData=NULL; int ntris = 0, *recastData=NULL;
unsigned short *tris=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) if (!res)
{ {
printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n"); printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n");
goto exit; goto exit;
} }
res = buildNavMeshData(nverts, verts, ntris, tris, recastData, trisToFacesMap, res = buildNavMeshData(*nverts, *verts, ntris, tris, recastData, *trisToFacesMap,
ndtris, dtris, npolys, dmeshes,polys, vertsPerPoly, ndtris, dtris, npolys, dmeshes,polys, vertsPerPoly,
dtrisToPolysMap, dtrisToTrisMap); dtrisToPolysMap, dtrisToTrisMap);
if (!res) if (!res)
@ -436,15 +494,15 @@ bool buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int& vertsPerPoly,
exit: exit:
if (tris) if (tris)
delete tris; MEM_freeN(tris);
return res; return res;
} }
int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx) int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx)
{ {
int res = -1; int i, res = -1;
for(int i=0; i<vertsPerPoly; i++) for(i=0; i<vertsPerPoly; i++)
{ {
if (p[i]==0xffff) if (p[i]==0xffff)
break; break;

@ -136,7 +136,11 @@ char *BLI_ungzip_to_mem(const char *from_file, int *size_r)
else break; else break;
} }
if(mem && alloc_size!=size) if(size==0) {
MEM_freeN(mem);
mem= NULL;
}
else if(alloc_size!=size)
mem= MEM_reallocN(mem, size); mem= MEM_reallocN(mem, size);
*size_r= size; *size_r= size;

@ -67,7 +67,7 @@ set(SRC
intern/MOD_mirror.c intern/MOD_mirror.c
intern/MOD_multires.c intern/MOD_multires.c
intern/MOD_ngoninterp.c intern/MOD_ngoninterp.c
intern/MOD_navmesh.cpp intern/MOD_navmesh.c
intern/MOD_none.c intern/MOD_none.c
intern/MOD_particleinstance.c intern/MOD_particleinstance.c
intern/MOD_particlesystem.c intern/MOD_particlesystem.c
@ -119,11 +119,11 @@ if(NOT WITH_MOD_FLUID)
endif() endif()
if(WITH_GAMEENGINE) if(WITH_GAMEENGINE)
# for MOD_navmesh.cpp # for MOD_navmesh.c
add_definitions(-DWITH_GAMEENGINE) add_definitions(-DWITH_GAMEENGINE)
list(APPEND INC list(APPEND INC
../gpu ../gpu
../../../extern/recastnavigation/Recast/Include ../../../extern/recastnavigation
) )
endif() endif()

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
Import ('env') Import ('env')
sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp') sources = env.Glob('intern/*.c')
incs = '. ./intern' incs = '. ./intern'
incs += ' #/intern/guardedalloc #/intern/decimation/extern #/intern/bsp/extern #/intern/elbeem/extern #/extern/glew/include' 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') defs.append('DISABLE_ELBEEM')
if env['WITH_BF_GAMEENGINE']: if env['WITH_BF_GAMEENGINE']:
incs += ' #/extern/recastnavigation/Recast/Include' incs += ' #/extern/recastnavigation'
defs.append('WITH_GAMEENGINE') defs.append('WITH_GAMEENGINE')
env.BlenderLib ( libname = 'bf_modifiers', sources = sources, env.BlenderLib ( libname = 'bf_modifiers', sources = sources,

@ -27,22 +27,17 @@
*/ */
#include <math.h> #include <math.h>
#ifdef WITH_GAMEENGINE #include "DNA_mesh_types.h"
# include "Recast.h" #include "DNA_meshdata_types.h"
#endif
extern "C"{
#ifdef WITH_GAMEENGINE #ifdef WITH_GAMEENGINE
# include "recast-capi.h"
# include "BKE_navmesh_conversion.h" # include "BKE_navmesh_conversion.h"
# include "GL/glew.h" # include "GL/glew.h"
# include "GPU_buffers.h" # include "GPU_buffers.h"
# include "GPU_draw.h" # include "GPU_draw.h"
#endif #endif
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BLI_math.h" #include "BLI_math.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
@ -53,12 +48,12 @@ extern "C"{
#include "BKE_customdata.h" #include "BKE_customdata.h"
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
inline int bit(int a, int b) static int bit(int a, int b)
{ {
return (a & (1 << b)) >> b; return (a & (1 << b)) >> b;
} }
inline void intToCol(int i, float* col) static void intToCol(int i, float* col)
{ {
int r = bit(i, 0) + bit(i, 3) * 2 + 1; int r = bit(i, 0) + bit(i, 3) * 2 + 1;
int g = bit(i, 1) + bit(i, 4) * 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 */ /* 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 *nmmd = (NavMeshModifierData*) md; */
/* NavMeshModifierData *tnmmd = (NavMeshModifierData*) target; */ /* NavMeshModifierData *tnmmd = (NavMeshModifierData*) target; */
@ -94,10 +89,12 @@ static void drawNavMeshColored(DerivedMesh *dm)
MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT); MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT);
MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE); MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE);
int* polygonIdx = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST); int* polygonIdx = (int*)CustomData_get_layer(&dm->faceData, CD_RECAST);
if (!polygonIdx)
return;
const float BLACK_COLOR[3] = {0.f, 0.f, 0.f}; const float BLACK_COLOR[3] = {0.f, 0.f, 0.f};
float col[3]; float col[3];
if (!polygonIdx)
return;
/* /*
//UI_ThemeColor(TH_WIRE); //UI_ThemeColor(TH_WIRE);
glDisable(GL_LIGHTING); 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)) static void navDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
{ {
(void) setDrawOptions;
drawNavMeshColored(dm); drawNavMeshColored(dm);
} }
static void navDM_drawFacesSolid(DerivedMesh *dm, static void navDM_drawFacesSolid(DerivedMesh *dm,
float (*partial_redraw_planes)[4], 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); //drawFacesSolid_original(dm, partial_redraw_planes, fast, setMaterial);
drawNavMeshColored(dm); drawNavMeshColored(dm);
} }
#endif /* WITH_GAMEENGINE */ #endif /* WITH_GAMEENGINE */
static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,DerivedMesh *dm) static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *UNUSED(mmd), DerivedMesh *dm)
{ {
#ifdef WITH_GAMEENGINE #ifdef WITH_GAMEENGINE
DerivedMesh *result; DerivedMesh *result;
int maxFaces = dm->getNumFaces(dm); 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); result = CDDM_copy(dm);
if (!CustomData_has_layer(&result->faceData, CD_RECAST)) 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, CustomData_add_layer_named(&result->faceData, CD_RECAST, CD_DUPLICATE,
sourceRecastData, maxFaces, "recastData"); 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->drawFacesTex = navDM_drawFacesTex;
result->drawFacesSolid = navDM_drawFacesSolid; result->drawFacesSolid = navDM_drawFacesSolid;
//process mesh //process mesh
int vertsPerPoly=0, nverts=0, ndtris=0, npolys=0; res = buildNavMeshDataByDerivedMesh(dm, &vertsPerPoly, &nverts, &verts, &ndtris, &dtris,
float* verts=NULL; &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap,
unsigned short *dtris=NULL, *dmeshes=NULL, *polys=NULL; &trisToFacesMap);
int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL;
bool res = buildNavMeshDataByDerivedMesh(dm, vertsPerPoly, nverts, verts, ndtris, dtris,
npolys, dmeshes, polys, dtrisToPolysMap, dtrisToTrisMap,
trisToFacesMap);
if (res) if (res)
{ {
size_t polyIdx;
//invalidate concave polygon //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]; unsigned short* poly = &polys[polyIdx*2*vertsPerPoly];
if (!polyIsConvex(poly, vertsPerPoly, verts)) if (!polyIsConvex(poly, vertsPerPoly, verts))
@ -189,7 +194,9 @@ static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,Deriv
unsigned short *dmesh = &dmeshes[4*polyIdx]; unsigned short *dmesh = &dmeshes[4*polyIdx];
unsigned short tbase = dmesh[2]; unsigned short tbase = dmesh[2];
unsigned short tnum = dmesh[3]; 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 triidx = dtrisToTrisMap[tbase+ti];
unsigned short faceidx = trisToFacesMap[triidx]; unsigned short faceidx = trisToFacesMap[triidx];
@ -207,19 +214,19 @@ static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,Deriv
//clean up //clean up
if (verts!=NULL) if (verts!=NULL)
delete verts; MEM_freeN(verts);
if (dtris!=NULL) if (dtris!=NULL)
delete dtris; MEM_freeN(dtris);
if (dmeshes!=NULL) if (dmeshes!=NULL)
delete dmeshes; MEM_freeN(dmeshes);
if (polys!=NULL) if (polys!=NULL)
delete polys; MEM_freeN(polys);
if (dtrisToPolysMap!=NULL) if (dtrisToPolysMap!=NULL)
delete dtrisToPolysMap; MEM_freeN(dtrisToPolysMap);
if (dtrisToTrisMap!=NULL) if (dtrisToTrisMap!=NULL)
delete dtrisToTrisMap; MEM_freeN(dtrisToTrisMap);
if (trisToFacesMap!=NULL) if (trisToFacesMap!=NULL)
delete trisToFacesMap; MEM_freeN(trisToFacesMap);
return result; return result;
#else // WITH_GAMEENGINE #else // WITH_GAMEENGINE
@ -237,11 +244,11 @@ static int isDisabled(ModifierData *md, int useRenderParams)
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData,
int useRenderParams, int isFinalCalc) int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{ {
DerivedMesh *result = NULL; DerivedMesh *result = NULL;
NavMeshModifierData *nmmd = (NavMeshModifierData*) md; 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 ) if (ob->body_type!=OB_BODY_TYPE_NAVMESH || !hasRecastData )
{ {
//convert to nav mesh object: //convert to nav mesh object:
@ -255,10 +262,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
Mesh* obmesh = (Mesh *)ob->data; Mesh* obmesh = (Mesh *)ob->data;
if (obmesh) if (obmesh)
{ {
int i;
int numFaces = obmesh->totface; int numFaces = obmesh->totface;
int* recastData;
CustomData_add_layer_named(&obmesh->fdata, CD_RECAST, CD_CALLOC, NULL, numFaces, "recastData"); CustomData_add_layer_named(&obmesh->fdata, CD_RECAST, CD_CALLOC, NULL, numFaces, "recastData");
int* recastData = (int*)CustomData_get_layer(&obmesh->fdata, CD_RECAST); recastData = (int*)CustomData_get_layer(&obmesh->fdata, CD_RECAST);
for (int i=0; i<numFaces; i++) for (i=0; i<numFaces; i++)
{ {
recastData[i] = i+1; recastData[i] = i+1;
} }
@ -296,5 +305,3 @@ ModifierTypeInfo modifierType_NavMesh = {
/* foreachObjectLink */ 0, /* foreachObjectLink */ 0,
/* foreachIDLink */ 0, /* foreachIDLink */ 0,
}; };
};

@ -371,7 +371,6 @@ static PyObject *py_blf_load(PyObject *UNUSED(self), PyObject *args)
return PyLong_FromLong(BLF_load(filename)); return PyLong_FromLong(BLF_load(filename));
} }
#ifdef INTERNATIONAL
PyDoc_STRVAR(py_blf_gettext_doc, PyDoc_STRVAR(py_blf_gettext_doc,
".. function:: gettext(msgid)\n" ".. function:: gettext(msgid)\n"
"\n" "\n"
@ -384,6 +383,7 @@ PyDoc_STRVAR(py_blf_gettext_doc,
); );
static PyObject *py_blf_gettext(PyObject *UNUSED(self), PyObject *value) static PyObject *py_blf_gettext(PyObject *UNUSED(self), PyObject *value)
{ {
#ifdef INTERNATIONAL
if ((U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_IFACE)) { if ((U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_IFACE)) {
const char *msgid= _PyUnicode_AsString(value); const char *msgid= _PyUnicode_AsString(value);
if(msgid == NULL) { if(msgid == NULL) {
@ -393,11 +393,12 @@ static PyObject *py_blf_gettext(PyObject *UNUSED(self), PyObject *value)
return PyUnicode_FromString(BLF_gettext(msgid)); return PyUnicode_FromString(BLF_gettext(msgid));
} }
else { else
#endif /* INTERNATIONAL */
{
return Py_INCREF(value), value; return Py_INCREF(value), value;
} }
} }
#endif /* INTERNATIONAL */
/*----------------------------MODULE INIT-------------------------*/ /*----------------------------MODULE INIT-------------------------*/
static PyMethodDef BLF_methods[] = { static PyMethodDef BLF_methods[] = {
@ -414,9 +415,7 @@ static PyMethodDef BLF_methods[] = {
{"shadow_offset", (PyCFunction) py_blf_shadow_offset, METH_VARARGS, py_blf_shadow_offset_doc}, {"shadow_offset", (PyCFunction) py_blf_shadow_offset, METH_VARARGS, py_blf_shadow_offset_doc},
{"size", (PyCFunction) py_blf_size, METH_VARARGS, py_blf_size_doc}, {"size", (PyCFunction) py_blf_size, METH_VARARGS, py_blf_size_doc},
{"load", (PyCFunction) py_blf_load, METH_VARARGS, py_blf_load_doc}, {"load", (PyCFunction) py_blf_load, METH_VARARGS, py_blf_load_doc},
#ifdef INTERNATIONAL
{"gettext", (PyCFunction) py_blf_gettext, METH_O, py_blf_gettext_doc}, {"gettext", (PyCFunction) py_blf_gettext, METH_O, py_blf_gettext_doc},
#endif
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

@ -30,4 +30,5 @@ void BPy_init_modules(void);
extern PyObject *bpy_package_py; extern PyObject *bpy_package_py;
/* bpy_interface_atexit.c */ /* bpy_interface_atexit.c */
void BPY_atexit_init(void); void BPY_atexit_register(void);
void BPY_atexit_unregister(void);

@ -241,7 +241,7 @@ void BPY_python_start(int argc, const char **argv)
pyrna_alloc_types(); pyrna_alloc_types();
BPY_atexit_init(); /* this can init any time */ BPY_atexit_register(); /* this can init any time */
#ifndef WITH_PYTHON_MODULE #ifndef WITH_PYTHON_MODULE
py_tstate= PyGILState_GetThisThreadState(); py_tstate= PyGILState_GetThisThreadState();
@ -262,6 +262,8 @@ void BPY_python_end(void)
bpy_intern_string_exit(); bpy_intern_string_exit();
BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */
Py_Finalize(); Py_Finalize();
#ifdef TIME_PY_RUN #ifdef TIME_PY_RUN

@ -1,5 +1,5 @@
/* /*
* $Id: * $Id$
* *
* ***** BEGIN GPL LICENSE BLOCK ***** * ***** BEGIN GPL LICENSE BLOCK *****
* *
@ -46,24 +46,26 @@ static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyOb
} }
static PyMethodDef meth_bpy_atexit= {"bpy_atexit", (PyCFunction)bpy_atexit, METH_NOARGS, NULL}; static PyMethodDef meth_bpy_atexit= {"bpy_atexit", (PyCFunction)bpy_atexit, METH_NOARGS, NULL};
static PyObject *func_bpy_atregister= NULL; /* borrowed referebce, atexit holds */
void BPY_atexit_init(void) static void atexit_func_call(const char *func_name, PyObject *atexit_func_arg)
{ {
/* note - no error checking, if any of these fail we'll get a crash /* note - no error checking, if any of these fail we'll get a crash
* this is intended, but if its problematic it could be changed * this is intended, but if its problematic it could be changed
* - campbell */ * - campbell */
PyObject *atexit_mod= PyImport_ImportModuleLevel((char *)"atexit", NULL, NULL, NULL, 0); PyObject *atexit_mod= PyImport_ImportModuleLevel((char *)"atexit", NULL, NULL, NULL, 0);
PyObject *atexit_register= PyObject_GetAttrString(atexit_mod, "register"); PyObject *atexit_func= PyObject_GetAttrString(atexit_mod, func_name);
PyObject *args= PyTuple_New(1); PyObject *args= PyTuple_New(1);
PyObject *ret; PyObject *ret;
PyTuple_SET_ITEM(args, 0, (PyObject *)PyCFunction_New(&meth_bpy_atexit, NULL)); PyTuple_SET_ITEM(args, 0, atexit_func_arg);
Py_INCREF(atexit_func_arg); /* only incref so we dont dec'ref along with 'args' */
ret= PyObject_CallObject(atexit_register, args); ret= PyObject_CallObject(atexit_func, args);
Py_DECREF(atexit_mod); Py_DECREF(atexit_mod);
Py_DECREF(atexit_register); Py_DECREF(atexit_func);
Py_DECREF(args); Py_DECREF(args);
if(ret) { if(ret) {
@ -72,5 +74,19 @@ void BPY_atexit_init(void)
else { /* should never happen */ else { /* should never happen */
PyErr_Print(); PyErr_Print();
} }
}
void BPY_atexit_register(void)
{
/* atexit module owns this new function reference */
BLI_assert(func_bpy_atregister ==NULL);
func_bpy_atregister= (PyObject *)PyCFunction_New(&meth_bpy_atexit, NULL);
atexit_func_call("register", func_bpy_atregister);
}
void BPY_atexit_unregister(void)
{
atexit_func_call("unregister", func_bpy_atregister);
func_bpy_atregister= NULL; /* don't really need to set but just incase */
} }

@ -403,7 +403,10 @@ void WM_exit_ext(bContext *C, const short do_python)
free_posebuf(); free_posebuf();
BLF_exit(); BLF_exit();
#ifdef INTERNATIONAL
BLF_free_unifont(); BLF_free_unifont();
#endif
ANIM_keyingset_infos_exit(); ANIM_keyingset_infos_exit();

@ -998,7 +998,11 @@ int main(int argc, char** argv)
// Cleanup // Cleanup
RNA_exit(); RNA_exit();
BLF_exit(); BLF_exit();
#ifdef INTERNATIONAL
BLF_free_unifont(); BLF_free_unifont();
#endif
IMB_exit(); IMB_exit();
free_nodesystem(); free_nodesystem();

@ -26,6 +26,8 @@
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
*/ */
#include "MEM_guardedalloc.h"
#include "BLI_math_vector.h" #include "BLI_math_vector.h"
#include "KX_NavMeshObject.h" #include "KX_NavMeshObject.h"
#include "RAS_MeshObject.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 *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL;
int nAllVerts = 0; int nAllVerts = 0;
float *allVerts = NULL; float *allVerts = NULL;
buildNavMeshDataByDerivedMesh(dm, vertsPerPoly, nAllVerts, allVerts, ndtris, dtris, buildNavMeshDataByDerivedMesh(dm, &vertsPerPoly, &nAllVerts, &allVerts, &ndtris, &dtris,
npolys, dmeshes, polys, dtrisToPolysMap, dtrisToTrisMap, trisToFacesMap); &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, &trisToFacesMap);
MEM_freeN(dtrisToPolysMap);
MEM_freeN(dtrisToTrisMap);
MEM_freeN(trisToFacesMap);
unsigned short *verticesMap = new unsigned short[nAllVerts]; unsigned short *verticesMap = new unsigned short[nAllVerts];
memset(verticesMap, 0xffff, sizeof(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 else
{ {
@ -445,7 +453,12 @@ bool KX_NavMeshObject::BuildNavMesh()
m_navMesh->init(data, dataSize, true); m_navMesh->init(data, dataSize, true);
delete [] vertices; 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) if (dvertices)
{ {
delete [] dvertices; delete [] dvertices;