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')
for f in df:
# This files aren't used anymore
if f in ['.Blanguages', '.bfont.ttf']:
continue
if not env['WITH_BF_INTERNATIONAL']:
if 'locale' in dp:
continue
if f == '.Blanguages':
continue
if not env['WITH_BF_FREETYPE']:
if f.endswith('.ttf'):
continue

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

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

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

@ -3,6 +3,7 @@
Import('env')
sources = env.Glob('Recast/Source/*.cpp') + env.Glob('Detour/Source/*.cpp')
sources += ['recast-capi.cpp']
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 */
#define BLENDER_VERSION_CHAR
/* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE alpha
#define BLENDER_VERSION_CYCLE beta
struct ListBase;
struct MemFile;

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

@ -357,10 +357,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()

@ -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'
@ -93,10 +93,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']

@ -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,30 +63,34 @@ 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);
float d = abx[0]*abx[0]+abx[2]*abx[2];
float t = abx[0]*dx[0]+abx[2]*dx[2];
float d, t;
sub_v3_v3v3(abx, b,a);
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)
t /= d;
if (t < 0)
@ -93,33 +99,42 @@ float distPointToSegmentSq(const float* point, const float* a, const float* b)
t = 1;
dx[0] = a[0] + t*abx[0] - point[0];
dx[2] = a[2] + t*abx[2] - point[2];
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;
int nfaces;
MFace *faces;
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]);
}
//calculate number of tris
int nfaces = dm->getNumFaces(dm);
MFace *faces = dm->getFaceArray(dm);
nfaces = dm->getNumFaces(dm);
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 +142,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 +163,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 +216,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)
{
@ -201,11 +233,12 @@ bool buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys,
{
if (nv==capacity)
{
unsigned short* newPolyBig;
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);
memcpy(newPolyBig, newPoly, sizeof(unsigned short)*nv);
delete newPoly;
MEM_freeN(newPoly);
newPoly = newPolyBig;
}
newPoly[nv++] = dtris[tri*3*2+edge];
@ -216,7 +249,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 +260,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 +269,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 +282,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 +306,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 +329,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 +337,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 +383,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 +419,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 +435,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 +447,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 +494,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;

@ -136,7 +136,11 @@ char *BLI_ungzip_to_mem(const char *from_file, int *size_r)
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);
*size_r= size;

@ -67,7 +67,7 @@ set(SRC
intern/MOD_mirror.c
intern/MOD_multires.c
intern/MOD_ngoninterp.c
intern/MOD_navmesh.cpp
intern/MOD_navmesh.c
intern/MOD_none.c
intern/MOD_particleinstance.c
intern/MOD_particlesystem.c
@ -119,11 +119,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()

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

@ -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 int bit(int a, int 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 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,
};
};

@ -371,7 +371,6 @@ static PyObject *py_blf_load(PyObject *UNUSED(self), PyObject *args)
return PyLong_FromLong(BLF_load(filename));
}
#ifdef INTERNATIONAL
PyDoc_STRVAR(py_blf_gettext_doc,
".. function:: gettext(msgid)\n"
"\n"
@ -384,6 +383,7 @@ PyDoc_STRVAR(py_blf_gettext_doc,
);
static PyObject *py_blf_gettext(PyObject *UNUSED(self), PyObject *value)
{
#ifdef INTERNATIONAL
if ((U.transopts & USER_DOTRANSLATE) && (U.transopts & USER_TR_IFACE)) {
const char *msgid= _PyUnicode_AsString(value);
if(msgid == NULL) {
@ -393,11 +393,12 @@ static PyObject *py_blf_gettext(PyObject *UNUSED(self), PyObject *value)
return PyUnicode_FromString(BLF_gettext(msgid));
}
else {
else
#endif /* INTERNATIONAL */
{
return Py_INCREF(value), value;
}
}
#endif /* INTERNATIONAL */
/*----------------------------MODULE INIT-------------------------*/
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},
{"size", (PyCFunction) py_blf_size, METH_VARARGS, py_blf_size_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},
#endif
{NULL, NULL, 0, NULL}
};

@ -30,4 +30,5 @@ void BPy_init_modules(void);
extern PyObject *bpy_package_py;
/* 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();
BPY_atexit_init(); /* this can init any time */
BPY_atexit_register(); /* this can init any time */
#ifndef WITH_PYTHON_MODULE
py_tstate= PyGILState_GetThisThreadState();
@ -262,6 +262,8 @@ void BPY_python_end(void)
bpy_intern_string_exit();
BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */
Py_Finalize();
#ifdef TIME_PY_RUN

@ -1,5 +1,5 @@
/*
* $Id:
* $Id$
*
* ***** 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 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
* this is intended, but if its problematic it could be changed
* - campbell */
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 *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_register);
Py_DECREF(atexit_func);
Py_DECREF(args);
if(ret) {
@ -72,5 +74,19 @@ void BPY_atexit_init(void)
else { /* should never happen */
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();
BLF_exit();
#ifdef INTERNATIONAL
BLF_free_unifont();
#endif
ANIM_keyingset_infos_exit();

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

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