- fixed bug in steering actuator: calculate 2d distance to target for seeking and...
authorNick Samarin <nicks1987@bigmir.net>
Thu, 29 Jul 2010 14:06:48 +0000 (14:06 +0000)
committerNick Samarin <nicks1987@bigmir.net>
Thu, 29 Jul 2010 14:06:48 +0000 (14:06 +0000)
- added possibility to add navmesh modifier manually in order to transform manually created mesh to navigation mesh (with navigation polygons data layer)
- added possibility to use existed navigation mesh object for navmesh generation (so new object won't be created, but existed object will be updated)

extern/recastnavigation/BlenderNavMesh/NavMeshConversion.cpp
source/blender/editors/object/object_navmesh.cpp
source/blender/makesrna/intern/rna_modifier.c
source/blender/modifiers/intern/MOD_navmesh.cpp
source/gameengine/Ketsji/KX_SteeringActuator.cpp

index ed02a27cc43c13057299424a62951edf25fba6a9..ca11ed68c54dd0ca27c10241945dd50acab5b846 100644 (file)
@@ -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;
        }
 
 
index f7527e2d5d5a812aa3277d82ab638f77dfb6741f..b8728e35a546c78046533c4c20018935804c68fb 100644 (file)
@@ -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)
index 83252e404e088b60bc9a85c8e8134c32e70acf6f..5c5f854f05b568617ae1558a34c036c80d9425e5 100644 (file)
@@ -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
index 8f9142458883ee599bb2dbcc4acc38ce22d67eac..851615769ab8f60f139a93ef58c6ba282c299c38 100644 (file)
@@ -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,
index 78b6247b775988ab5883c59e5766de1dfe4c1231..f70826d16f9fd99f23ccdba69659eb6e8bfda790 100644 (file)
@@ -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;