forked from bartvdbraak/blender
added option for automatic facing in steering actuator
This commit is contained in:
parent
3a8f3dd3f5
commit
b822f0bb7a
@ -472,6 +472,8 @@ void init_actuator(bActuator *act)
|
||||
sta->turnspeed = 120.f;
|
||||
sta->dist = 1.f;
|
||||
sta->velocity= 3.f;
|
||||
sta->flag = ACT_STEERING_AUTOMATICFACING;
|
||||
sta->facingaxis = 1;
|
||||
default:
|
||||
; /* this is very severe... I cannot make any memory for this */
|
||||
/* logic brick... */
|
||||
|
@ -4348,6 +4348,12 @@ static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr)
|
||||
uiItemR(row, ptr, "acceleration", 0, NULL, 0);
|
||||
uiItemR(row, ptr, "turnspeed", 0, NULL, 0);
|
||||
row = uiLayoutRow(layout, 0);
|
||||
uiItemR(row, ptr, "facing", 0, NULL, 0);
|
||||
if (RNA_boolean_get(ptr, "facing"))
|
||||
{
|
||||
uiItemR(row, ptr, "facingaxis", 0, NULL, 0);
|
||||
}
|
||||
row = uiLayoutRow(layout, 0);
|
||||
uiItemR(row, ptr, "selfterminated", 0, NULL, 0);
|
||||
if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING)
|
||||
{
|
||||
|
@ -224,8 +224,9 @@ typedef struct bArmatureActuator {
|
||||
} bArmatureActuator;
|
||||
|
||||
typedef struct bSteeringActuator {
|
||||
char pad[7];
|
||||
char pad[5];
|
||||
char flag;
|
||||
short facingaxis;
|
||||
int type; /* 0=seek, 1=flee, 2=path following */
|
||||
float dist;
|
||||
float velocity;
|
||||
@ -525,6 +526,7 @@ typedef struct bActuator {
|
||||
/* steeringactuator->flag */
|
||||
#define ACT_STEERING_SELFTERMINATED 1
|
||||
#define ACT_STEERING_ENABLEVISUALIZATION 2
|
||||
#define ACT_STEERING_AUTOMATICFACING 4
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1892,6 +1892,15 @@ static void rna_def_steering_actuator(BlenderRNA *brna)
|
||||
{ACT_STEERING_PATHFOLLOWING, "PATHFOLLOWING", 0, "Path following", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem facingaxis_items[] ={
|
||||
{1, "X", 0, "X", ""},
|
||||
{2, "Y", 0, "Y", ""},
|
||||
{3, "Z", 0, "Z", ""},
|
||||
{4, "-X", 0, "-X", ""},
|
||||
{5, "-Y", 0, "-Y", ""},
|
||||
{6, "-Z", 0, "-Z", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna= RNA_def_struct(brna, "SteeringActuator", "Actuator");
|
||||
RNA_def_struct_ui_text(srna, "Steering Actuator", "");
|
||||
RNA_def_struct_sdna_from(srna, "bSteeringActuator", "data");
|
||||
@ -1956,6 +1965,18 @@ static void rna_def_steering_actuator(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "NavMesh Object", "Navigation mesh");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_SteeringActuator_navmesh_set", NULL, NULL);
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "facing", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_AUTOMATICFACING);
|
||||
RNA_def_property_ui_text(prop, "Facing", "Enable automatic facing");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "facingaxis", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "facingaxis");
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
void RNA_def_actuator(BlenderRNA *brna)
|
||||
|
@ -1059,11 +1059,12 @@ void BL_ConvertActuators(char* maggiename,
|
||||
|
||||
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;
|
||||
KX_SteeringActuator *tmpstact
|
||||
= new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist,
|
||||
stAct->velocity, stAct->acceleration, stAct->turnspeed,
|
||||
selfTerminated, stAct->updateTime,
|
||||
scene->GetObstacleSimulation(), enableVisualization);
|
||||
scene->GetObstacleSimulation(), facingMode, enableVisualization);
|
||||
baseact = tmpstact;
|
||||
break;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "KX_NavMeshObject.h"
|
||||
#include "KX_ObstacleSimulation.h"
|
||||
#include "KX_PythonInit.h"
|
||||
#include "KX_PyMath.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -55,6 +56,7 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
|
||||
bool isSelfTerminated,
|
||||
int pathUpdatePeriod,
|
||||
KX_ObstacleSimulation* simulation,
|
||||
short facingmode,
|
||||
bool enableVisualization) :
|
||||
SCA_IActuator(gameobj, KX_ACT_STEERING),
|
||||
m_mode(mode),
|
||||
@ -69,9 +71,11 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
|
||||
m_isActive(false),
|
||||
m_simulation(simulation),
|
||||
m_enableVisualization(enableVisualization),
|
||||
m_facingMode(facingmode),
|
||||
m_obstacle(NULL),
|
||||
m_pathLen(0),
|
||||
m_wayPointIdx(-1)
|
||||
m_wayPointIdx(-1),
|
||||
m_steerVec(MT_Vector3(0, 0, 0))
|
||||
{
|
||||
m_navmesh = static_cast<KX_NavMeshObject*>(navmesh);
|
||||
if (m_navmesh)
|
||||
@ -81,6 +85,13 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
|
||||
|
||||
if (m_simulation)
|
||||
m_obstacle = m_simulation->GetObstacle((KX_GameObject*)gameobj);
|
||||
KX_GameObject* parent = ((KX_GameObject*)gameobj)->GetParent();
|
||||
if (m_facingMode>0 && parent)
|
||||
{
|
||||
m_parentlocalmat = parent->GetSGNode()->GetLocalOrientation();
|
||||
}
|
||||
else
|
||||
m_parentlocalmat.setIdentity();
|
||||
}
|
||||
|
||||
KX_SteeringActuator::~KX_SteeringActuator()
|
||||
@ -175,7 +186,7 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
||||
MT_Vector3 vectotarg = targpos - mypos;
|
||||
MT_Vector3 vectotarg2d = vectotarg;
|
||||
vectotarg2d.z() = 0;
|
||||
MT_Vector3 steervec = MT_Vector3(0, 0, 0);
|
||||
m_steerVec = MT_Vector3(0, 0, 0);
|
||||
bool apply_steerforce = false;
|
||||
bool terminate = true;
|
||||
|
||||
@ -184,8 +195,8 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
||||
if (vectotarg2d.length2()>m_distance*m_distance)
|
||||
{
|
||||
terminate = false;
|
||||
steervec = vectotarg;
|
||||
steervec.normalize();
|
||||
m_steerVec = vectotarg;
|
||||
m_steerVec.normalize();
|
||||
apply_steerforce = true;
|
||||
}
|
||||
break;
|
||||
@ -193,8 +204,8 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
||||
if (vectotarg2d.length2()<m_distance*m_distance)
|
||||
{
|
||||
terminate = false;
|
||||
steervec = -vectotarg;
|
||||
steervec.normalize();
|
||||
m_steerVec = -vectotarg;
|
||||
m_steerVec.normalize();
|
||||
apply_steerforce = true;
|
||||
}
|
||||
break;
|
||||
@ -228,7 +239,7 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
||||
waypoint.setValue(&m_path[3*m_wayPointIdx]);
|
||||
}
|
||||
|
||||
steervec = waypoint - mypos;
|
||||
m_steerVec = waypoint - mypos;
|
||||
apply_steerforce = true;
|
||||
|
||||
|
||||
@ -248,10 +259,10 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
||||
{
|
||||
bool isdyna = obj->IsDynamic();
|
||||
if (isdyna)
|
||||
steervec.z() = 0;
|
||||
if (!steervec.fuzzyZero())
|
||||
steervec.normalize();
|
||||
MT_Vector3 newvel = m_velocity*steervec;
|
||||
m_steerVec.z() = 0;
|
||||
if (!m_steerVec.fuzzyZero())
|
||||
m_steerVec.normalize();
|
||||
MT_Vector3 newvel = m_velocity*m_steerVec;
|
||||
|
||||
//adjust velocity to avoid obstacles
|
||||
if (m_simulation && m_obstacle /*&& !newvel.fuzzyZero()*/)
|
||||
@ -264,6 +275,7 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
||||
KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(0.,1.,0.));
|
||||
}
|
||||
|
||||
HandleActorFace(newvel);
|
||||
if (isdyna)
|
||||
{
|
||||
//temporary solution: set 2D steering velocity directly to obj
|
||||
@ -295,6 +307,96 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
||||
return true;
|
||||
}
|
||||
|
||||
const MT_Vector3& KX_SteeringActuator::GetSteeringVec()
|
||||
{
|
||||
if (m_isActive)
|
||||
return m_steerVec;
|
||||
else
|
||||
return MT_Vector3(0, 0, 0);
|
||||
}
|
||||
|
||||
void KX_SteeringActuator::HandleActorFace(MT_Vector3& velocity)
|
||||
{
|
||||
if (m_facingMode==0)
|
||||
return;
|
||||
MT_Vector3 dir = velocity;
|
||||
if (dir.fuzzyZero())
|
||||
return;
|
||||
dir.normalize();
|
||||
MT_Vector3 up(0,0,1);
|
||||
MT_Vector3 left;
|
||||
MT_Matrix3x3 mat;
|
||||
switch (m_facingMode)
|
||||
{
|
||||
case 1: // TRACK X
|
||||
{
|
||||
left = dir.safe_normalized();
|
||||
dir = -(left.cross(up)).safe_normalized();
|
||||
break;
|
||||
};
|
||||
case 2: // TRACK Y
|
||||
{
|
||||
left = (dir.cross(up)).safe_normalized();
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: // track Z
|
||||
{
|
||||
left = up.safe_normalized();
|
||||
up = dir.safe_normalized();
|
||||
dir = left;
|
||||
left = (dir.cross(up)).safe_normalized();
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // TRACK -X
|
||||
{
|
||||
left = -dir.safe_normalized();
|
||||
dir = -(left.cross(up)).safe_normalized();
|
||||
break;
|
||||
};
|
||||
case 5: // TRACK -Y
|
||||
{
|
||||
left = (-dir.cross(up)).safe_normalized();
|
||||
dir = -dir;
|
||||
break;
|
||||
}
|
||||
case 6: // track -Z
|
||||
{
|
||||
left = up.safe_normalized();
|
||||
up = -dir.safe_normalized();
|
||||
dir = left;
|
||||
left = (dir.cross(up)).safe_normalized();
|
||||
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)
|
||||
{
|
||||
MT_Point3 localpos;
|
||||
localpos = curobj->GetSGNode()->GetLocalPosition();
|
||||
MT_Matrix3x3 parentmatinv;
|
||||
parentmatinv = parentObject->NodeGetWorldOrientation ().inverse ();
|
||||
mat = parentmatinv * mat;
|
||||
mat = m_parentlocalmat * mat;
|
||||
curobj->NodeSetLocalOrientation(mat);
|
||||
curobj->NodeSetLocalPosition(localpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
curobj->NodeSetLocalOrientation(mat);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -338,6 +440,7 @@ PyAttributeDef KX_SteeringActuator::Attributes[] = {
|
||||
KX_PYATTRIBUTE_FLOAT_RW("turnspeed", 0.0f, 720.0f, KX_SteeringActuator, m_turnspeed),
|
||||
KX_PYATTRIBUTE_BOOL_RW("selfterminated", KX_SteeringActuator, m_isSelfTerminated),
|
||||
KX_PYATTRIBUTE_BOOL_RW("enableVisualization", KX_SteeringActuator, m_enableVisualization),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("steeringVec", KX_SteeringActuator, pyattr_get_steeringVec),
|
||||
KX_PYATTRIBUTE_INT_RW("pathUpdatePeriod", -1, 100000, true, KX_SteeringActuator, m_pathUpdatePeriod),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
@ -404,6 +507,13 @@ int KX_SteeringActuator::pyattr_set_navmesh(void *self, const struct KX_PYATTRIB
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
PyObject* KX_SteeringActuator::pyattr_get_steeringVec(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_SteeringActuator* actuator = static_cast<KX_SteeringActuator*>(self);
|
||||
const MT_Vector3& steeringVec = actuator->GetSteeringVec();
|
||||
return PyObjectFrom(steeringVec);
|
||||
}
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
||||
/* eof */
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
#include "SCA_IActuator.h"
|
||||
#include "SCA_LogicManager.h"
|
||||
#include "MT_Matrix3x3.h"
|
||||
|
||||
class KX_GameObject;
|
||||
class KX_NavMeshObject;
|
||||
@ -64,11 +65,15 @@ class KX_SteeringActuator : public SCA_IActuator
|
||||
bool m_isActive;
|
||||
bool m_isSelfTerminated;
|
||||
bool m_enableVisualization;
|
||||
short m_facingMode;
|
||||
float m_path[MAX_PATH_LENGTH*3];
|
||||
int m_pathLen;
|
||||
int m_pathUpdatePeriod;
|
||||
double m_pathUpdateTime;
|
||||
int m_wayPointIdx;
|
||||
MT_Matrix3x3 m_parentlocalmat;
|
||||
MT_Vector3 m_steerVec;
|
||||
void HandleActorFace(MT_Vector3& velocity);
|
||||
public:
|
||||
enum KX_STEERINGACT_MODE
|
||||
{
|
||||
@ -90,6 +95,7 @@ public:
|
||||
bool isSelfTerminated,
|
||||
int pathUpdatePeriod,
|
||||
KX_ObstacleSimulation* simulation,
|
||||
short facingmode,
|
||||
bool enableVisualization);
|
||||
virtual ~KX_SteeringActuator();
|
||||
virtual bool Update(double curtime, bool frame);
|
||||
@ -98,6 +104,7 @@ public:
|
||||
virtual void ProcessReplica();
|
||||
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
|
||||
virtual bool UnlinkObject(SCA_IObject* clientobj);
|
||||
const MT_Vector3& GetSteeringVec();
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
@ -110,6 +117,7 @@ public:
|
||||
static int pyattr_set_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static PyObject* pyattr_get_navmesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_navmesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static PyObject* pyattr_get_steeringVec(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
Loading…
Reference in New Issue
Block a user