BGE: Fix T41502 Path following jumping
authorJorge Bernal <jbernalmartinez@gmail.com>
Wed, 18 Feb 2015 22:24:02 +0000 (23:24 +0100)
committerJorge Bernal <jbernalmartinez@gmail.com>
Wed, 18 Feb 2015 22:24:02 +0000 (23:24 +0100)
New Lock Z velocity parameter was added. This parameter avoid the micro-jumping.
By default it is actived except when you load an old file that it is deactived to keep former behaviour.

Additionally it was solved another issue related with the acceleration: That is the acceleration value was not taked into account and we had always the maximum linear velocity from the beginning of movement. Now the acceleration is taken into account until we reach the maximum velocity.
When you load an old file, the acceleration value is set to the maximum range (1000.f). This way we simulate a maximum velocity constant from the beginning of movement (former behaviour).

{F142195}

Reviewers: moguri, dfelinto, campbellbarton

Reviewed By: campbellbarton

Subscribers: sergey

Differential Revision: https://developer.blender.org/D1074

source/blender/blenkernel/intern/sca.c
source/blender/blenloader/intern/versioning_270.c
source/blender/editors/space_logic/logic_window.c
source/blender/makesdna/DNA_actuator_types.h
source/blender/makesrna/intern/rna_actuator.c
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Ketsji/KX_SteeringActuator.cpp
source/gameengine/Ketsji/KX_SteeringActuator.h

index 9159c9e9afc2571380e2e4f46e6c0d6905884136..c902659c03908bd6f2718e51fc8efa8fd0ab2fb6 100644 (file)
@@ -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:
index 1afdc348c243844f64ef8a43f0e613fdc1c0adbd..f4591e4d107e3779c96a858e1163d30313c18216 100644 (file)
@@ -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;
+                                       }
+                               }
+                       }
+               }
        }
 }
index 37c634672dff773bdad2f037d157017aecc30772..7204144ce857373855fd35c4e73f4dcdbddca306 100644 (file)
@@ -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);
index bdf1b62646d3a78c039cff8fcb15b06aaa9056ce..9af0c1dac10174c88dd2c6a0951adee6d645515f 100644 (file)
@@ -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
index 6f2c968764ccdec60e79b59e18c3dd88d1bbe4d6..83a6d728d8090eaed60553591d037ee36c06d2ec 100644 (file)
@@ -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)
index f6ed3366625fbb24264e3e7d6e49a76cafdf7a1c..ff4b5a61d129ed67db1c21f370ed43cbabb339f8 100644 (file)
@@ -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;
                        }
index ff192299702a7e881a9326d0e88d506ae773e1e2..10d4273a2b4f6633d6a6f07dcb6124818a421b9a 100644 (file)
@@ -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
 };
 
index 1e8ac9a54f07fd85292c21fe71ea098ddb93da34..3273471c166031c0f66d506732c4bac3899108bc 100644 (file)
@@ -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);