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