diff --git a/projectfiles_vc9/blender/modifiers/modifiers.vcproj b/projectfiles_vc9/blender/modifiers/modifiers.vcproj index f2c738a0c5d..8e93c61b481 100644 --- a/projectfiles_vc9/blender/modifiers/modifiers.vcproj +++ b/projectfiles_vc9/blender/modifiers/modifiers.vcproj @@ -182,7 +182,7 @@ cellsize = 0.3f; - nmmd->cellheight = 0.2f; - nmmd->agentmaxslope = 45.0f; - nmmd->agentmaxclimb = 0.9f; - nmmd->agentheight = 2.0f; - nmmd->agentradius = 0.6f; - nmmd->edgemaxlen = 12.0f; - nmmd->edgemaxerror = 1.3f; - nmmd->regionminsize = 50.f; - nmmd->regionmergesize = 20.f; - nmmd->vertsperpoly = 6; - nmmd->detailsampledist = 6.0f; - nmmd->detailsamplemaxerror = 1.0f; -} - -static void copyData(ModifierData *md, ModifierData *target) -{ - NavMeshModifierData *nmmd = (NavMeshModifierData*) md; - NavMeshModifierData *tnmmd = (NavMeshModifierData*) target; - -} - -static DerivedMesh *createNavMesh(NavMeshModifierData *mmd,DerivedMesh *dm) -{ - int i; - DerivedMesh *result; - int numVerts, numEdges, numFaces; - int maxVerts = dm->getNumVerts(dm); - int maxEdges = dm->getNumEdges(dm); - int maxFaces = dm->getNumFaces(dm); - - numVerts = numEdges = numFaces = 0; - - result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2); - - for(i = 0; i < maxVerts; i++) { - MVert inMV; - MVert *mv = CDDM_get_vert(result, numVerts); - float co[3]; - - dm->getVert(dm, i, &inMV); - - copy_v3_v3(co, inMV.co); - DM_copy_vert_data(dm, result, i, numVerts, 1); - *mv = inMV; - numVerts++; - - - { - MVert *mv2 = CDDM_get_vert(result, numVerts); - DM_copy_vert_data(dm, result, i, numVerts, 1); - *mv2 = *mv; - co[2] +=.5f; - copy_v3_v3(mv2->co, co); - numVerts++; - } - - } - - for(i = 0; i < maxEdges; i++) { - MEdge inMED; - MEdge *med = CDDM_get_edge(result, numEdges); - - dm->getEdge(dm, i, &inMED); - - DM_copy_edge_data(dm, result, i, numEdges, 1); - *med = inMED; - numEdges++; - - med->v1 = inMED.v1*2; - med->v2 = inMED.v2*2; - //med->flag |= ME_EDGEDRAW | ME_EDGERENDER; - - { - MEdge *med2 = CDDM_get_edge(result, numEdges); - - DM_copy_edge_data(dm, result, i, numEdges, 1); - *med2 = *med; - numEdges++; - - med2->v1 += 1; - med2->v2 += 1; - } - } - - for(i = 0; i < maxFaces; i++) { - MFace inMF; - MFace *mf = CDDM_get_face(result, numFaces); - - dm->getFace(dm, i, &inMF); - - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf = inMF; - numFaces++; - - mf->v1 = inMF.v1*2; - mf->v2 = inMF.v2*2; - mf->v3 = inMF.v3*2; - mf->v4 = inMF.v4*2; - - { - MFace *mf2 = CDDM_get_face(result, numFaces); - DM_copy_face_data(dm, result, i, numFaces, 1); - *mf2 = *mf; - - mf2->v1 += 1; - mf2->v2 += 1; - mf2->v3 += 1; - if(inMF.v4) mf2->v4 += 1; - - //test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3); - numFaces++; - } - } - -/* - CDDM_lower_num_verts(result, numVerts); - CDDM_lower_num_edges(result, numEdges); - CDDM_lower_num_faces(result, numFaces);*/ - - return result; -} - - -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, - int useRenderParams, int isFinalCalc) -{ - DerivedMesh *result; - - NavMeshModifierData *nmmd = (NavMeshModifierData*) md; - - result = createNavMesh(nmmd, derivedData); - - return result; -} - - -ModifierTypeInfo modifierType_NavMesh = { - /* name */ "NavMesh", - /* structName */ "NavMeshModifierData", - /* structSize */ sizeof(NavMeshModifierData), - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh, - /* copyData */ copyData, - /* deformVerts */ 0, - /* deformVertsEM */ 0, - /* deformMatricesEM */ 0, - /* applyModifier */ applyModifier, - /* applyModifierEM */ 0, - /* initData */ initData, - /* requiredDataMask */ 0, - /* freeData */ 0, - /* isDisabled */ 0, - /* updateDepgraph */ 0, - /* dependsOnTime */ 0, - /* foreachObjectLink */ 0, - /* foreachIDLink */ 0, -}; diff --git a/source/blender/modifiers/intern/MOD_navmesh.cpp b/source/blender/modifiers/intern/MOD_navmesh.cpp new file mode 100644 index 00000000000..c876987e590 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_navmesh.cpp @@ -0,0 +1,392 @@ +/* +* $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) 2005 by the Blender Foundation. +* All rights reserved. +* +* Contributor(s): +* +* ***** END GPL LICENSE BLOCK ***** +* +*/ +#include +#include "Recast.h" + +extern "C"{ + +#include "DNA_meshdata_types.h" +#include "BLI_math.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_particle.h" +#include "MEM_guardedalloc.h" + + + +static void initData(ModifierData *md) +{ + NavMeshModifierData *nmmd = (NavMeshModifierData*) md; + + nmmd->cellsize = 0.3f; + nmmd->cellheight = 0.2f; + nmmd->agentmaxslope = 45.0f; + nmmd->agentmaxclimb = 0.9f; + nmmd->agentheight = 2.0f; + nmmd->agentradius = 0.6f; + nmmd->edgemaxlen = 12.0f; + nmmd->edgemaxerror = 1.3f; + nmmd->regionminsize = 50.f; + nmmd->regionmergesize = 20.f; + nmmd->vertsperpoly = 6; + nmmd->detailsampledist = 6.0f; + nmmd->detailsamplemaxerror = 1.0f; +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + NavMeshModifierData *nmmd = (NavMeshModifierData*) md; + NavMeshModifierData *tnmmd = (NavMeshModifierData*) target; + + //.todo - deep copy +} + +static DerivedMesh *buildNavMesh(NavMeshModifierData *mmd,DerivedMesh *dm) +{ + const int nverts = dm->getNumVerts(dm); + MVert *mvert = dm->getVertArray(dm); + const int nfaces = dm->getNumFaces(dm); + MFace *mface = dm->getFaceArray(dm); + float* verts; + int *tris, *tri; + float bmin[3], bmax[3]; + int i,j; + DerivedMesh* result = NULL; + rcHeightfield* solid; + unsigned char *triflags; + rcCompactHeightfield* chf; + rcContourSet *cset; + rcPolyMesh* pmesh; + rcPolyMeshDetail* dmesh; + int numVerts, numEdges, numFaces; + + //calculate count of tris + int ntris = nfaces; + for (i=0; iv4) + ntris+=1; + } + + //create verts + verts = (float*) MEM_mallocN(sizeof(float)*3*nverts, "verts"); + for (i=0; ico[0]; + verts[3*i+1] = v->co[2]; + verts[3*i+2] = v->co[1]; + } + //create tris + tris = (int*) MEM_mallocN(sizeof(int)*3*ntris, "faces"); + tri = tris; + for (i=0; iv1; tri[1]= mf->v3; tri[2]= mf->v2; + tri += 3; + if (mf->v4) + { + tri[0]= mf->v1; tri[1]= mf->v4; tri[2]= mf->v3; + tri += 3; + } + } + + rcCalcBounds(verts, nverts, bmin, bmax); + + // + // Step 1. Initialize build config. + // + rcConfig cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.cs = mmd->cellsize; + cfg.ch = mmd->cellheight; + cfg.walkableSlopeAngle = mmd->agentmaxslope; + cfg.walkableHeight = (int)ceilf(mmd->agentheight/ cfg.ch); + cfg.walkableClimb = (int)floorf(mmd->agentmaxclimb / cfg.ch); + cfg.walkableRadius = (int)ceilf(mmd->agentradius / cfg.cs); + cfg.maxEdgeLen = (int)(mmd->edgemaxlen/ mmd->cellsize); + cfg.maxSimplificationError = mmd->edgemaxerror; + cfg.minRegionSize = (int)rcSqr(mmd->regionminsize); + cfg.mergeRegionSize = (int)rcSqr(mmd->regionmergesize); + cfg.maxVertsPerPoly = mmd->vertsperpoly; + cfg.detailSampleDist = mmd->detailsampledist< 0.9f ? 0 : mmd->cellsize * mmd->detailsampledist; + cfg.detailSampleMaxError = mmd->cellheight * mmd->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); + + // + // Step 2. Rasterize input polygon soup. + // + // Allocate voxel heightfield where we rasterize our input data to. + solid = new rcHeightfield; + if (!solid) + return NULL; + + if (!rcCreateHeightfield(*solid, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch)) + return NULL; + + // Allocate array that can hold triangle flags. + triflags = (unsigned char*) MEM_mallocN(sizeof(unsigned char)*ntris, "triflags"); + if (!triflags) + return NULL; + // 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); + MEM_freeN(triflags); + MEM_freeN(verts); + MEM_freeN(tris); + + // + // Step 3. Filter walkables surfaces. + // + rcFilterLedgeSpans(cfg.walkableHeight, cfg.walkableClimb, *solid); + rcFilterWalkableLowHeightSpans(cfg.walkableHeight, *solid); + + // + // Step 4. Partition walkable surface to simple regions. + // + + chf = new rcCompactHeightfield; + if (!chf) + return NULL; + if (!rcBuildCompactHeightfield(cfg.walkableHeight, cfg.walkableClimb, RC_WALKABLE, *solid, *chf)) + return NULL; + + delete solid; + + // Prepare for region partitioning, by calculating distance field along the walkable surface. + if (!rcBuildDistanceField(*chf)) + return NULL; + + // Partition the walkable surface into simple regions without holes. + if (!rcBuildRegions(*chf, cfg.walkableRadius, cfg.borderSize, cfg.minRegionSize, cfg.mergeRegionSize)) + return NULL; + + // + // Step 5. Trace and simplify region contours. + // + // Create contours. + cset = new rcContourSet; + if (!cset) + return NULL; + + if (!rcBuildContours(*chf, cfg.maxSimplificationError, cfg.maxEdgeLen, *cset)) + return NULL; + + // + // Step 6. Build polygons mesh from contours. + // + pmesh = new rcPolyMesh; + if (!pmesh) + return NULL; + if (!rcBuildPolyMesh(*cset, cfg.maxVertsPerPoly, *pmesh)) + return NULL; + + + // + // Step 7. Create detail mesh which allows to access approximate height on each polygon. + // + + dmesh = new rcPolyMeshDetail; + if (!dmesh) + return NULL; + + if (!rcBuildPolyMeshDetail(*pmesh, *chf, cfg.detailSampleDist, cfg.detailSampleMaxError, *dmesh)) + return NULL; + + delete chf; + delete cset; + + + // + // Create blender mesh from detail poly mesh + // + + numVerts = dmesh->nverts; + numFaces = dmesh->ntris; + numEdges = dmesh->ntris*3; + + result = CDDM_new(numVerts, numEdges, numFaces); + //copy verts + for(i = 0; i < numVerts; i++) { + MVert *mv = CDDM_get_vert(result, i); + copy_v3_v3(mv->co, &dmesh->verts[3*i]); + SWAP(float, mv->co[1], mv->co[2]); + } + + //create faces and edges + numFaces = numEdges = 0; + for (i=0; inmeshes; i++) + { + unsigned short vbase = dmesh->meshes[4*i+0]; + unsigned short vnum = dmesh->meshes[4*i+1]; + unsigned short tribase = dmesh->meshes[4*i+2]; + unsigned short trinum = dmesh->meshes[4*i+3]; + + for (j=0; jtris[4*(tribase+j)]; + MFace *mf = CDDM_get_face(result, numFaces); + MEdge *med; + mf->v1 = vbase + tri[0]; + mf->v2 = vbase + tri[1]; + mf->v3 = vbase + tri[2]; + numFaces++; + + { + int e1=0, e2=2; + for (;e1<3; e2=e1++) + { + med = CDDM_get_edge(result, numEdges); + med->v1 = vbase + tri[e2]; + med->v2 = vbase + tri[e1]; + numEdges++; + } + } + } + } + + + delete pmesh; + delete dmesh; + + return result; +} + +static DerivedMesh *testCreateNavMesh(NavMeshModifierData *mmd,DerivedMesh *dm) +{ + int i; + DerivedMesh *result; + int numVerts, numEdges, numFaces; + int maxVerts = dm->getNumVerts(dm); + int maxEdges = dm->getNumEdges(dm); + int maxFaces = dm->getNumFaces(dm); + +/* MVert *mv; + MEdge *med; + MFace *mf; + numVerts = numEdges = numFaces = 0; + + result = CDDM_new(3, 3, 1); + mv = CDDM_get_vert(result, 0); + mv->co[0] = -10; mv->co[1] = -10; mv->co[2] = 0; + mv = CDDM_get_vert(result, 1); + mv->co[0] = -10; mv->co[1] = 10; mv->co[2] = 0; + mv = CDDM_get_vert(result, 2); + mv->co[0] = 10; mv->co[1] = -10; mv->co[2] = 0; + + med = CDDM_get_edge(result, 0); + med->v1 = 0; med->v1 = 1; + med = CDDM_get_edge(result, 1); + med->v1 = 1; med->v1 = 2; + med = CDDM_get_edge(result, 2); + med->v1 = 2; med->v1 = 0; + + mf = CDDM_get_face(result, 0); + mf->v1 = 0; mf->v2 = 1; mf->v3 = 2; +*/ + + result = CDDM_new(maxVerts, maxEdges, maxFaces); + numVerts = numEdges = numFaces = 0; + for(i = 0; i < maxVerts; i++) { + MVert inMV; + MVert *mv = CDDM_get_vert(result, numVerts); + float co[3]; + dm->getVert(dm, i, &inMV); + copy_v3_v3(co, inMV.co); + SWAP(float, co[1], co[2]); + *mv = inMV; + mv->co[2] +=.5f; + numVerts++; + } + + for(i = 0; i < maxEdges; i++) { + MEdge inMED; + MEdge *med = CDDM_get_edge(result, numEdges); + dm->getEdge(dm, i, &inMED); + *med = inMED; + numEdges++; + } + + for(i = 0; i < maxFaces; i++) { + MFace inMF; + MFace *mf = CDDM_get_face(result, numFaces); + dm->getFace(dm, i, &inMF); + *mf = inMF; + numFaces++; + } + + return result; +} + + +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, + int useRenderParams, int isFinalCalc) +{ + DerivedMesh *result; + + NavMeshModifierData *nmmd = (NavMeshModifierData*) md; + + //for test + //result = testCreateNavMesh(nmmd, derivedData); + result = buildNavMesh(nmmd, derivedData); + + return result; +} + + +ModifierTypeInfo modifierType_NavMesh = { + /* name */ "NavMesh", + /* structName */ "NavMeshModifierData", + /* structSize */ sizeof(NavMeshModifierData), + /* type */ eModifierTypeType_Constructive, + /* flags */ eModifierTypeFlag_AcceptsMesh, + /* copyData */ copyData, + /* deformVerts */ 0, + /* deformVertsEM */ 0, + /* deformMatricesEM */ 0, + /* applyModifier */ applyModifier, + /* applyModifierEM */ 0, + /* initData */ initData, + /* requiredDataMask */ 0, + /* freeData */ 0, + /* isDisabled */ 0, + /* updateDepgraph */ 0, + /* dependsOnTime */ 0, + /* foreachObjectLink */ 0, + /* foreachIDLink */ 0, +}; + +}; \ No newline at end of file diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp index 2c423558768..f4fea3f29f6 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.cpp +++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp @@ -115,8 +115,6 @@ bool KX_NavMeshObject::BuildVertIndArrays(RAS_MeshObject* meshobj, float *&verti MFace *mface = dm->getFaceArray(dm); int numpolys = dm->getNumFaces(dm); int numverts = dm->getNumVerts(dm); - int* index = (int*)dm->getFaceDataArray(dm, CD_ORIGINDEX); - MTFace *tface = (MTFace *)dm->getFaceDataArray(dm, CD_MTFACE); nverts = numverts; if (nverts >= 0xffff)