[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29325] branches/soc-2010-nicks/source/ gameengine: Added segment obstacles, creation obstacles for walls of navigation mesh

Nick Samarin nicks1987 at bigmir.net
Tue Jun 8 01:09:50 CEST 2010


Revision: 29325
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29325
Author:   nicks
Date:     2010-06-08 01:09:50 +0200 (Tue, 08 Jun 2010)

Log Message:
-----------
Added segment obstacles, creation obstacles for walls of navigation mesh

Modified Paths:
--------------
    branches/soc-2010-nicks/source/gameengine/Converter/BL_BlenderDataConversion.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.h
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_ObstacleSimulation.h
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp

Modified: branches/soc-2010-nicks/source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2010-06-07 22:57:54 UTC (rev 29324)
+++ branches/soc-2010-nicks/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2010-06-07 23:09:50 UTC (rev 29325)
@@ -2639,6 +2639,7 @@
 	converter->RegisterWorldInfo(worldinfo);
 	kxscene->SetWorldInfo(worldinfo);
 
+
 	//create object representations for obstacle simulation
 	KX_ObstacleSimulation* obssimulation = kxscene->GetObstacleSimulation();
 	if (obssimulation)
@@ -2653,6 +2654,21 @@
 		}
 	}
 
+	//build navigation mesh
+	for ( i=0;i<objectlist->GetCount();i++)
+	{
+		KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i));
+		struct Object* blenderobject = gameobj->GetBlenderObject();
+		if (blenderobject->type==OB_MESH && (blenderobject->gameflag & OB_NAVMESH))
+		{
+			KX_NavMeshObject* navmesh = static_cast<KX_NavMeshObject*>(gameobj);
+			navmesh->BuildNavMesh();
+			navmesh->SetVisible(0, true);
+			if (obssimulation)
+				obssimulation->AddObstaclesForNavMesh(navmesh);
+		}
+	}
+
 #define CONVERT_LOGIC
 #ifdef CONVERT_LOGIC
 	// convert logic bricks, sensors, controllers and actuators
@@ -2693,19 +2709,7 @@
 
 	logicbrick_conversionlist->Release();
 	
-	//build navigation mesh
-	for ( i=0;i<objectlist->GetCount();i++)
-	{
-		KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i));
-		struct Object* blenderobject = gameobj->GetBlenderObject();
-		if (blenderobject->type==OB_MESH && (blenderobject->gameflag & OB_NAVMESH))
-		{
-			KX_NavMeshObject* pathfinder = static_cast<KX_NavMeshObject*>(gameobj);
-			pathfinder->BuildNavMesh();
-			pathfinder->SetVisible(0, true);
-		}
-	}
-	
+
 	// Calculate the scene btree -
 	// too slow - commented out.
 	//kxscene->SetNodeTree(tf.MakeTree());

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp	2010-06-07 22:57:54 UTC (rev 29324)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.cpp	2010-06-07 23:09:50 UTC (rev 29325)
@@ -307,6 +307,11 @@
 	return true;
 }
 
+dtStatNavMesh* KX_NavMeshObject::GetNavMesh()
+{
+	return m_navMesh;
+}
+
 void KX_NavMeshObject::DrawNavMesh()
 {
 	if (!m_navMesh)

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.h
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.h	2010-06-07 22:57:54 UTC (rev 29324)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_NavMeshObject.h	2010-06-07 23:09:50 UTC (rev 29325)
@@ -55,6 +55,7 @@
 
 
 	bool BuildNavMesh();
+	dtStatNavMesh* GetNavMesh();
 	int FindPath(const MT_Point3& from, const MT_Point3& to, float* path, int maxPathLen);
 	float Raycast(const MT_Point3& from, const MT_Point3& to);
 	void DrawNavMesh();

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp	2010-06-07 22:57:54 UTC (rev 29324)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_ObstacleSimulation.cpp	2010-06-07 23:09:50 UTC (rev 29325)
@@ -33,7 +33,8 @@
 */
 
 #include "KX_ObstacleSimulation.h"
-#include "KX_GameObject.h"
+#include "KX_NavMeshObject.h"
+#include "KX_PythonInit.h"
 #include "DNA_object_types.h"
 #include "math.h"
 #define M_PI       3.14159265358979323846
@@ -60,7 +61,86 @@
 	return 1;
 }
 
+inline float perp(const MT_Vector2& a, const MT_Vector2& b) { return a.x()*b.y() - a.y()*b.x(); }
 
+
+int sweepCircleSegment(const MT_Vector3& pos0, const MT_Scalar r0, const MT_Vector2& v,
+					   const MT_Vector3& pa, const MT_Vector3& pb, const MT_Scalar sr,
+					   float& tmin, float &tmax)
+{
+	// equation parameters
+	MT_Vector2 c0(pos0.x(), pos0.y());
+	MT_Vector2 sa(pa.x(), pa.y());
+	MT_Vector2 sb(pb.x(), pb.y());
+	MT_Vector2 L = sb-sa;
+	MT_Vector2 H = c0-sa;
+	MT_Scalar radius = r0+sr;
+	float l2 = L.length2();
+	float r2 = radius * radius;
+	float dl = perp(v, L);
+	float hl = perp(H, L);
+	float a = dl * dl;
+	float b = 2.0f * hl * dl;
+	float c = hl * hl - (r2 * l2);
+	float d = (b*b) - (4.0f * a * c);
+
+	// infinite line missed by infinite ray.
+	if (d < 0.0f)
+		return 0;
+
+	d = sqrtf(d);
+	tmin = (-b - d) / (2.0f * a);
+	tmax = (-b + d) / (2.0f * a);
+
+	// line missed by ray range.
+	/*	if (tmax < 0.0f || tmin > 1.0f)
+	return 0;*/
+
+	// find what part of the ray was collided.
+	MT_Vector2 Pedge;
+	Pedge = c0+v*tmin;
+	H = Pedge - sa;
+	float e0 = MT_dot(H, L) / l2;
+	Pedge = c0 + v*tmax;
+	H = Pedge - sa;
+	float e1 = MT_dot(H, L) / l2;
+
+	if (e0 < 0.0f || e1 < 0.0f)
+	{
+		float ctmin, ctmax;
+		if (sweepCircleCircle(pos0, r0, v, pa, sr, ctmin, ctmax))
+		{
+			if (e0 < 0.0f && ctmin > tmin)
+				tmin = ctmin;
+			if (e1 < 0.0f && ctmax < tmax)
+				tmax = ctmax;
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	if (e0 > 1.0f || e1 > 1.0f)
+	{
+		float ctmin, ctmax;
+		if (sweepCircleCircle(pos0, r0, v, pb, sr, ctmin, ctmax))
+		{
+			if (e0 > 1.0f && ctmin > tmin)
+				tmin = ctmin;
+			if (e1 > 1.0f && ctmax < tmax)
+				tmax = ctmax;
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+
 KX_ObstacleSimulation::KX_ObstacleSimulation()
 {
 
@@ -75,19 +155,60 @@
 	}
 	m_obstacles.clear();
 }
+KX_Obstacle* KX_ObstacleSimulation::CreateObstacle()
+{
+	KX_Obstacle* obstacle = new KX_Obstacle();
+	m_obstacles.push_back(obstacle);
+	return obstacle;
+}
+
 void KX_ObstacleSimulation::AddObstacleForObj(KX_GameObject* gameobj)
 {
-	KX_Obstacle* obstacle = new KX_Obstacle();
+	KX_Obstacle* obstacle = CreateObstacle();
 	struct Object* blenderobject = gameobj->GetBlenderObject();
+	obstacle->m_type = KX_OBSTACLE_OBJ;
+	obstacle->m_shape = KX_OBSTACLE_CIRCLE;
 	obstacle->m_rad = blenderobject->inertia; //.todo use radius of collision shape bound sphere 
 	obstacle->m_gameObj = gameobj;
-	m_obstacles.push_back(obstacle);
+	
 }
 
+void KX_ObstacleSimulation::AddObstaclesForNavMesh(KX_NavMeshObject* navmeshobj)
+{	
+	dtStatNavMesh* navmesh = navmeshobj->GetNavMesh();
+	if (navmesh)
+	{
+		int npoly = navmesh->getPolyCount();
+		for (int pi=0; pi<npoly; pi++)
+		{
+			const dtStatPoly* poly = navmesh->getPoly(pi);
+
+			for (int i = 0, j = (int)poly->nv-1; i < (int)poly->nv; j = i++)
+			{	
+				if (poly->n[j]) continue;
+				const float* vj = navmesh->getVertex(poly->v[j]);
+				const float* vi = navmesh->getVertex(poly->v[i]);
+		
+				KX_Obstacle* obstacle = CreateObstacle();
+				obstacle->m_type = KX_OBSTACLE_NAV_MESH;
+				obstacle->m_shape = KX_OBSTACLE_SEGMENT;
+				obstacle->m_gameObj = navmeshobj;
+				obstacle->m_pos = MT_Vector3(vj[0], vj[2], vj[1]);
+				obstacle->m_pos2 = MT_Vector3(vi[0], vi[2], vi[1]);
+				obstacle->m_rad = 0;
+				obstacle->m_vel = MT_Vector2(0,0);
+			}
+		}
+	}
+}
+
 void KX_ObstacleSimulation::UpdateObstacles()
 {
 	for (size_t i=0; i<m_obstacles.size(); i++)
 	{
+		if (m_obstacles[i]->m_shape==KX_OBSTACLE_NAV_MESH || m_obstacles[i]->m_shape==KX_OBSTACLE_SEGMENT)
+			continue;
+
 		KX_Obstacle* obs = m_obstacles[i];
 		obs->m_pos = obs->m_gameObj->NodeGetWorldPosition();
 		obs->m_vel.x() = obs->m_gameObj->GetLinearVelocity().x();
@@ -106,10 +227,23 @@
 	return NULL;
 }
 
-void KX_ObstacleSimulation::AdjustObstacleVelocity(KX_Obstacle* activeObst, MT_Vector3& velocity)
+void KX_ObstacleSimulation::AdjustObstacleVelocity(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, 
+													MT_Vector3& velocity)
 {
 }
 
+void KX_ObstacleSimulation::DrawObstacles()
+{
+	static const MT_Vector3 bluecolor(0,0,1);
+	for (size_t i=0; i<m_obstacles.size(); i++)
+	{
+		if (m_obstacles[i]->m_shape==KX_OBSTACLE_SEGMENT)
+		{
+			KX_RasterizerDrawDebugLine(m_obstacles[i]->m_pos, m_obstacles[i]->m_pos2, bluecolor);
+		}
+	}	
+}
+
 KX_ObstacleSimulationTOI::KX_ObstacleSimulationTOI():
 	m_avoidSteps(32),
 	m_minToi(0.5f),
@@ -131,13 +265,14 @@
 	m_toiCircles.clear();
 }
 
-void KX_ObstacleSimulationTOI::AddObstacleForObj(KX_GameObject* gameobj)
+KX_Obstacle* KX_ObstacleSimulationTOI::CreateObstacle()
 {
-	KX_ObstacleSimulation::AddObstacleForObj(gameobj);
+	KX_Obstacle* obstacle = KX_ObstacleSimulation::CreateObstacle();
 	m_toiCircles.push_back(new TOICircle());
+	return obstacle;
 }
 
-void KX_ObstacleSimulationTOI::AdjustObstacleVelocity(KX_Obstacle* activeObst, MT_Vector3& velocity)
+void KX_ObstacleSimulationTOI::AdjustObstacleVelocity(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, MT_Vector3& velocity)
 {
 	int nobs = m_obstacles.size();
 	int obstidx = std::find(m_obstacles.begin(), m_obstacles.end(), activeObst) - m_obstacles.begin();
@@ -177,28 +312,38 @@
 		float tmine = 0;
 		for (int i = 0; i < nobs; ++i)
 		{
-			if (i==obstidx)
+			KX_Obstacle* ob = m_obstacles[i];
+			if ( (ob==activeObst) ||
+				 (ob->m_type==KX_OBSTACLE_NAV_MESH && ob->m_gameObj!=activeNavMeshObj)	)
 				continue;
-			KX_Obstacle* ob = m_obstacles[i];
 
 			float htmin,htmax;
 
-			MT_Vector2 vab;
-			if (ob->m_vel.length2() < 0.01f*0.01f)
+			if (ob->m_type == KX_OBSTACLE_CIRCLE)
 			{
-				// Stationary, use VO
-				vab = svel;
+				MT_Vector2 vab;
+				if (ob->m_vel.length2() < 0.01f*0.01f)
+				{
+					// Stationary, use VO
+					vab = svel;
+				}
+				else
+				{
+					// Moving, use RVO
+					vab = 2*svel - vel - ob->m_vel;
+				}
+
+				if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad, 
+										vab, ob->m_pos, ob->m_rad, htmin, htmax))
+					continue;
 			}
-			else
+			else if (ob->m_type == KX_OBSTACLE_SEGMENT)
 			{
-				// Moving, use RVO
-				vab = 2*svel - vel - ob->m_vel;
+				if (!sweepCircleSegment(activeObst->m_pos, activeObst->m_rad, svel, 
+										ob->m_pos, ob->m_pos2, ob->m_rad, htmin, htmax))
+					continue;
 			}
 
-			if (!sweepCircleCircle(activeObst->m_pos, activeObst->m_rad, 
-									vab, ob->m_pos, ob->m_rad, htmin, htmax))
-				continue;
-
 			if (htmin > 0.0f)
 			{
 				// The closest obstacle is somewhere ahead of us, keep track of nearest obstacle.

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_ObstacleSimulation.h
===================================================================

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list