[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