From: <hik...@us...> - 2012-07-27 06:34:32
|
Revision: 11445 http://supertuxkart.svn.sourceforge.net/supertuxkart/?rev=11445&view=rev Author: hikerstk Date: 2012-07-27 06:34:25 +0000 (Fri, 27 Jul 2012) Log Message: ----------- Split skidding handling into three separate functions: determineTrackDirection, handleCurve, doSkid (the latter was already implement, but didn't do anything). Modified Paths: -------------- main/trunk/src/karts/controller/skidding_ai.cpp main/trunk/src/karts/controller/skidding_ai.hpp Modified: main/trunk/src/karts/controller/skidding_ai.cpp =================================================================== --- main/trunk/src/karts/controller/skidding_ai.cpp 2012-07-27 06:31:04 UTC (rev 11444) +++ main/trunk/src/karts/controller/skidding_ai.cpp 2012-07-27 06:34:25 UTC (rev 11445) @@ -22,7 +22,7 @@ //The AI debugging works best with just 1 AI kart, so set the number of karts //to 2 in main.cpp with quickstart and run supertuxkart with the arg -N. #ifdef DEBUG - // Enable AI graphical debugging + // Enable AeI graphical debugging # undef AI_DEBUG // Shows left and right lines when using new findNonCrashing function # undef AI_DEBUG_NEW_FIND_NON_CRASHING @@ -1016,6 +1016,7 @@ m_curve[CURVE_RIGHT]->addPoint(m_kart->getXYZ()+eps); #endif #ifdef AI_DEBUG_KART_HEADING + const Vec3 eps(0,0.5f,0); m_curve[CURVE_KART]->clear(); m_curve[CURVE_KART]->addPoint(m_kart->getXYZ()+eps); Vec3 forw(0, 0, 50); @@ -1214,16 +1215,15 @@ unsigned int next = qg->getNode(m_track_node).getSuccessor(succ); - unsigned int last; - //qg->getNode(m_track_node).getDirectionData(succ, &dir, &last); qg->getNode(next).getDirectionData(m_successor_index[next], - &m_current_track_direction, &last); + &m_current_track_direction, + &m_last_direction_node); #ifdef AI_DEBUG -// m_curve[CURVE_QG]->clear(); -// for(unsigned int i=m_track_node; i<=last; i++) + m_curve[CURVE_QG]->clear(); + for(unsigned int i=m_track_node; i<=m_last_direction_node; i++) { -// m_curve[CURVE_QG]->addPoint(qg->getNode(i).getCenter()); + m_curve[CURVE_QG]->addPoint(qg->getNode(i).getCenter()); } #endif m_controls->m_skid = false; @@ -1231,89 +1231,61 @@ if(m_current_track_direction==GraphNode::DIR_LEFT || m_current_track_direction==GraphNode::DIR_RIGHT ) { - // Ideally we would like to have a circle that: - // 1) goes through the kart position - // 2) has the current heading of the kart as tangent in that point - // 3) goes through the last point - // 4) has a tangent at the last point that faces towards the next node - // Unfortunately conditions 1 to 3 already fully determine the circle, - // i.e. it is not always possible to find an appropriate circle. - // Using the first three conditions is mostly a good choice (since the - // kart will already point towards the direction of the circle), and - // the case that the kart is facing wrong was already tested for above + handleCurve(); + } // if(m_current_track_direction == DIR_LEFT || DIR_RIGHT ) - Vec3 center; - Vec3 xyz = m_kart->getXYZ(); - Vec3 tangent = m_kart->getTrans()(Vec3(0,0,1)) - xyz; - Vec3 last_xyz = qg->getNode(last).getCenter(); - determineTurnRadius(xyz, tangent, last_xyz, - ¢er, &m_current_curve_radius); + return; +} // determineTrackDirection + +// ---------------------------------------------------------------------------- +/** If the kart is at/in a curve, determine the turn radius. + */ +void SkiddingAI::handleCurve() +{ + // Ideally we would like to have a circle that: + // 1) goes through the kart position + // 2) has the current heading of the kart as tangent in that point + // 3) goes through the last point + // 4) has a tangent at the last point that faces towards the next node + // Unfortunately conditions 1 to 3 already fully determine the circle, + // i.e. it is not always possible to find an appropriate circle. + // Using the first three conditions is mostly a good choice (since the + // kart will already point towards the direction of the circle), and + // the case that the kart is facing wrong was already tested for before + + const QuadGraph *qg = QuadGraph::get(); + Vec3 xyz = m_kart->getXYZ(); + Vec3 tangent = m_kart->getTrans()(Vec3(0,0,1)) - xyz; + Vec3 last_xyz = qg->getNode(m_last_direction_node).getCenter(); + + determineTurnRadius(xyz, tangent, last_xyz, + &m_curve_center, &m_current_curve_radius); + #ifdef ADJUST_TURN_RADIUS_TO_AVOID_CRASH_INTO_TRACK - for(unsigned int i=next; i<=last; i++) + for(unsigned int i=next; i<=last; i++) + { + // Pick either the lower left or right point: + int index = m_current_track_direction==GraphNode::DIR_LEFT + ? 0 : 1; + float r = (center - qg->getQuadOfNode(i)[index]).length(); + if(m_current_curve_radius < r) { - // Pick either the lower left or right point: - int index = m_current_track_direction==GraphNode::DIR_LEFT - ? 0 : 1; - float r = (center - qg->getQuadOfNode(i)[index]).length(); - if(m_current_curve_radius < r) - { - determineTurnRadius(xyz, tangent, qg->getQuadOfNode(i)[index], - ¢er, &m_current_curve_radius); - break; - } + determineTurnRadius(xyz, tangent, qg->getQuadOfNode(i)[index], + ¢er, &m_current_curve_radius); + break; } + } #endif #if defined(AI_DEBUG) && defined(AI_DEBUG_CIRCLES) - m_curve[CURVE_PREDICT1]->makeCircle(center, m_current_curve_radius); - m_curve[CURVE_PREDICT1]->addPoint(last_xyz); - m_curve[CURVE_PREDICT1]->addPoint(center); - m_curve[CURVE_PREDICT1]->addPoint(xyz); + m_curve[CURVE_PREDICT1]->makeCircle(m_curve_center, + m_current_curve_radius); + m_curve[CURVE_PREDICT1]->addPoint(last_xyz); + m_curve[CURVE_PREDICT1]->addPoint(m_curve_center); + m_curve[CURVE_PREDICT1]->addPoint(xyz); #endif - // Only try skidding when a certain minimum speed is reached. - if(m_kart->getSpeed() > 5.0f) - { - // Estimate how long it takes to finish the curve - Vec3 diff_kart = xyz - center; - Vec3 diff_last = last_xyz - center; - float angle_kart = atan2(diff_kart.getX(), diff_kart.getZ()); - float angle_last = atan2(diff_last.getX(), diff_last.getZ()); - float angle = m_current_track_direction == GraphNode::DIR_RIGHT - ? angle_last - angle_kart - : angle_kart - angle_last; - angle = normalizeAngle(angle); - float length = m_current_curve_radius*fabsf(angle); - float duration = length / m_kart->getSpeed(); - duration *= 1.5f; - const Skidding *skidding = m_kart->getSkidding(); - if(m_controls->m_skid && duration < 1.0f) - { - m_controls->m_skid = false; - if(m_ai_debug) - printf("[AI] skid : '%s' too short, stop skid.\n", - m_kart->getIdent().c_str()); - } - else if(skidding->getNumberOfBonusTimes()>0 && - skidding->getTimeTillBonus(0) < duration) - { -#ifdef DEBUG - if(m_ai_debug) - printf("[AI] skid: %s start skid, duration %f.\n", - m_kart->getIdent().c_str(), duration); -#endif - m_controls->m_skid = true; - //m_controls->m_steering = - // m_current_track_direction == GraphNode::DIR_RIGHT : 1 : -1; - - } // if curve long enough for skidding - } // if speed > minimum skid speed - } // if(m_current_track_direction == DIR_LEFT || DIR_RIGHT ) - - - return; -} // determineTrackDirection - +} // handleCurve // ---------------------------------------------------------------------------- /** Determines if the kart should skid. The base implementation enables * skidding @@ -1323,7 +1295,51 @@ */ bool SkiddingAI::doSkid(float steer_fraction) { - return m_controls->m_skid; + // No skidding on straights + if(m_current_track_direction==GraphNode::DIR_STRAIGHT) + return false; + + const float MIN_SKID_SPEED = 5.0f; + const QuadGraph *qg = QuadGraph::get(); + Vec3 last_xyz = qg->getNode(m_last_direction_node).getCenter(); + + // Only try skidding when a certain minimum speed is reached. + if(m_kart->getSpeed()<MIN_SKID_SPEED) return false; + + // Estimate how long it takes to finish the curve + Vec3 diff_kart = m_kart->getXYZ() - m_curve_center; + Vec3 diff_last = last_xyz - m_curve_center; + float angle_kart = atan2(diff_kart.getX(), diff_kart.getZ()); + float angle_last = atan2(diff_last.getX(), diff_last.getZ()); + float angle = m_current_track_direction == GraphNode::DIR_RIGHT + ? angle_last - angle_kart + : angle_kart - angle_last; + angle = normalizeAngle(angle); + float length = m_current_curve_radius*fabsf(angle); + float duration = length / m_kart->getSpeed(); + duration *= 1.5f; + const Skidding *skidding = m_kart->getSkidding(); + if(m_controls->m_skid && duration < 1.0f) + { + if(m_ai_debug) + printf("[AI] skid : '%s' too short, stop skid.\n", + m_kart->getIdent().c_str()); + return false; + } + + else if(skidding->getNumberOfBonusTimes()>0 && + skidding->getTimeTillBonus(0) < duration) + { +#ifdef DEBUG + if(m_ai_debug) + printf("[AI] skid: %s start skid, duration %f.\n", + m_kart->getIdent().c_str(), duration); +#endif + return true; + + } // if curve long enough for skidding + + return false; } // doSkid //----------------------------------------------------------------------------- Modified: main/trunk/src/karts/controller/skidding_ai.hpp =================================================================== --- main/trunk/src/karts/controller/skidding_ai.hpp 2012-07-27 06:31:04 UTC (rev 11444) +++ main/trunk/src/karts/controller/skidding_ai.hpp 2012-07-27 06:34:25 UTC (rev 11445) @@ -113,8 +113,6 @@ /** Time an item has been collected and not used. */ float m_time_since_last_shot; - float m_curve_angle; - float m_time_since_stuck; int m_start_kart_crash_direction; //-1 = left, 1 = right, 0 = no crash. @@ -126,6 +124,14 @@ * when being on a straigt section. */ float m_current_curve_radius; + /** Stores the center of the curve (if the kart is in a curve, + * otherwise undefined). */ + Vec3 m_curve_center; + + /** The index of the last node with the same direction as the current + * node the kart is on (i.e. if kart is in a left turn, this will be + * the last node that is still turning left). */ + unsigned int m_last_direction_node; #ifdef DEBUG /** For skidding debugging: shows the estimated turn shape. */ ShowCurve **m_curve; @@ -160,6 +166,7 @@ float *radius); virtual bool doSkid(float steer_fraction); virtual void setSteering(float angle, float dt); + void handleCurve(); protected: virtual unsigned int getNextSector(unsigned int index); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |