diff options
-rw-r--r-- | extern/recastnavigation/BlenderNavMesh/NavMeshConversion.cpp | 11 | ||||
-rw-r--r-- | source/blender/editors/object/object_navmesh.cpp | 66 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_navmesh.cpp | 41 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_SteeringActuator.cpp | 6 |
5 files changed, 100 insertions, 26 deletions
diff --git a/extern/recastnavigation/BlenderNavMesh/NavMeshConversion.cpp b/extern/recastnavigation/BlenderNavMesh/NavMeshConversion.cpp index ed02a27cc43..ca11ed68c54 100644 --- a/extern/recastnavigation/BlenderNavMesh/NavMeshConversion.cpp +++ b/extern/recastnavigation/BlenderNavMesh/NavMeshConversion.cpp @@ -310,11 +310,18 @@ bool buildNavMeshData(const int nverts, const float* verts, { memcpy(dtris+3*2*i, tris+3*dtrisToTrisMap[i], sizeof(unsigned short)*3); } - //create new recast data corresponded to dtris + //create new recast data corresponded to dtris and renumber for continious indices + int prevPolyIdx=-1, curPolyIdx, newPolyIdx=0; dtrisToPolysMap = new int[ndtris]; for (int i=0; i<ndtris; i++) { - dtrisToPolysMap[i] = recastData[trisToFacesMap[dtrisToTrisMap[i]]]; + curPolyIdx = recastData[trisToFacesMap[dtrisToTrisMap[i]]]; + if (curPolyIdx!=prevPolyIdx) + { + newPolyIdx++; + prevPolyIdx=curPolyIdx; + } + dtrisToPolysMap[i] = newPolyIdx; } diff --git a/source/blender/editors/object/object_navmesh.cpp b/source/blender/editors/object/object_navmesh.cpp index f7527e2d5d5..b8728e35a54 100644 --- a/source/blender/editors/object/object_navmesh.cpp +++ b/source/blender/editors/object/object_navmesh.cpp @@ -43,6 +43,8 @@ extern "C" #include "BKE_depsgraph.h" #include "BKE_context.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_scene.h" #include "BKE_DerivedMesh.h" #include "BKE_cdderivedmesh.h" #include "BLI_editVert.h" @@ -57,6 +59,9 @@ extern "C" /*mesh/mesh_intern.h */ extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges); +extern void free_vertlist(EditMesh *em, ListBase *edve); +extern void free_edgelist(EditMesh *em, ListBase *lb); +extern void free_facelist(EditMesh *em, ListBase *lb); #include "WM_api.h" #include "WM_types.h" @@ -301,23 +306,43 @@ static bool buildNavMesh(const RecastData& recastParams, int nverts, float* vert return true; } -static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh) +static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh, Base* base) { - Object *obedit; float co[3], rot[3]; EditMesh *em; int i,j, k, polyverts; unsigned short* v; int face[3]; Scene *scene= CTX_data_scene(C); - + Object* obedit; + int createob = base==NULL; zero_v3(co); zero_v3(rot); - obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1); - ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); + if (createob) + { + //create new object + obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1); + } + else + { + obedit = base->object; + scene_select_base(scene, base); + copy_v3_v3(obedit->loc, co); + copy_v3_v3(obedit->rot, rot); + } + ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); em = BKE_mesh_get_editmesh(((Mesh *)obedit->data)); + if (!createob) + { + //clear + if(em->verts.first) free_vertlist(em, &em->verts); + if(em->edges.first) free_edgelist(em, &em->edges); + if(em->faces.first) free_facelist(em, &em->faces); + if(em->selected.first) BLI_freelistN(&(em->selected)); + } + //create verts for polygon mesh for(i = 0; i < pmesh->nverts; i++) { v = &pmesh->verts[3*i]; @@ -392,13 +417,20 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD ED_object_exit_editmode(C, EM_FREEDATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - obedit->gameflag &= ~OB_COLLISION; - obedit->gameflag |= OB_NAVMESH; - obedit->body_type = OB_BODY_TYPE_NAVMESH; - rename_id((ID *)obedit, "Navmesh"); + if (createob) + { + obedit->gameflag &= ~OB_COLLISION; + obedit->gameflag |= OB_NAVMESH; + obedit->body_type = OB_BODY_TYPE_NAVMESH; + rename_id((ID *)obedit, "Navmesh"); + } + + ModifierData *md= modifiers_findByType(obedit, eModifierType_NavMesh); + if (!md) + { + ED_object_modifier_add(NULL, scene, obedit, NULL, eModifierType_NavMesh); + } - ED_object_modifier_add(NULL, scene, obedit, NULL, eModifierType_NavMesh); - //ModifierData *md= modifiers_findByType(ob, eModifierType_NavMesh); return obedit; } @@ -411,15 +443,22 @@ static int create_navmesh_exec(bContext *C, wmOperator *op) rcPolyMesh* pmesh; rcPolyMeshDetail* dmesh; LinkNode* obs = NULL; + Base* navmeshBase = NULL; CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - BLI_linklist_append(&obs, (void*)base->object); + if (base->object->body_type==OB_BODY_TYPE_NAVMESH) + { + if (!navmeshBase || base==CTX_data_active_base(C)) + navmeshBase = base; + } + else + BLI_linklist_append(&obs, (void*)base->object); } CTX_DATA_END; createVertsTrisData(C, obs, nverts, verts, ntris, tris); BLI_linklist_free(obs, NULL); buildNavMesh(scene->gm.recastData, nverts, verts, ntris, tris, pmesh, dmesh); - createRepresentation(C, pmesh, dmesh); + createRepresentation(C, pmesh, dmesh, navmeshBase); return OPERATOR_FINISHED; } @@ -520,7 +559,6 @@ static int findFreeNavPolyIndex(EditMesh* em) qsort(indices, numfaces, sizeof(int), compare); //search first free index int freeIdx = 1; - int maxIdx = indices[numfaces-1]; for (int i=0; i<numfaces; i++) { if (indices[i]==freeIdx) diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 83252e404e0..5c5f854f05b 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -61,7 +61,6 @@ EnumPropertyItem modifier_type_items[] ={ {eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""}, {eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""}, {eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""}, - {eModifierType_NavMesh, "NAVMESH", ICON_MOD_DECIM, "Navigation mesh", ""}, {0, "", 0, "Deform", ""}, {eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""}, {eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""}, @@ -84,6 +83,7 @@ EnumPropertyItem modifier_type_items[] ={ {eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""}, {eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""}, {eModifierType_Surface, "SURFACE", ICON_MOD_PHYSICS, "Surface", ""}, + {eModifierType_NavMesh, "NAVMESH", ICON_MOD_PHYSICS, "Navigation mesh", ""}, {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME diff --git a/source/blender/modifiers/intern/MOD_navmesh.cpp b/source/blender/modifiers/intern/MOD_navmesh.cpp index 8f914245888..851615769ab 100644 --- a/source/blender/modifiers/intern/MOD_navmesh.cpp +++ b/source/blender/modifiers/intern/MOD_navmesh.cpp @@ -30,7 +30,7 @@ #include "NavMeshConversion.h" extern "C"{ - +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "BLI_math.h" #include "BKE_cdderivedmesh.h" @@ -125,9 +125,6 @@ static void navDM_drawFacesSolid(DerivedMesh *dm, static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,DerivedMesh *dm) { DerivedMesh *result; - int numVerts, numEdges, numFaces; - int maxVerts = dm->getNumVerts(dm); - int maxEdges = dm->getNumEdges(dm); int maxFaces = dm->getNumFaces(dm); result = CDDM_copy(dm); @@ -209,9 +206,39 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der { DerivedMesh *result = NULL; NavMeshModifierData *nmmd = (NavMeshModifierData*) md; + bool hasRecastData = CustomData_has_layer(&derivedData->faceData, CD_PROP_INT)>0; + if (ob->body_type!=OB_BODY_TYPE_NAVMESH || !hasRecastData ) + { + //convert to nav mesh object: + //1)set physics type + ob->gameflag &= ~OB_COLLISION; + ob->gameflag |= OB_NAVMESH; + ob->body_type = OB_BODY_TYPE_NAVMESH; + //2)add and init recast data layer + if (!hasRecastData) + { + int numFaces = derivedData->getNumFaces(derivedData); + CustomData_add_layer_named(&derivedData->faceData, CD_PROP_INT, CD_CALLOC, NULL, numFaces, "recastData"); + int* recastData = (int*)CustomData_get_layer(&derivedData->faceData, CD_PROP_INT); + for (int i=0; i<numFaces; i++) + { + recastData[i] = i+1; + } + + Mesh* obmesh = (Mesh *)ob->data; + if (obmesh) + { + CustomData_add_layer_named(&obmesh->fdata, CD_PROP_INT, CD_CALLOC, NULL, numFaces, "recastData"); + int* recastData = (int*)CustomData_get_layer(&obmesh->fdata, CD_PROP_INT); + for (int i=0; i<numFaces; i++) + { + recastData[i] = i+1; + } + } + } + } - if (ob->body_type==OB_BODY_TYPE_NAVMESH) - result = createNavMeshForVisualization(nmmd, derivedData); + result = createNavMeshForVisualization(nmmd, derivedData); return result; } @@ -223,7 +250,7 @@ ModifierTypeInfo modifierType_NavMesh = { /* structSize */ sizeof(NavMeshModifierData), /* type */ eModifierTypeType_Constructive, /* flags */ (ModifierTypeFlag) (eModifierTypeFlag_AcceptsMesh - | eModifierTypeFlag_NoUserAdd), + | eModifierTypeFlag_Single), /* copyData */ copyData, /* deformVerts */ 0, /* deformVertsEM */ 0, diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.cpp b/source/gameengine/Ketsji/KX_SteeringActuator.cpp index 78b6247b775..f70826d16f9 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.cpp +++ b/source/gameengine/Ketsji/KX_SteeringActuator.cpp @@ -173,13 +173,15 @@ bool KX_SteeringActuator::Update(double curtime, bool frame) const MT_Point3& mypos = obj->NodeGetWorldPosition(); const MT_Point3& targpos = m_target->NodeGetWorldPosition(); MT_Vector3 vectotarg = targpos - mypos; + MT_Vector3 vectotarg2d = vectotarg; + vectotarg2d.z() = 0; MT_Vector3 steervec = MT_Vector3(0, 0, 0); bool apply_steerforce = false; bool terminate = true; switch (m_mode) { case KX_STEERING_SEEK: - if (vectotarg.length2()>m_distance*m_distance) + if (vectotarg2d.length2()>m_distance*m_distance) { terminate = false; steervec = vectotarg; @@ -188,7 +190,7 @@ bool KX_SteeringActuator::Update(double curtime, bool frame) } break; case KX_STEERING_FLEE: - if (vectotarg.length2()<m_distance*m_distance) + if (vectotarg2d.length2()<m_distance*m_distance) { terminate = false; steervec = -vectotarg; |