Revision: 30816
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30816
Author:   nicks
Date:     2010-07-27 23:01:00 +0200 (Tue, 27 Jul 2010)

Log Message:
-----------
- added operators for manual assigning navigation polygon idx to mesh faces in 
edit mode
- modified conversion process to take into account changes caused by mesh 
editing
Note: conversion to dtStatNavMesh in KX_NavMeshObject hasn't worked correctly 
yet

Modified Paths:
--------------
    branches/soc-2010-nicks/release/scripts/ui/properties_data_modifier.py
    branches/soc-2010-nicks/source/blender/editors/object/object_intern.h
    branches/soc-2010-nicks/source/blender/editors/object/object_navmesh.cpp
    branches/soc-2010-nicks/source/blender/editors/object/object_ops.c
    branches/soc-2010-nicks/source/blender/modifiers/intern/MOD_navmesh.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.h

Modified: branches/soc-2010-nicks/release/scripts/ui/properties_data_modifier.py
===================================================================
--- branches/soc-2010-nicks/release/scripts/ui/properties_data_modifier.py      
2010-07-27 19:56:16 UTC (rev 30815)
+++ branches/soc-2010-nicks/release/scripts/ui/properties_data_modifier.py      
2010-07-27 21:01:00 UTC (rev 30816)
@@ -462,7 +462,12 @@
             row.label()
 
     def NAVMESH(self, layout, ob, md, wide_ui):
-        layout = self.layout
+        split = layout.split()
+        if ob.mode == 'EDIT':
+            col = split.column()
+            col.operator("object.assign_navpolygon", text="Assign poly idx")
+            col = split.column()
+            col.operator("object.assign_new_navpolygon", text="Assign new poly 
idx")
 
     def PARTICLE_INSTANCE(self, layout, ob, md, wide_ui):
         layout.prop(md, "object")

Modified: branches/soc-2010-nicks/source/blender/editors/object/object_intern.h
===================================================================
--- branches/soc-2010-nicks/source/blender/editors/object/object_intern.h       
2010-07-27 19:56:16 UTC (rev 30815)
+++ branches/soc-2010-nicks/source/blender/editors/object/object_intern.h       
2010-07-27 21:01:00 UTC (rev 30816)
@@ -224,6 +224,8 @@
 
 /* object_navmesh.cpp */
 void OBJECT_OT_create_navmesh(struct wmOperatorType *ot);
+void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot);
+void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot);
 
 #endif /* ED_OBJECT_INTERN_H */
 

Modified: 
branches/soc-2010-nicks/source/blender/editors/object/object_navmesh.cpp
===================================================================
--- branches/soc-2010-nicks/source/blender/editors/object/object_navmesh.cpp    
2010-07-27 19:56:16 UTC (rev 30815)
+++ branches/soc-2010-nicks/source/blender/editors/object/object_navmesh.cpp    
2010-07-27 21:01:00 UTC (rev 30816)
@@ -50,6 +50,8 @@
 #include "ED_object.h"
 #include "BLI_math_vector.h"
 
+#include "RNA_access.h"
+
 #include "ED_mesh.h"
 
 /*mesh/mesh_intern.h */
@@ -372,7 +374,7 @@
 
                        //set navigation polygon idx to the custom layer
                        int* polygonIdx = (int*)CustomData_em_get(&em->fdata, 
newFace->data, CD_PROP_INT);
-                       *polygonIdx = i;
+                       *polygonIdx = i+1; //add 1 to avoid zero idx
                }
                
                EM_free_index_arrays();
@@ -425,7 +427,7 @@
 void OBJECT_OT_create_navmesh(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "NavMesh";
+       ot->name= "Create navigation mesh";
        ot->description= "Create navigation mesh for selected objects";
        ot->idname= "OBJECT_OT_create_navmesh";
 
@@ -435,4 +437,145 @@
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
+
+static int assign_navpolygon_poll(bContext *C)
+{
+       Object *ob= (Object *)CTX_data_pointer_get_type(C, "object", 
&RNA_Object).data;
+       if (!ob || !ob->data)
+               return 0;
+       return (((Mesh*)ob->data)->edit_mesh != NULL);
 }
+
+static int assign_navpolygon_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
+
+       //do work here
+       int targetPolyIdx = -1;
+       EditFace *ef, *efa;
+       efa = EM_get_actFace(em, 0);
+       if (efa) 
+       {
+               if (CustomData_has_layer(&em->fdata, CD_PROP_INT))
+               {
+                       targetPolyIdx = *(int*)CustomData_em_get(&em->fdata, 
efa->data, CD_PROP_INT);
+                       targetPolyIdx = targetPolyIdx>=0? targetPolyIdx : 
-targetPolyIdx;
+                       if (targetPolyIdx>0)
+                       {
+                               //set target poly idx to other selected faces
+                               ef = (EditFace*)em->faces.last;
+                               while(ef) 
+                               {
+                                       if((ef->f & SELECT )&& ef!=efa) 
+                                       {
+                                               int* recastDataBlock = 
(int*)CustomData_em_get(&em->fdata, ef->data, CD_PROP_INT);
+                                               *recastDataBlock = 
targetPolyIdx;
+                                       }
+                                       ef = ef->prev;
+                               }
+                       }
+               }               
+       }
+       
+       DAG_id_flush_update((ID*)obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+       BKE_mesh_end_editmesh((Mesh*)obedit->data, em);
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Assign polygon index ";
+       ot->description= "Assign polygon index to face by active face";
+       ot->idname= "OBJECT_OT_assign_navpolygon";
+
+       /* api callbacks */
+       ot->poll = assign_navpolygon_poll;
+       ot->exec= assign_navpolygon_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int compare(const void * a, const void * b){  
+       return ( *(int*)a - *(int*)b );
+}
+static int findFreeNavPolyIndex(EditMesh* em)
+{
+       //construct vector of indices
+       int numfaces = em->totface;
+       int* indices = new int[numfaces];
+       EditFace* ef = (EditFace*)em->faces.last;
+       int idx = 0;
+       while(ef) 
+       {
+               int polyIdx = *(int*)CustomData_em_get(&em->fdata, ef->data, 
CD_PROP_INT);
+               indices[idx] = polyIdx;
+               idx++;
+               ef = ef->prev;
+       }
+       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)
+                       freeIdx++;
+               else if (indices[i]>freeIdx)
+                       break;
+       }
+       delete indices;
+       return freeIdx;
+}
+
+static int assign_new_navpolygon_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
+
+       EditFace *ef;
+       if (CustomData_has_layer(&em->fdata, CD_PROP_INT))
+       {
+               int targetPolyIdx = findFreeNavPolyIndex(em);
+               if (targetPolyIdx>0)
+               {
+                       //set target poly idx to selected faces
+                       ef = (EditFace*)em->faces.last;
+                       while(ef) 
+                       {
+                               if(ef->f & SELECT ) 
+                               {
+                                       int* recastDataBlock = 
(int*)CustomData_em_get(&em->fdata, ef->data, CD_PROP_INT);
+                                       *recastDataBlock = targetPolyIdx;
+                               }
+                               ef = ef->prev;
+                       }
+               }
+       }               
+
+       DAG_id_flush_update((ID*)obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+       BKE_mesh_end_editmesh((Mesh*)obedit->data, em);
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Assign new polygon index ";
+       ot->description= "Assign new polygon index to face";
+       ot->idname= "OBJECT_OT_assign_new_navpolygon";
+
+       /* api callbacks */
+       ot->poll = assign_navpolygon_poll;
+       ot->exec= assign_new_navpolygon_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+}

Modified: branches/soc-2010-nicks/source/blender/editors/object/object_ops.c
===================================================================
--- branches/soc-2010-nicks/source/blender/editors/object/object_ops.c  
2010-07-27 19:56:16 UTC (rev 30815)
+++ branches/soc-2010-nicks/source/blender/editors/object/object_ops.c  
2010-07-27 21:01:00 UTC (rev 30816)
@@ -211,6 +211,8 @@
        WM_operatortype_append(OBJECT_OT_drop_named_material);
 
        WM_operatortype_append(OBJECT_OT_create_navmesh);
+       WM_operatortype_append(OBJECT_OT_assign_navpolygon);
+       WM_operatortype_append(OBJECT_OT_assign_new_navpolygon);
 }
 
 void ED_operatormacros_object(void)

Modified: 
branches/soc-2010-nicks/source/blender/modifiers/intern/MOD_navmesh.cpp
===================================================================
--- branches/soc-2010-nicks/source/blender/modifiers/intern/MOD_navmesh.cpp     
2010-07-27 19:56:16 UTC (rev 30815)
+++ branches/soc-2010-nicks/source/blender/modifiers/intern/MOD_navmesh.cpp     
2010-07-27 21:01:00 UTC (rev 30816)
@@ -42,20 +42,11 @@
 #include "GPU_draw.h"
 #include "UI_resources.h"
 
-
-static void initData(ModifierData *md)
+//service function
+inline int abs(int a)
 {
-       NavMeshModifierData *nmmd = (NavMeshModifierData*) md;
+       return a>=0 ? a: -a;
 }
-
-static void copyData(ModifierData *md, ModifierData *target)
-{
-       NavMeshModifierData *nmmd = (NavMeshModifierData*) md;
-       NavMeshModifierData *tnmmd = (NavMeshModifierData*) target;
-
-       //.todo - deep copy
-}
-
 inline int bit(int a, int b)
 {
        return (a & (1 << b)) >> b;
@@ -70,6 +61,387 @@
        col[1] = 1 - g*63.0f/255.0f;
        col[2] = 1 - b*63.0f/255.0f;
 }
+
+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)
+{
+       return area2(a, b, c) < 0;
+}
+
+inline int polyNumVerts(const unsigned short* p, const int vertsPerPoly)
+{
+       int nv = 0;
+       for (int i=0; i<vertsPerPoly; i++)
+       {
+               if (p[i]==0xffff)
+                       break;
+               nv++;
+       }
+       return nv;
+}
+
+inline bool polyIsConvex(const unsigned short* p, const int vertsPerPoly, 
const float* verts)
+{
+       int nv = polyNumVerts(p, vertsPerPoly);
+       if (nv<3)
+               return false;
+       for (int 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 true;
+}
+
+static 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];
+       if (d > 0)
+               t /= d;
+       if (t < 0)
+               t = 0;
+       else if (t > 1)
+               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];
+}
+
+static bool buildRawVertIndicesData(DerivedMesh* dm, int &nverts, float 
*&verts, 
+                                                                       int 
&ntris, unsigned short *&tris, int *&trisToFacesMap,
+                                                                       int 
*&recastData)
+{
+       nverts = dm->getNumVerts(dm);
+       verts = new float[3*nverts];
+       dm->getVertCos(dm, (float(*)[3])verts);
+       
+       //flip coordinates
+       for (int 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);
+       ntris = nfaces;
+       for (int fi=0; fi<nfaces; fi++)
+       {
+               MFace* face = &faces[fi];
+               if (face->v4)
+                       ntris++;
+       }
+
+       //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++)
+       {
+               MFace* face = &faces[fi];
+               tri[3*triIdx+0] = face->v1;
+               tri[3*triIdx+1] = face->v3;
+               tri[3*triIdx+2] = face->v2;
+               trisToFacesMap[triIdx++]=fi;
+               if (face->v4)
+               {
+                       tri[3*triIdx+0] = face->v1;
+                       tri[3*triIdx+1] = face->v4;
+                       tri[3*triIdx+2] = face->v2;
+                       trisToFacesMap[triIdx++]=fi;
+               }
+       }
+
+       //carefully, recast data is just reference to data in derived mesh
+       recastData = (int*)CustomData_get_layer(&dm->faceData, CD_PROP_INT);
+       return true;
+}
+

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to