Added 'early targeting': the rubber ball will align its relative position
to the center of the track according to the relative distance of its target (more precisely: it will move the interpolation control points). This results in the ball being better align when it switches to aim-directly-at- target mode, meaning that the target-distance can be reduced, hopefully reducing the frequency with which tunneling happens. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10016 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
81ce56c358
commit
b9e4325560
@ -43,13 +43,23 @@
|
||||
squash-duration: How long karts stay squashed.
|
||||
delete-timer: How long before the ball is removed
|
||||
if no suitable target is found.
|
||||
early-target-factor: the rubber ball can use the
|
||||
relative position of the kart to the
|
||||
center of the track for improved targeting
|
||||
(i.e. the ball will align its relative
|
||||
position to the center of the track early).
|
||||
This allows a lower target-distance to be
|
||||
used since the ball is better aligned,
|
||||
hopefully reducing the frequency of
|
||||
tunneling.
|
||||
-->
|
||||
<item name="rubber-ball" icon="rubber_ball-icon.png"
|
||||
model="rubber_ball.b3d" speed="35.0"
|
||||
scale="1 1 1" interval="1"
|
||||
max-height="4.0" min-height="0"
|
||||
fast-ping-distance="50"
|
||||
target-distance="25" target-max-angle = "90"
|
||||
early-target-factor="1"
|
||||
target-distance="15" target-max-angle = "90"
|
||||
min-interpolation-distance="10"
|
||||
squash-slowdown="0.5" squash-duration="3"
|
||||
delete-time="5.0" max-height-difference="10" />
|
||||
|
@ -37,6 +37,7 @@ float RubberBall::m_st_target_max_angle;
|
||||
float RubberBall::m_st_delete_time;
|
||||
float RubberBall::m_st_max_height_difference;
|
||||
float RubberBall::m_st_fast_ping_distance;
|
||||
float RubberBall::m_st_early_target_factor;
|
||||
int RubberBall::m_next_id = 0;
|
||||
|
||||
RubberBall::RubberBall(Kart *kart)
|
||||
@ -62,29 +63,28 @@ RubberBall::RubberBall(Kart *kart)
|
||||
|
||||
// Do not adjust the up velocity
|
||||
setAdjustUpVelocity(false);
|
||||
m_max_lifespan = 9999;
|
||||
m_target = NULL;
|
||||
m_ping_sfx = sfx_manager->createSoundSource("ball_bounce");
|
||||
m_max_lifespan = 9999;
|
||||
m_target = NULL;
|
||||
m_aiming_at_target = false;
|
||||
m_fast_ping = false;
|
||||
// At the start the ball aims at quads till it gets close enough to the
|
||||
// target:
|
||||
m_height_timer = 0.0f;
|
||||
m_interval = m_st_interval;
|
||||
m_current_max_height = m_max_height;
|
||||
m_ping_sfx = sfx_manager->createSoundSource("ball_bounce");
|
||||
// Just init the previoux coordinates with some value that's not getXYZ()
|
||||
m_previous_xyz = m_owner->getXYZ();
|
||||
m_previous_xyz = m_owner->getXYZ();
|
||||
|
||||
// A negative value indicates that the timer is not active
|
||||
m_delete_timer = -1.0f;
|
||||
m_delete_timer = -1.0f;
|
||||
|
||||
computeTarget();
|
||||
|
||||
|
||||
// initialises the current graph node
|
||||
TrackSector::update(getXYZ());
|
||||
initializeControlPoints(m_owner->getXYZ());
|
||||
|
||||
// At the start the ball aims at quads till it gets close enough to the
|
||||
// target:
|
||||
m_aiming_at_target = false;
|
||||
m_fast_ping = false;
|
||||
m_height_timer = 0.0f;
|
||||
m_interval = m_st_interval;
|
||||
m_current_max_height = m_max_height;
|
||||
} // RubberBall
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -209,8 +209,26 @@ void RubberBall::getNextControlPoint()
|
||||
|
||||
m_last_aimed_graph_node = next;
|
||||
m_length_cp_2_3 = dist;
|
||||
m_control_points[3] =
|
||||
QuadGraph::get()->getQuadOfNode(m_last_aimed_graph_node).getCenter();
|
||||
const Quad &quad =
|
||||
QuadGraph::get()->getQuadOfNode(m_last_aimed_graph_node);
|
||||
Vec3 aim = quad.getCenter();
|
||||
// If we are close enough for the ball to hop faster, adjust the position
|
||||
// relative to the center of the track depending on where the target is:
|
||||
|
||||
// if(m_fast_ping)
|
||||
{
|
||||
LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld());
|
||||
float r = world->getTrackSector(m_target->getWorldKartId())
|
||||
.getRelativeDistanceToCenter();
|
||||
printf("ratio r %f, adjusting from %f %f ", r,
|
||||
aim.getX(), aim.getZ());
|
||||
aim -= m_st_early_target_factor * r
|
||||
* QuadGraph::get()->getNode(m_last_aimed_graph_node)
|
||||
.getCenterToRightVector();
|
||||
printf(" to %f %f\n", aim.getX(), aim.getZ());
|
||||
}
|
||||
|
||||
m_control_points[3] = aim;
|
||||
} // getNextControlPoint
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -221,15 +239,16 @@ void RubberBall::getNextControlPoint()
|
||||
*/
|
||||
void RubberBall::init(const XMLNode &node, scene::IMesh *bowling)
|
||||
{
|
||||
m_st_interval = 1.0f;
|
||||
m_st_squash_duration = 3.0f;
|
||||
m_st_squash_slowdown = 0.5f;
|
||||
m_st_interval = 1.0f;
|
||||
m_st_squash_duration = 3.0f;
|
||||
m_st_squash_slowdown = 0.5f;
|
||||
m_st_min_interpolation_distance = 30.0f;
|
||||
m_st_target_distance = 50.0f;
|
||||
m_st_target_max_angle = 25.0f;
|
||||
m_st_delete_time = 10.0f;
|
||||
m_st_max_height_difference = 10.0f;
|
||||
m_st_fast_ping_distance = 50.0f;
|
||||
m_st_early_target_factor = 1.0f;
|
||||
|
||||
if(!node.get("interval", &m_st_interval))
|
||||
printf("[powerup] Warning: no interval specified for rubber ball.\n");
|
||||
@ -260,11 +279,15 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *bowling)
|
||||
"rubber ball.\n");
|
||||
if(!node.get("fast-ping-distance", &m_st_fast_ping_distance))
|
||||
printf(
|
||||
"[powerup] Warning: no fast-ping-distancespecified for "
|
||||
"[powerup] Warning: no fast-ping-distance specified for "
|
||||
"rubber ball.\n");
|
||||
if(m_st_fast_ping_distance < m_st_target_distance)
|
||||
printf("Warning: ping-distance is smaller than target distance.\n"
|
||||
"hat should not happen, but is ignored for now.\n");
|
||||
if(!node.get("early-target-factor", &m_st_early_target_factor))
|
||||
printf(
|
||||
"[powerup] Warning: no early-target-factor specified for "
|
||||
"rubber ball.\n");
|
||||
Flyable::init(node, bowling, PowerupManager::POWERUP_RUBBERBALL);
|
||||
} // init
|
||||
|
||||
|
@ -83,6 +83,22 @@ private:
|
||||
* ball will be deleted. */
|
||||
static float m_st_delete_time;
|
||||
|
||||
/** This factor is used to influence how much the rubber ball should aim
|
||||
* at its target early. It used the 'distance to center of track' of its
|
||||
* target, and adjusts the interpolation control points to be more or
|
||||
* less at the same (relative) distance from center. If the factor is
|
||||
* 1, the rubber ball will aim to be at the same relative distance,
|
||||
* if the factor is 0, the rubber ball will aim directly at the
|
||||
* driveline points. A factor of 1 usually means that by the time
|
||||
* the ball starts aiming directly at the target it is (nearly) on the
|
||||
* same 'line', meaning it only has to go straight. On the other hand
|
||||
* in a tunnel this might result in the ball being too far to the
|
||||
* side, increasing the likelihood of the ball tunneling through
|
||||
* (which can happen when the ball switches to aim-at-target mode,
|
||||
* in a tight curve, so that the direct line to the target goes through
|
||||
* a wall. */
|
||||
static float m_st_early_target_factor;
|
||||
|
||||
/** A pointer to the target kart. */
|
||||
const Kart *m_target;
|
||||
|
||||
|
@ -61,6 +61,10 @@ GraphNode::GraphNode(unsigned int quad_index, unsigned int node_index)
|
||||
// Only this 2d point is needed later
|
||||
m_lower_center_2d = core::vector2df(m_lower_center.getX(),
|
||||
m_lower_center.getZ() );
|
||||
|
||||
// The vector from the center of the quad to the middle of the right
|
||||
// side of the quad
|
||||
m_center_to_right = (quad[1]+quad[2])*0.5f - quad.getCenter();
|
||||
} // GraphNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -33,7 +33,8 @@
|
||||
class QuadGraph;
|
||||
|
||||
/**
|
||||
* \brief This class stores a node of the graph, i.e. a list of successor edges.
|
||||
* \brief This class stores a node of the graph, i.e. a list of successor
|
||||
* edges.
|
||||
* \ingroup tracks
|
||||
*/
|
||||
class GraphNode
|
||||
@ -81,6 +82,9 @@ class GraphNode
|
||||
/** Upper center point of the graph node. */
|
||||
Vec3 m_upper_center;
|
||||
|
||||
/** A vector from the center of the quad to the right edge. */
|
||||
Vec3 m_center_to_right;
|
||||
|
||||
/** Line between lower and upper center, saves computation in
|
||||
* getDistanceFromLine() later. The line is 2d only since otherwise
|
||||
* taller karts would have a larger distance from the center. It also
|
||||
@ -118,6 +122,7 @@ public:
|
||||
void getDistances(const Vec3 &xyz, Vec3 *result);
|
||||
float getDistance2FromPoint(const Vec3 &xyz);
|
||||
void setupPathsToNode();
|
||||
void setChecklineRequirements(int latest_checkline);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the i-th successor node. */
|
||||
unsigned int getSuccessor(unsigned int i) const
|
||||
@ -167,7 +172,8 @@ public:
|
||||
const Vec3& getUpperCenter() const {return m_upper_center;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the center point of this graph node. */
|
||||
const Vec3 getCenter() const {return (m_upper_center + m_lower_center) / 2.0f;}
|
||||
const Vec3 getCenter() const
|
||||
{return (m_upper_center + m_lower_center) / 2.0f;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the length of the quad of this node. */
|
||||
float getNodeLength() const
|
||||
@ -193,12 +199,15 @@ public:
|
||||
// If we have a path to node vector, use its information, otherwise
|
||||
// (i.e. there is only one successor anyway) use this one successor.
|
||||
return m_path_to_node.size()>0 ? m_path_to_node[n] : 0;
|
||||
}
|
||||
} // getSuccesorToReach
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void setChecklineRequirements(int latest_checkline);
|
||||
|
||||
const std::vector<int>& getChecklineRequirements() const { return m_checkline_requirements; }
|
||||
/** Returns a vector from the center of the node to the middle of the
|
||||
* right side. */
|
||||
const Vec3 &getCenterToRightVector() const { return m_center_to_right; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the checkline requirements of this graph node. */
|
||||
const std::vector<int>& getChecklineRequirements() const
|
||||
{ return m_checkline_requirements; }
|
||||
}; // GraphNode
|
||||
|
||||
#endif
|
||||
|
@ -112,3 +112,21 @@ void TrackSector::rescue()
|
||||
m_last_valid_graph_node = QuadGraph::get()->getNode(m_current_graph_node)
|
||||
.getPredecessor();
|
||||
} // rescue
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the relative distance of the corresponding kart from the center,
|
||||
* i.e. a value between -1 and 1 inclusive.
|
||||
* \return THe relative distance between -1.0f and +1.0f;
|
||||
*/
|
||||
float TrackSector::getRelativeDistanceToCenter() const
|
||||
{
|
||||
float w = QuadGraph::get()->getNode(m_current_graph_node).getPathWidth();
|
||||
// w * 0.5 is the distance from center of the quad to the left or right
|
||||
// This way we get a value between -1 and 1.
|
||||
float ratio = getDistanceToCenter()/(w*0.5f);
|
||||
if(ratio>1.0f)
|
||||
ratio=1.0f;
|
||||
else if(ratio<-1.0f)
|
||||
ratio=-1.0f;
|
||||
return ratio;
|
||||
} // getRelativeDistanceToCenter
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
void reset();
|
||||
void rescue();
|
||||
void update(const Vec3 &xyz);
|
||||
float getRelativeDistanceToCenter() const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how far the the object is from the start line. */
|
||||
float getDistanceFromStart() const { return m_current_track_coords.getZ();}
|
||||
|
Loading…
Reference in New Issue
Block a user