diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 9159c9e9afc..c902659c039 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -496,7 +496,7 @@ void init_actuator(bActuator *act) sta->turnspeed = 120.f; sta->dist = 1.f; sta->velocity= 3.f; - sta->flag = ACT_STEERING_AUTOMATICFACING; + sta->flag = ACT_STEERING_AUTOMATICFACING | ACT_STEERING_LOCKZVEL; sta->facingaxis = 1; break; case ACT_MOUSE: diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 1afdc348c24..f4591e4d107 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -616,5 +616,17 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + if (!DNA_struct_elem_find(fd->filesdna, "bSteeringActuator", "float", "acceleration")) { + for (ob = main->object.first; ob; ob = ob->id.next) { + bActuator *act; + for (act = ob->actuators.first; act; act = act->next) { + if (act->type == ACT_STEERING) { + bSteeringActuator *sact = act->data; + sact->acceleration = 1000.f; + } + } + } + } } } diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 37c634672df..7204144ce85 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -2105,12 +2105,15 @@ static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr) } row = uiLayoutRow(layout, false); - uiItemR(row, ptr, "self_terminated", 0, NULL, ICON_NONE); + col = uiLayoutColumn(row, false); + uiItemR(col, ptr, "self_terminated", 0, NULL, ICON_NONE); if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING) { - uiItemR(row, ptr, "update_period", 0, NULL, ICON_NONE); - row = uiLayoutRow(layout, false); + col = uiLayoutColumn(row, false); + uiItemR(col, ptr, "update_period", 0, NULL, ICON_NONE); } row = uiLayoutRow(layout, false); + uiItemR(row, ptr, "lock_z_velocity", 1, NULL, ICON_NONE); + row = uiLayoutRow(layout, false); uiItemR(row, ptr, "show_visualization", 0, NULL, ICON_NONE); if (RNA_enum_get(ptr, "mode") != ACT_STEERING_PATHFOLLOWING) { uiLayoutSetActive(row, false); diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index bdf1b62646d..9af0c1dac10 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -570,6 +570,7 @@ typedef struct bActuator { #define ACT_STEERING_ENABLEVISUALIZATION 2 #define ACT_STEERING_AUTOMATICFACING 4 #define ACT_STEERING_NORMALUP 8 +#define ACT_STEERING_LOCKZVEL 16 /* mouseactuator->type */ #define ACT_MOUSE_VISIBILITY 0 diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c index 6f2c968764c..83a6d728d80 100644 --- a/source/blender/makesrna/intern/rna_actuator.c +++ b/source/blender/makesrna/intern/rna_actuator.c @@ -2056,6 +2056,11 @@ static void rna_def_steering_actuator(BlenderRNA *brna) 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); + + prop = RNA_def_property(srna, "lock_z_velocity", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_LOCKZVEL); + RNA_def_property_ui_text(prop, "Lock Z velocity", "Disable simulation of linear motion along Z axis"); + RNA_def_property_update(prop, NC_LOGIC, NULL); } static void rna_def_mouse_actuator(BlenderRNA *brna) diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index f6ed3366625..ff4b5a61d12 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -1087,11 +1087,12 @@ void BL_ConvertActuators(const char* maggiename, 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; + bool lockzvel = (stAct->flag & ACT_STEERING_LOCKZVEL) !=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, normalup, enableVisualization); + scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization, lockzvel); baseact = tmpstact; break; } diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.cpp b/source/gameengine/Ketsji/KX_SteeringActuator.cpp index ff192299702..10d4273a2b4 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.cpp +++ b/source/gameengine/Ketsji/KX_SteeringActuator.cpp @@ -41,7 +41,7 @@ /* Native functions */ /* ------------------------------------------------------------------------- */ -KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj, +KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj, int mode, KX_GameObject *target, KX_GameObject *navmesh, @@ -54,7 +54,8 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj, KX_ObstacleSimulation* simulation, short facingmode, bool normalup, - bool enableVisualization) + bool enableVisualization, + bool lockzvel) : SCA_IActuator(gameobj, KX_ACT_STEERING), m_target(target), m_mode(mode), @@ -72,6 +73,7 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj, m_normalUp(normalup), m_pathLen(0), m_pathUpdatePeriod(pathUpdatePeriod), + m_lockzvel(lockzvel), m_wayPointIdx(-1), m_steerVec(MT_Vector3(0, 0, 0)) { @@ -261,19 +263,19 @@ bool KX_SteeringActuator::Update(double curtime, bool frame) if (apply_steerforce) { + MT_Vector3 newvel; bool isdyna = obj->IsDynamic(); if (isdyna) 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()*/) { if (m_enableVisualization) KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(1.0, 0.0, 0.0)); - m_simulation->AdjustObstacleVelocity(m_obstacle, m_mode!=KX_STEERING_PATHFOLLOWING ? m_navmesh : NULL, + m_simulation->AdjustObstacleVelocity(m_obstacle, m_mode!=KX_STEERING_PATHFOLLOWING ? m_navmesh : NULL, newvel, m_acceleration*delta, m_turnspeed/180.0f*M_PI*delta); if (m_enableVisualization) KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(0.0, 1.0, 0.0)); @@ -282,10 +284,18 @@ bool KX_SteeringActuator::Update(double curtime, bool frame) HandleActorFace(newvel); if (isdyna) { - //temporary solution: set 2D steering velocity directly to obj - //correct way is to apply physical force + //TODO: Take into account angular velocity on turns MT_Vector3 curvel = obj->GetLinearVelocity(); - newvel.z() = curvel.z(); + + newvel = (curvel.length() * m_steerVec) + (m_acceleration * delta) * m_steerVec; + if (newvel.length2() >= (m_velocity * m_velocity)) + newvel = m_velocity * m_steerVec; + + if (m_lockzvel) + newvel.z() = 0.0f; + else + newvel.z() = curvel.z(); + obj->setLinearVelocity(newvel, false); } else @@ -554,6 +564,7 @@ PyAttributeDef KX_SteeringActuator::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("steeringVec", KX_SteeringActuator, pyattr_get_steeringVec), KX_PYATTRIBUTE_SHORT_RW("facingMode", 0, 6, true, KX_SteeringActuator, m_facingMode), KX_PYATTRIBUTE_INT_RW("pathUpdatePeriod", -1, 100000, true, KX_SteeringActuator, m_pathUpdatePeriod), + KX_PYATTRIBUTE_BOOL_RW("lockZVelocity", KX_SteeringActuator, m_lockzvel), { NULL } //Sentinel }; diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.h b/source/gameengine/Ketsji/KX_SteeringActuator.h index 1e8ac9a54f0..3273471c166 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.h +++ b/source/gameengine/Ketsji/KX_SteeringActuator.h @@ -62,6 +62,7 @@ class KX_SteeringActuator : public SCA_IActuator int m_pathLen; int m_pathUpdatePeriod; double m_pathUpdateTime; + bool m_lockzvel; int m_wayPointIdx; MT_Matrix3x3 m_parentlocalmat; MT_Vector3 m_steerVec; @@ -89,7 +90,8 @@ public: KX_ObstacleSimulation* simulation, short facingmode, bool normalup, - bool enableVisualization); + bool enableVisualization, + bool lockzvel); virtual ~KX_SteeringActuator(); virtual bool Update(double curtime, bool frame);