[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30816] branches/soc-2010-nicks: - added operators for manual assigning navigation polygon idx to mesh faces in edit mode
Nick Samarin
nicks1987 at bigmir.net
Tue Jul 27 23:01:00 CEST 2010
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. @@
More information about the Bf-blender-cvs
mailing list