From 2c3e5395c67c33a032e1d8734c6c9ca603b87206 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Fri, 22 Jul 2011 06:26:28 +0000 Subject: [PATCH] Updated height and interval handling if the ball is getting closer to the target. Now the ball behaviour keeps being smooth while it is getting closer to the target. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9323 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/items/rubber_ball.cpp | 83 +++++++++++++++++++++------------------ src/items/rubber_ball.hpp | 12 ++---- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 903ffae52..61e66a94b 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -67,10 +67,9 @@ RubberBall::RubberBall(Kart *kart) : Flyable(kart, PowerupManager::POWERUP_RUBBE // target: m_aiming_at_target = false; m_wrapped_around = false; - m_previous_height = 0.0f; m_timer = 0.0f; m_interval = m_st_interval; - + m_height = m_max_height; } // RubberBall // ----------------------------------------------------------------------------- @@ -160,56 +159,62 @@ void RubberBall::update(float dt) m_wrapped_around = old_distance > 0.9f * track_length && m_distance_along_track < 10.0f; + // FIXME: do we want to test if we have overtaken the target kart? - LinearWorld *world = dynamic_cast(World::getWorld()); - - float target_distance = - world->getDistanceDownTrackForKart(m_target->getWorldKartId()); - - - float x = target_distance - m_distance_along_track; - if(x<0) - x+=track_length; + // When the ball hits the floor, we adjust maximum height and + // interval so that the ball bounces faster when it is getting + // closer to the target. m_timer += dt; if(m_timer>m_interval) + { m_timer -= m_interval; - float height; - if(x>50) - { - // Consider f(x) = x*(x-m_intervall), which is a parabolic function - // with f(0) = 0, f(m_intervall)=0. We then scale this function to - // fulfill: f(m_intervall/2) = m_max_height, or: - // f(m_interval/2) = -m_interval^2/4 = m_max_height - // --> scale with m_max_height / -m_interval^2/4 - float f = m_max_height / (-0.25f*m_interval*m_interval); - height = m_timer * (m_timer-m_interval) * f; + LinearWorld *world = dynamic_cast(World::getWorld()); + float target_distance = + world->getDistanceDownTrackForKart(m_target->getWorldKartId()); - // If we start the squashing as soon as the height is smaller than - // height of the ball, it looks to extreme. So a ratio r of the height - // of the ball and the current height of the object is used to tweak - // the look a bit. - float r = 2.0f; - if(r*heightsetScale(core::vector3df(1.0f, r*height/m_extend.getY(), - 1.0f)); + float distance = target_distance - m_distance_along_track; + if(distance<0) + distance+=track_length; + if(distance<50) + { + // Some experimental formulas + m_height = 0.5f*sqrt(distance); + m_interval = m_height / 10.0f; + } else - m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f)); + { + // Reset the values in case that the ball was already trying + // to get closer to the target, and then the target disappears + // (e.g. is eliminated or finishes the race). + m_interval = m_st_interval; + m_height = m_max_height; + } } - else - { - height = 0.5f*sqrt(x)*fabsf(sinf(10.0f*log(0.005f*(x+5.0f)))); - } -#if 0 - printf("ball z %f dt %f x %f h %f, ah %f\n", - next_xyz.getZ(),dt, - x, height1, average_height); -#endif + + // Consider f(x) = x*(x-m_intervall), which is a parabolic function + // with f(0) = 0, f(m_intervall)=0. We then scale this function to + // fulfill: f(m_intervall/2) = m_height, or: + // f(m_interval/2) = -m_interval^2/4 = m_height + // --> scale with m_height / -m_interval^2/4 + float f = m_height / (-0.25f*m_interval*m_interval); + float height = m_timer * (m_timer-m_interval) * f; next_xyz.setY(getHoT() + height); + // If we start squashing the ball as soon as the height is smaller than + // height of the ball, it looks to extreme. So a ratio r of the height + // of the ball and the current height of the object is used to tweak + // the look a bit. + float r = 2.0f; + if(r*heightsetScale(core::vector3df(1.0f, r*height/m_extend.getY(), + 1.0f)); + else + m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f)); + setXYZ(next_xyz); } // update diff --git a/src/items/rubber_ball.hpp b/src/items/rubber_ball.hpp index 270ade326..8d04024b5 100644 --- a/src/items/rubber_ball.hpp +++ b/src/items/rubber_ball.hpp @@ -45,17 +45,9 @@ private: * point we aimed at and have to aim at the next point. */ float m_distance_along_track; - /** Since the distance between target and ball can vary a bit, - * using it to determine height on a formula is not smooth (e.g. - * ball can actually go up a bit during one frame while actually - * going down). Therefore we use a weighted average of previous - * height newly determined height. */ - float m_previous_height; - /** A class variable to store the default interval size. */ static float m_st_interval; - /** How long it takes from one bounce of the ball to the next. */ float m_interval; @@ -63,6 +55,10 @@ private: * It is always between 0 and m_interval. */ float m_timer; + /** The maximum height of the ball. This value will be reduced if the + * ball gets closer to the target. */ + float m_height; + /** True if the ball just crossed the start line, i.e. its * distance changed from close to length of track in the * previous time step to a bit over zero now. */