forked from bartvdbraak/blender
Added:
- obstacle culling for correct simulation in 3d - flag for steering actuator termination on reaching target - path recalculation period - advance by waypoints (for path following)
This commit is contained in:
parent
700c32e738
commit
c92d0dfdf6
@ -544,6 +544,9 @@ class WORLD_PT_game_physics_obstacles(WorldButtonsPanel):
|
|||||||
wide_ui = context.region.width > narrowui
|
wide_ui = context.region.width > narrowui
|
||||||
|
|
||||||
layout.prop(gs, "obstacle_simulation", text = "Type")
|
layout.prop(gs, "obstacle_simulation", text = "Type")
|
||||||
|
if gs.obstacle_simulation != 'None':
|
||||||
|
layout.prop(gs, "level_height", text="Level height")
|
||||||
|
|
||||||
|
|
||||||
classes = [
|
classes = [
|
||||||
PHYSICS_PT_game_physics,
|
PHYSICS_PT_game_physics,
|
||||||
|
@ -473,6 +473,7 @@ Scene *add_scene(char *name)
|
|||||||
sce->gm.matmode = GAME_MAT_MULTITEX;
|
sce->gm.matmode = GAME_MAT_MULTITEX;
|
||||||
|
|
||||||
sce->gm.obstacleSimulation= OBSTSIMULATION_NONE;
|
sce->gm.obstacleSimulation= OBSTSIMULATION_NONE;
|
||||||
|
sce->gm.levelHeight = 2.f;
|
||||||
|
|
||||||
sound_create_scene(sce);
|
sound_create_scene(sce);
|
||||||
|
|
||||||
|
@ -4276,6 +4276,10 @@ static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr)
|
|||||||
row = uiLayoutRow(layout, 0);
|
row = uiLayoutRow(layout, 0);
|
||||||
uiItemR(row, ptr, "acceleration", 0, NULL, 0);
|
uiItemR(row, ptr, "acceleration", 0, NULL, 0);
|
||||||
uiItemR(row, ptr, "turnspeed", 0, NULL, 0);
|
uiItemR(row, ptr, "turnspeed", 0, NULL, 0);
|
||||||
|
row = uiLayoutRow(layout, 0);
|
||||||
|
uiItemR(row, ptr, "selfterminated", 0, NULL, 0);
|
||||||
|
if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING)
|
||||||
|
uiItemR(row, ptr, "updateperiod", 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,12 +215,14 @@ typedef struct bArmatureActuator {
|
|||||||
} bArmatureActuator;
|
} bArmatureActuator;
|
||||||
|
|
||||||
typedef struct bSteeringActuator {
|
typedef struct bSteeringActuator {
|
||||||
char pad[4];
|
char pad[7];
|
||||||
|
char flag;
|
||||||
int type; /* 0=seek, 1=flee, 2=path following */
|
int type; /* 0=seek, 1=flee, 2=path following */
|
||||||
float dist;
|
float dist;
|
||||||
float velocity;
|
float velocity;
|
||||||
float acceleration;
|
float acceleration;
|
||||||
float turnspeed;
|
float turnspeed;
|
||||||
|
int updateTime;
|
||||||
struct Object *target;
|
struct Object *target;
|
||||||
struct Object *navmesh;
|
struct Object *navmesh;
|
||||||
} bSteeringActuator;
|
} bSteeringActuator;
|
||||||
@ -518,6 +520,8 @@ typedef struct FreeCamera {
|
|||||||
#define ACT_STEERING_SEEK 0
|
#define ACT_STEERING_SEEK 0
|
||||||
#define ACT_STEERING_FLEE 1
|
#define ACT_STEERING_FLEE 1
|
||||||
#define ACT_STEERING_PATHFOLLOWING 2
|
#define ACT_STEERING_PATHFOLLOWING 2
|
||||||
|
/* steeringactuator->flag */
|
||||||
|
#define ACT_STEERING_SELFTERMINATED 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -451,11 +451,12 @@ typedef struct GameData {
|
|||||||
* bit 3: (gameengine): Activity culling is enabled.
|
* bit 3: (gameengine): Activity culling is enabled.
|
||||||
* bit 5: (gameengine) : enable Bullet DBVT tree for view frustrum culling
|
* bit 5: (gameengine) : enable Bullet DBVT tree for view frustrum culling
|
||||||
*/
|
*/
|
||||||
short mode, flag, matmode, pad[6];
|
short mode, flag, matmode/*, pad[2]*/;
|
||||||
short occlusionRes; /* resolution of occlusion Z buffer in pixel */
|
short occlusionRes; /* resolution of occlusion Z buffer in pixel */
|
||||||
short physicsEngine;
|
short physicsEngine;
|
||||||
short ticrate, maxlogicstep, physubstep, maxphystep;
|
short ticrate, maxlogicstep, physubstep, maxphystep;
|
||||||
short obstacleSimulation;
|
short obstacleSimulation;
|
||||||
|
float levelHeight;
|
||||||
|
|
||||||
/* standalone player */
|
/* standalone player */
|
||||||
struct GameFraming framing;
|
struct GameFraming framing;
|
||||||
|
@ -1897,6 +1897,17 @@ static void rna_def_steering_actuator(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Target Object", "Set target object");
|
RNA_def_property_ui_text(prop, "Target Object", "Set target object");
|
||||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "selfterminated", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_SELFTERMINATED);
|
||||||
|
RNA_def_property_ui_text(prop, "Self terminated", "Terminate when target is reached");
|
||||||
|
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "updateperiod", PROP_INT, PROP_NONE);
|
||||||
|
RNA_def_property_int_sdna(prop, NULL, "updateTime");
|
||||||
|
RNA_def_property_ui_range(prop, -1, 100000, 1, 1);
|
||||||
|
RNA_def_property_ui_text(prop, "Update period", "Path update period");
|
||||||
|
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "navmesh", PROP_POINTER, PROP_NONE);
|
prop= RNA_def_property(srna, "navmesh", PROP_POINTER, PROP_NONE);
|
||||||
RNA_def_property_struct_type(prop, "Object");
|
RNA_def_property_struct_type(prop, "Object");
|
||||||
RNA_def_property_pointer_sdna(prop, NULL, "navmesh");
|
RNA_def_property_pointer_sdna(prop, NULL, "navmesh");
|
||||||
|
@ -1760,6 +1760,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
|
|||||||
RNA_def_property_enum_items(prop, obstacle_simulation_items);
|
RNA_def_property_enum_items(prop, obstacle_simulation_items);
|
||||||
RNA_def_property_ui_text(prop, "Obstacle simulation", "Simulation used for obstacle avoidance in the game engine");
|
RNA_def_property_ui_text(prop, "Obstacle simulation", "Simulation used for obstacle avoidance in the game engine");
|
||||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||||
|
|
||||||
|
prop= RNA_def_property(srna, "level_height", PROP_FLOAT, PROP_ACCELERATION);
|
||||||
|
RNA_def_property_float_sdna(prop, NULL, "levelHeight");
|
||||||
|
RNA_def_property_range(prop, 0.0f, 200.0f);
|
||||||
|
RNA_def_property_ui_text(prop, "Level height", "Max difference in heights of obstacles to enable their interaction");
|
||||||
|
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_scene_render_layer(BlenderRNA *brna)
|
static void rna_def_scene_render_layer(BlenderRNA *brna)
|
||||||
|
@ -1057,9 +1057,11 @@ void BL_ConvertActuators(char* maggiename,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool selfTerminated = (stAct->flag & ACT_STEERING_SELFTERMINATED) !=0;
|
||||||
KX_SteeringActuator *tmpstact
|
KX_SteeringActuator *tmpstact
|
||||||
= new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist,
|
= new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist,
|
||||||
stAct->velocity, stAct->acceleration, stAct->turnspeed,
|
stAct->velocity, stAct->acceleration, stAct->turnspeed,
|
||||||
|
selfTerminated, stAct->updateTime,
|
||||||
scene->GetObstacleSimulation());
|
scene->GetObstacleSimulation());
|
||||||
baseact = tmpstact;
|
baseact = tmpstact;
|
||||||
break;
|
break;
|
||||||
|
@ -334,6 +334,25 @@ void KX_NavMeshObject::DrawNavMesh()
|
|||||||
return;
|
return;
|
||||||
MT_Vector3 color(0.f, 0.f, 0.f);
|
MT_Vector3 color(0.f, 0.f, 0.f);
|
||||||
|
|
||||||
|
enum RenderMode {DETAILED_TRIS, WALLS};
|
||||||
|
static const RenderMode renderMode = DETAILED_TRIS;
|
||||||
|
switch (renderMode)
|
||||||
|
{
|
||||||
|
case WALLS :
|
||||||
|
for (int pi=0; pi<m_navMesh->getPolyCount(); pi++)
|
||||||
|
{
|
||||||
|
const dtStatPoly* poly = m_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 = m_navMesh->getVertex(poly->v[j]);
|
||||||
|
const float* vi = m_navMesh->getVertex(poly->v[i]);
|
||||||
|
KX_RasterizerDrawDebugLine(MT_Vector3(vj[0], vj[2], vj[1]), MT_Vector3(vi[0], vi[2], vi[1]), color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DETAILED_TRIS :
|
||||||
for (int i = 0; i < m_navMesh->getPolyDetailCount(); ++i)
|
for (int i = 0; i < m_navMesh->getPolyDetailCount(); ++i)
|
||||||
{
|
{
|
||||||
const dtStatPoly* p = m_navMesh->getPoly(i);
|
const dtStatPoly* p = m_navMesh->getPoly(i);
|
||||||
@ -360,6 +379,8 @@ void KX_NavMeshObject::DrawNavMesh()
|
|||||||
KX_RasterizerDrawDebugLine(tri[k], tri[(k+1)%3], color);
|
KX_RasterizerDrawDebugLine(tri[k], tri[(k+1)%3], color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int KX_NavMeshObject::FindPath(const MT_Point3& from, const MT_Point3& to, float* path, int maxPathLen)
|
int KX_NavMeshObject::FindPath(const MT_Point3& from, const MT_Point3& to, float* path, int maxPathLen)
|
||||||
|
@ -166,7 +166,8 @@ static float interpolateToi(float a, const float* dir, const float* toi, const i
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KX_ObstacleSimulation::KX_ObstacleSimulation()
|
KX_ObstacleSimulation::KX_ObstacleSimulation(MT_Scalar levelHeight)
|
||||||
|
: m_levelHeight(levelHeight)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -285,12 +286,51 @@ void KX_ObstacleSimulation::DrawObstacles()
|
|||||||
else if (m_obstacles[i]->m_shape==KX_OBSTACLE_CIRCLE)
|
else if (m_obstacles[i]->m_shape==KX_OBSTACLE_CIRCLE)
|
||||||
{
|
{
|
||||||
KX_RasterizerDrawDebugCircle(m_obstacles[i]->m_pos, m_obstacles[i]->m_rad, bluecolor,
|
KX_RasterizerDrawDebugCircle(m_obstacles[i]->m_pos, m_obstacles[i]->m_rad, bluecolor,
|
||||||
normal.normalized(), SECTORS_NUM);
|
normal, SECTORS_NUM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KX_ObstacleSimulationTOI::KX_ObstacleSimulationTOI():
|
static MT_Point3 nearestPointToObstacle(MT_Point3& pos ,KX_Obstacle* obstacle)
|
||||||
|
{
|
||||||
|
switch (obstacle->m_shape)
|
||||||
|
{
|
||||||
|
case KX_OBSTACLE_SEGMENT :
|
||||||
|
{
|
||||||
|
MT_Vector3 ab = obstacle->m_pos2 - obstacle->m_pos;
|
||||||
|
if (!ab.fuzzyZero())
|
||||||
|
{
|
||||||
|
MT_Vector3 abdir = ab.normalized();
|
||||||
|
MT_Vector3 v = pos - obstacle->m_pos;
|
||||||
|
MT_Scalar proj = abdir.dot(v);
|
||||||
|
CLAMP(proj, 0, ab.length());
|
||||||
|
MT_Point3 res = obstacle->m_pos + abdir*proj;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case KX_OBSTACLE_CIRCLE :
|
||||||
|
default:
|
||||||
|
return obstacle->m_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KX_ObstacleSimulation::FilterObstacle(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj, KX_Obstacle* otherObst)
|
||||||
|
{
|
||||||
|
//filter obstacles by type
|
||||||
|
if ( (otherObst == activeObst) ||
|
||||||
|
(otherObst->m_type==KX_OBSTACLE_NAV_MESH && otherObst->m_gameObj!=activeNavMeshObj) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//filter obstacles by position
|
||||||
|
MT_Point3 p = nearestPointToObstacle(activeObst->m_pos, otherObst);
|
||||||
|
if ( fabs(activeObst->m_pos.z() - p.z()) > m_levelHeight)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
KX_ObstacleSimulationTOI::KX_ObstacleSimulationTOI(MT_Scalar levelHeight):
|
||||||
|
KX_ObstacleSimulation(levelHeight),
|
||||||
m_avoidSteps(32),
|
m_avoidSteps(32),
|
||||||
m_minToi(0.5f),
|
m_minToi(0.5f),
|
||||||
m_maxToi(1.2f),
|
m_maxToi(1.2f),
|
||||||
@ -360,8 +400,8 @@ void KX_ObstacleSimulationTOI::AdjustObstacleVelocity(KX_Obstacle* activeObst, K
|
|||||||
for (int i = 0; i < nobs; ++i)
|
for (int i = 0; i < nobs; ++i)
|
||||||
{
|
{
|
||||||
KX_Obstacle* ob = m_obstacles[i];
|
KX_Obstacle* ob = m_obstacles[i];
|
||||||
if ( (ob==activeObst) ||
|
bool res = FilterObstacle(activeObst, activeNavMeshObj, ob);
|
||||||
(ob->m_type==KX_OBSTACLE_NAV_MESH && ob->m_gameObj!=activeNavMeshObj) )
|
if (!res)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float htmin,htmax;
|
float htmin,htmax;
|
||||||
|
@ -73,9 +73,12 @@ class KX_ObstacleSimulation
|
|||||||
protected:
|
protected:
|
||||||
std::vector<KX_Obstacle*> m_obstacles;
|
std::vector<KX_Obstacle*> m_obstacles;
|
||||||
|
|
||||||
|
MT_Scalar m_levelHeight;
|
||||||
|
|
||||||
virtual KX_Obstacle* CreateObstacle();
|
virtual KX_Obstacle* CreateObstacle();
|
||||||
|
bool FilterObstacle(KX_Obstacle* activeObstacle, KX_NavMeshObject* activeNavMeshObj, KX_Obstacle* otherObstacle);
|
||||||
public:
|
public:
|
||||||
KX_ObstacleSimulation();
|
KX_ObstacleSimulation(MT_Scalar levelHeight);
|
||||||
virtual ~KX_ObstacleSimulation();
|
virtual ~KX_ObstacleSimulation();
|
||||||
|
|
||||||
void DrawObstacles();
|
void DrawObstacles();
|
||||||
@ -114,7 +117,7 @@ protected:
|
|||||||
std::vector<TOICircle*> m_toiCircles; // TOI circles (one per active agent)
|
std::vector<TOICircle*> m_toiCircles; // TOI circles (one per active agent)
|
||||||
virtual KX_Obstacle* CreateObstacle();
|
virtual KX_Obstacle* CreateObstacle();
|
||||||
public:
|
public:
|
||||||
KX_ObstacleSimulationTOI();
|
KX_ObstacleSimulationTOI(MT_Scalar levelHeight);
|
||||||
~KX_ObstacleSimulationTOI();
|
~KX_ObstacleSimulationTOI();
|
||||||
virtual void AdjustObstacleVelocity(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj,
|
virtual void AdjustObstacleVelocity(KX_Obstacle* activeObst, KX_NavMeshObject* activeNavMeshObj,
|
||||||
MT_Vector3& velocity, MT_Scalar maxDeltaSpeed,MT_Scalar maxDeltaAngle);
|
MT_Vector3& velocity, MT_Scalar maxDeltaSpeed,MT_Scalar maxDeltaAngle);
|
||||||
|
@ -214,7 +214,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
|
|||||||
switch (scene->gm.obstacleSimulation)
|
switch (scene->gm.obstacleSimulation)
|
||||||
{
|
{
|
||||||
case OBSTSIMULATION_TOI:
|
case OBSTSIMULATION_TOI:
|
||||||
m_obstacleSimulation = new KX_ObstacleSimulationTOI;
|
m_obstacleSimulation = new KX_ObstacleSimulationTOI((MT_Scalar)scene->gm.levelHeight);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_obstacleSimulation = NULL;
|
m_obstacleSimulation = NULL;
|
||||||
|
@ -52,6 +52,8 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
|
|||||||
MT_Scalar velocity,
|
MT_Scalar velocity,
|
||||||
MT_Scalar acceleration,
|
MT_Scalar acceleration,
|
||||||
MT_Scalar turnspeed,
|
MT_Scalar turnspeed,
|
||||||
|
bool isSelfTerminated,
|
||||||
|
int pathUpdatePeriod,
|
||||||
KX_ObstacleSimulation* simulation) :
|
KX_ObstacleSimulation* simulation) :
|
||||||
SCA_IActuator(gameobj, KX_ACT_STEERING),
|
SCA_IActuator(gameobj, KX_ACT_STEERING),
|
||||||
m_mode(mode),
|
m_mode(mode),
|
||||||
@ -60,10 +62,14 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
|
|||||||
m_velocity(velocity),
|
m_velocity(velocity),
|
||||||
m_acceleration(acceleration),
|
m_acceleration(acceleration),
|
||||||
m_turnspeed(turnspeed),
|
m_turnspeed(turnspeed),
|
||||||
|
m_isSelfTerminated(isSelfTerminated),
|
||||||
|
m_pathUpdatePeriod(pathUpdatePeriod),
|
||||||
m_updateTime(0),
|
m_updateTime(0),
|
||||||
m_isActive(false),
|
m_isActive(false),
|
||||||
m_simulation(simulation),
|
m_simulation(simulation),
|
||||||
m_obstacle(NULL)
|
m_obstacle(NULL),
|
||||||
|
m_pathLen(0),
|
||||||
|
m_wayPointIdx(-1)
|
||||||
{
|
{
|
||||||
m_navmesh = static_cast<KX_NavMeshObject*>(navmesh);
|
m_navmesh = static_cast<KX_NavMeshObject*>(navmesh);
|
||||||
if (m_navmesh)
|
if (m_navmesh)
|
||||||
@ -147,6 +153,7 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
|||||||
if (m_posevent && !m_isActive)
|
if (m_posevent && !m_isActive)
|
||||||
{
|
{
|
||||||
delta = 0;
|
delta = 0;
|
||||||
|
m_pathUpdateTime = -1;
|
||||||
m_updateTime = curtime;
|
m_updateTime = curtime;
|
||||||
m_isActive = true;
|
m_isActive = true;
|
||||||
}
|
}
|
||||||
@ -156,61 +163,89 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
|||||||
|
|
||||||
RemoveAllEvents();
|
RemoveAllEvents();
|
||||||
|
|
||||||
if (bNegativeEvent || !delta)
|
if (!delta)
|
||||||
return false; // do nothing on negative events
|
return true;
|
||||||
|
|
||||||
if (!m_target)
|
if (bNegativeEvent || !m_target)
|
||||||
return false;
|
return false; // do nothing on negative events
|
||||||
|
|
||||||
KX_GameObject *obj = (KX_GameObject*) GetParent();
|
KX_GameObject *obj = (KX_GameObject*) GetParent();
|
||||||
const MT_Point3& mypos = obj->NodeGetWorldPosition();
|
const MT_Point3& mypos = obj->NodeGetWorldPosition();
|
||||||
const MT_Point3& targpos = m_target->NodeGetWorldPosition();
|
const MT_Point3& targpos = m_target->NodeGetWorldPosition();
|
||||||
MT_Vector3 vectotarg = targpos - mypos;
|
MT_Vector3 vectotarg = targpos - mypos;
|
||||||
MT_Vector3 steervec = MT_Vector3(0, 0, 0);
|
MT_Vector3 steervec = MT_Vector3(0, 0, 0);
|
||||||
bool apply_steerforce = true;
|
bool apply_steerforce = false;
|
||||||
|
bool terminate = true;
|
||||||
|
|
||||||
switch (m_mode) {
|
switch (m_mode) {
|
||||||
case KX_STEERING_SEEK:
|
case KX_STEERING_SEEK:
|
||||||
if (vectotarg.length2()>m_distance*m_distance)
|
if (vectotarg.length2()>m_distance*m_distance)
|
||||||
{
|
{
|
||||||
apply_steerforce = true;
|
terminate = false;
|
||||||
steervec = vectotarg;
|
steervec = vectotarg;
|
||||||
steervec.normalize();
|
steervec.normalize();
|
||||||
|
apply_steerforce = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KX_STEERING_FLEE:
|
case KX_STEERING_FLEE:
|
||||||
if (vectotarg.length2()<m_distance*m_distance)
|
if (vectotarg.length2()<m_distance*m_distance)
|
||||||
{
|
{
|
||||||
apply_steerforce = true;
|
terminate = false;
|
||||||
steervec = -vectotarg;
|
steervec = -vectotarg;
|
||||||
steervec.normalize();
|
steervec.normalize();
|
||||||
|
apply_steerforce = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KX_STEERING_PATHFOLLOWING:
|
case KX_STEERING_PATHFOLLOWING:
|
||||||
if (m_navmesh && vectotarg.length2()>m_distance*m_distance)
|
if (m_navmesh && vectotarg.length2()>m_distance*m_distance)
|
||||||
{
|
{
|
||||||
static const int MAX_PATH_LENGTH = 128;
|
terminate = false;
|
||||||
static const MT_Vector3 PATH_COLOR(1,0,0);
|
|
||||||
|
|
||||||
float path[MAX_PATH_LENGTH*3];
|
static const MT_Scalar WAYPOINT_RADIUS(1.);
|
||||||
int pathlen = m_navmesh->FindPath(mypos, targpos, path, MAX_PATH_LENGTH);
|
|
||||||
if (pathlen > 1)
|
if (m_pathUpdateTime<0 || (m_pathUpdatePeriod>=0 &&
|
||||||
|
curtime - m_pathUpdateTime>((double)m_pathUpdatePeriod/1000)))
|
||||||
{
|
{
|
||||||
//debug draw
|
m_pathUpdateTime = curtime;
|
||||||
m_navmesh->DrawPath(path, pathlen, PATH_COLOR);
|
m_pathLen = m_navmesh->FindPath(mypos, targpos, m_path, MAX_PATH_LENGTH);
|
||||||
|
m_wayPointIdx = m_pathLen > 1 ? 1 : -1;
|
||||||
apply_steerforce = true;
|
|
||||||
MT_Vector3 waypoint(&path[3]);
|
|
||||||
steervec = waypoint - mypos;
|
|
||||||
steervec.z() = 0;
|
|
||||||
steervec.normalize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_wayPointIdx>0)
|
||||||
|
{
|
||||||
|
MT_Vector3 waypoint(&m_path[3*m_wayPointIdx]);
|
||||||
|
if ((waypoint-mypos).length2()<WAYPOINT_RADIUS*WAYPOINT_RADIUS)
|
||||||
|
{
|
||||||
|
m_wayPointIdx++;
|
||||||
|
if (m_wayPointIdx>=m_pathLen)
|
||||||
|
{
|
||||||
|
m_wayPointIdx = -1;
|
||||||
|
terminate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
waypoint.setValue(&m_path[3*m_wayPointIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
steervec = waypoint - mypos;
|
||||||
|
apply_steerforce = true;
|
||||||
|
|
||||||
|
//debug draw
|
||||||
|
static const MT_Vector3 PATH_COLOR(1,0,0);
|
||||||
|
m_navmesh->DrawPath(m_path, m_pathLen, PATH_COLOR);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apply_steerforce)
|
if (apply_steerforce)
|
||||||
{
|
{
|
||||||
|
bool isdyna = obj->IsDynamic();
|
||||||
|
if (isdyna)
|
||||||
|
steervec.z() = 0;
|
||||||
|
if (!steervec.fuzzyZero())
|
||||||
|
steervec.normalize();
|
||||||
MT_Vector3 newvel = m_velocity*steervec;
|
MT_Vector3 newvel = m_velocity*steervec;
|
||||||
|
|
||||||
//adjust velocity to avoid obstacles
|
//adjust velocity to avoid obstacles
|
||||||
@ -222,14 +257,23 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
|||||||
KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(0.,1.,0.));
|
KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(0.,1.,0.));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isdyna)
|
||||||
|
{
|
||||||
//temporary solution: set 2D steering velocity directly to obj
|
//temporary solution: set 2D steering velocity directly to obj
|
||||||
//correct way is to apply physical force
|
//correct way is to apply physical force
|
||||||
//MT_Vector3 movement = delta*m_velocity*steervec;
|
|
||||||
//obj->ApplyMovement(movement, false);
|
|
||||||
MT_Vector3 curvel = obj->GetLinearVelocity();
|
MT_Vector3 curvel = obj->GetLinearVelocity();
|
||||||
newvel.z() = curvel.z();
|
newvel.z() = curvel.z();
|
||||||
obj->setLinearVelocity(newvel, false);
|
obj->setLinearVelocity(newvel, false);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MT_Vector3 movement = delta*newvel;
|
||||||
|
obj->ApplyMovement(movement, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (terminate && m_isSelfTerminated)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -43,6 +43,7 @@ class KX_GameObject;
|
|||||||
class KX_NavMeshObject;
|
class KX_NavMeshObject;
|
||||||
struct KX_Obstacle;
|
struct KX_Obstacle;
|
||||||
class KX_ObstacleSimulation;
|
class KX_ObstacleSimulation;
|
||||||
|
const int MAX_PATH_LENGTH = 128;
|
||||||
|
|
||||||
class KX_SteeringActuator : public SCA_IActuator
|
class KX_SteeringActuator : public SCA_IActuator
|
||||||
{
|
{
|
||||||
@ -61,6 +62,12 @@ class KX_SteeringActuator : public SCA_IActuator
|
|||||||
KX_Obstacle* m_obstacle;
|
KX_Obstacle* m_obstacle;
|
||||||
double m_updateTime;
|
double m_updateTime;
|
||||||
bool m_isActive;
|
bool m_isActive;
|
||||||
|
bool m_isSelfTerminated;
|
||||||
|
float m_path[MAX_PATH_LENGTH*3];
|
||||||
|
int m_pathLen;
|
||||||
|
int m_pathUpdatePeriod;
|
||||||
|
double m_pathUpdateTime;
|
||||||
|
int m_wayPointIdx;
|
||||||
public:
|
public:
|
||||||
enum KX_STEERINGACT_MODE
|
enum KX_STEERINGACT_MODE
|
||||||
{
|
{
|
||||||
@ -79,6 +86,8 @@ public:
|
|||||||
MT_Scalar velocity,
|
MT_Scalar velocity,
|
||||||
MT_Scalar acceleration,
|
MT_Scalar acceleration,
|
||||||
MT_Scalar turnspeed,
|
MT_Scalar turnspeed,
|
||||||
|
bool isSelfTerminated,
|
||||||
|
int pathUpdatePeriod,
|
||||||
KX_ObstacleSimulation* simulation);
|
KX_ObstacleSimulation* simulation);
|
||||||
virtual ~KX_SteeringActuator();
|
virtual ~KX_SteeringActuator();
|
||||||
virtual bool Update(double curtime, bool frame);
|
virtual bool Update(double curtime, bool frame);
|
||||||
|
Loading…
Reference in New Issue
Block a user