[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [31355] branches/soc-2010-nicks/source: added option to set "up" vector of the actor orientation using navmesh normal (steering actuator)

Nick Samarin nicks1987 at bigmir.net
Sun Aug 15 19:40:57 CEST 2010


Revision: 31355
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31355
Author:   nicks
Date:     2010-08-15 19:40:57 +0200 (Sun, 15 Aug 2010)

Log Message:
-----------
added option to set "up" vector of the actor orientation using navmesh normal (steering actuator)

Modified Paths:
--------------
    branches/soc-2010-nicks/source/blender/editors/space_logic/logic_window.c
    branches/soc-2010-nicks/source/blender/makesdna/DNA_actuator_types.h
    branches/soc-2010-nicks/source/blender/makesrna/intern/rna_actuator.c
    branches/soc-2010-nicks/source/gameengine/Converter/KX_ConvertActuators.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.h

Modified: branches/soc-2010-nicks/source/blender/editors/space_logic/logic_window.c
===================================================================
--- branches/soc-2010-nicks/source/blender/editors/space_logic/logic_window.c	2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/blender/editors/space_logic/logic_window.c	2010-08-15 17:40:57 UTC (rev 31355)
@@ -4351,8 +4351,12 @@
 	uiItemR(row, ptr, "facing", 0, NULL, 0);
 	if (RNA_boolean_get(ptr, "facing"))
 	{
-		uiItemR(row, ptr, "facingaxis", 0, NULL, 0);	
+		uiItemR(row, ptr, "facingaxis", 0, NULL, 0);
 	}
+	if (RNA_pointer_get(ptr, "navmesh").data)
+	{
+		uiItemR(row, ptr, "normalup", 0, NULL, 0);		
+	}
 	row = uiLayoutRow(layout, 0);
 	uiItemR(row, ptr, "selfterminated", 0, NULL, 0);
 	if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING)

Modified: branches/soc-2010-nicks/source/blender/makesdna/DNA_actuator_types.h
===================================================================
--- branches/soc-2010-nicks/source/blender/makesdna/DNA_actuator_types.h	2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/blender/makesdna/DNA_actuator_types.h	2010-08-15 17:40:57 UTC (rev 31355)
@@ -527,6 +527,7 @@
 #define ACT_STEERING_SELFTERMINATED   1
 #define ACT_STEERING_ENABLEVISUALIZATION   2
 #define ACT_STEERING_AUTOMATICFACING   4
+#define ACT_STEERING_NORMALUP  8
 
 #endif
 

Modified: branches/soc-2010-nicks/source/blender/makesrna/intern/rna_actuator.c
===================================================================
--- branches/soc-2010-nicks/source/blender/makesrna/intern/rna_actuator.c	2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/blender/makesrna/intern/rna_actuator.c	2010-08-15 17:40:57 UTC (rev 31355)
@@ -1976,7 +1976,11 @@
 	RNA_def_property_enum_items(prop, facingaxis_items);
 	RNA_def_property_ui_text(prop, "Axis", "Axis for automatic facing");
 	RNA_def_property_update(prop, NC_LOGIC, NULL);
-	
+
+	prop= RNA_def_property(srna, "normalup", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_NORMALUP);
+	RNA_def_property_ui_text(prop, "N", "Use normal of the navmesh to set \"UP\" vector");
+	RNA_def_property_update(prop, NC_LOGIC, NULL);
 }
 
 void RNA_def_actuator(BlenderRNA *brna)

Modified: branches/soc-2010-nicks/source/gameengine/Converter/KX_ConvertActuators.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Converter/KX_ConvertActuators.cpp	2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/gameengine/Converter/KX_ConvertActuators.cpp	2010-08-15 17:40:57 UTC (rev 31355)
@@ -1060,11 +1060,12 @@
 				bool selfTerminated = (stAct->flag & ACT_STEERING_SELFTERMINATED) !=0;
 				bool enableVisualization = (stAct->flag & ACT_STEERING_ENABLEVISUALIZATION) !=0;
 				short facingMode = (stAct->flag & ACT_STEERING_AUTOMATICFACING) ? stAct->facingaxis : 0;
+				bool normalup = (stAct->flag & ACT_STEERING_NORMALUP) !=0;
 				KX_SteeringActuator *tmpstact
 					= new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist, 
 								stAct->velocity, stAct->acceleration, stAct->turnspeed, 
 								selfTerminated, stAct->updateTime,
-								scene->GetObstacleSimulation(), facingMode, enableVisualization);
+								scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization);
 				baseact = tmpstact;
 				break;
 			}

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp	2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp	2010-08-15 17:40:57 UTC (rev 31355)
@@ -39,8 +39,8 @@
 #include "KX_ObstacleSimulation.h"
 #include "KX_PythonInit.h"
 #include "KX_PyMath.h"
+#include "Recast.h"
 
-
 /* ------------------------------------------------------------------------- */
 /* Native functions                                                          */
 /* ------------------------------------------------------------------------- */
@@ -57,6 +57,7 @@
 									int pathUpdatePeriod,
 									KX_ObstacleSimulation* simulation,
 									short facingmode,
+									bool normalup,
 									bool enableVisualization)	 : 
 	SCA_IActuator(gameobj, KX_ACT_STEERING),
 	m_mode(mode),
@@ -72,6 +73,7 @@
 	m_simulation(simulation),	
 	m_enableVisualization(enableVisualization),
 	m_facingMode(facingmode),
+	m_normalUp(normalup),
 	m_obstacle(NULL),
 	m_pathLen(0),
 	m_wayPointIdx(-1),
@@ -309,23 +311,129 @@
 
 const MT_Vector3& KX_SteeringActuator::GetSteeringVec()
 {
+	static MT_Vector3 ZERO_VECTOR(0, 0, 0);
 	if (m_isActive)
 		return m_steerVec;
 	else
-		return MT_Vector3(0, 0, 0);
+		return ZERO_VECTOR;
 }
 
+inline float vdot2(const float* a, const float* b)
+{
+	return a[0]*b[0] + a[2]*b[2];
+}
+static bool barDistSqPointToTri(const float* p, const float* a, const float* b, const float* c)
+{
+	float v0[3], v1[3], v2[3];
+	vsub(v0, c,a);
+	vsub(v1, b,a);
+	vsub(v2, p,a);
+
+	const float dot00 = vdot2(v0, v0);
+	const float dot01 = vdot2(v0, v1);
+	const float dot02 = vdot2(v0, v2);
+	const float dot11 = vdot2(v1, v1);
+	const float dot12 = vdot2(v1, v2);
+
+	// Compute barycentric coordinates
+	float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
+	float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+	float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+	float ud = u<0.f ? -u : (u>1.f ? u-1.f : 0.f);
+	float vd = v<0.f ? -v : (v>1.f ? v-1.f : 0.f);
+	return ud*ud+vd*vd ;
+}
+
+inline void flipAxes(float* vec)
+{
+	std::swap(vec[1],vec[2]);
+}
+
+static bool getNavmeshNormal(dtStatNavMesh* navmesh, const MT_Vector3& pos, MT_Vector3& normal)
+{
+	static const float polyPickExt[3] = {2, 4, 2};
+	float spos[3];
+	pos.getValue(spos);	
+	flipAxes(spos);	
+	dtStatPolyRef sPolyRef = navmesh->findNearestPoly(spos, polyPickExt);
+	if (sPolyRef == 0)
+		return false;
+	const dtStatPoly* p = navmesh->getPoly(sPolyRef-1);
+	const dtStatPolyDetail* pd = navmesh->getPolyDetail(sPolyRef-1);
+
+	float distMin = FLT_MAX;
+	int idxMin = -1;
+	for (int i = 0; i < pd->ntris; ++i)
+	{
+		const unsigned char* t = navmesh->getDetailTri(pd->tbase+i);
+		const float* v[3];
+		for (int j = 0; j < 3; ++j)
+		{
+			if (t[j] < p->nv)
+				v[j] = navmesh->getVertex(p->v[t[j]]);
+			else
+				v[j] = navmesh->getDetailVertex(pd->vbase+(t[j]-p->nv));
+		}
+		float dist = barDistSqPointToTri(spos, v[0], v[1], v[2]);
+		if (dist<distMin)
+		{
+			distMin = dist;
+			idxMin = i;
+		}			
+	}
+
+	if (idxMin>=0)
+	{
+		const unsigned char* t = navmesh->getDetailTri(pd->tbase+idxMin);
+		const float* v[3];
+		for (int j = 0; j < 3; ++j)
+		{
+			if (t[j] < p->nv)
+				v[j] = navmesh->getVertex(p->v[t[j]]);
+			else
+				v[j] = navmesh->getDetailVertex(pd->vbase+(t[j]-p->nv));
+		}
+		MT_Vector3 tri[3];
+		for (size_t j=0; j<3; j++)
+			tri[j].setValue(v[j][0],v[j][2],v[j][1]);
+		MT_Vector3 a,b;
+		a = tri[1]-tri[0];
+		b = tri[2]-tri[0];
+		normal = b.cross(a).safe_normalized();
+		return true;
+	}
+
+	return false;
+}
+
 void KX_SteeringActuator::HandleActorFace(MT_Vector3& velocity)
 {
-	if (m_facingMode==0)
+	if (m_facingMode==0 && (!m_navmesh || !m_normalUp))
 		return;
-	MT_Vector3 dir = velocity;
+	KX_GameObject* curobj = (KX_GameObject*) GetParent();
+	MT_Vector3 dir = m_facingMode==0 ?  curobj->NodeGetLocalOrientation().getColumn(1) : velocity;
 	if (dir.fuzzyZero())
 		return;	
 	dir.normalize();
 	MT_Vector3 up(0,0,1);
 	MT_Vector3 left;
 	MT_Matrix3x3 mat;
+	
+	if (m_navmesh && m_normalUp)
+	{
+		dtStatNavMesh* navmesh =  m_navmesh->GetNavMesh();
+		MT_Vector3 normal;
+		MT_Vector3 trpos = m_navmesh->TransformToLocalCoords(curobj->NodeGetWorldPosition());
+		if (getNavmeshNormal(navmesh, trpos, normal))
+		{
+
+			left = (dir.cross(up)).safe_normalized();
+			dir = (-left.cross(normal)).safe_normalized();			
+			up = normal;
+		}
+	}
+
 	switch (m_facingMode)
 	{
 	case 1: // TRACK X
@@ -370,14 +478,15 @@
 			break;
 		}
 	}
+
 	mat.setValue (
 		left[0], dir[0],up[0], 
 		left[1], dir[1],up[1],
 		left[2], dir[2],up[2]
 	);
 
-	KX_GameObject* curobj = (KX_GameObject*) GetParent();
 	
+	
 	KX_GameObject* parentObject = curobj->GetParent();
 	if(parentObject)
 	{ 

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.h
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.h	2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.h	2010-08-15 17:40:57 UTC (rev 31355)
@@ -66,6 +66,7 @@
 	bool m_isSelfTerminated;
 	bool m_enableVisualization;
 	short m_facingMode;
+	bool m_normalUp;
 	float m_path[MAX_PATH_LENGTH*3];
 	int m_pathLen;
 	int m_pathUpdatePeriod;
@@ -96,6 +97,7 @@
 						int pathUpdatePeriod,
 						KX_ObstacleSimulation* simulation,
 						short facingmode,
+						bool normalup,
 						bool enableVisualization);
 	virtual ~KX_SteeringActuator();
 	virtual bool Update(double curtime, bool frame);





More information about the Bf-blender-cvs mailing list