///note that carposition must be in patch space ///returns distance from left side of the track float GetHorizontalDistanceAlongPatch(const BEZIER & patch, MATHVECTOR <float, 3> carposition) { MATHVECTOR <float, 3> leftside = (patch.GetPoint(0,0) + patch.GetPoint(3,0))*0.5; MATHVECTOR <float, 3> rightside = (patch.GetPoint(0,3) + patch.GetPoint(3,3))*0.5; MATHVECTOR <float, 3> patchwidthvector = rightside - leftside; return patchwidthvector.Normalize().dot(carposition-leftside); }
///trim the patch's width in-place void TrimPatch(BEZIER & patch, float trimleft_front, float trimright_front, float trimleft_back, float trimright_back) { MATHVECTOR <float, 3> frontvector = (patch.GetPoint(0,3) - patch.GetPoint(0,0)); MATHVECTOR <float, 3> backvector = (patch.GetPoint(3,3) - patch.GetPoint(3,0)); float frontwidth = frontvector.Magnitude(); float backwidth = backvector.Magnitude(); if (trimleft_front + trimright_front > frontwidth) { float scale = frontwidth/(trimleft_front + trimright_front); trimleft_front *= scale; trimright_front *= scale; } if (trimleft_back + trimright_back > backwidth) { float scale = backwidth/(trimleft_back + trimright_back); trimleft_back *= scale; trimright_back *= scale; } MATHVECTOR <float, 3> newfl = patch.GetPoint(0,0); MATHVECTOR <float, 3> newfr = patch.GetPoint(0,3); MATHVECTOR <float, 3> newbl = patch.GetPoint(3,0); MATHVECTOR <float, 3> newbr = patch.GetPoint(3,3); if (frontvector.Magnitude() > 0.001) { MATHVECTOR <float, 3> trimdirection_front = frontvector.Normalize(); newfl = patch.GetPoint(0,0) + trimdirection_front*trimleft_front; newfr = patch.GetPoint(0,3) - trimdirection_front*trimright_front; } if (backvector.Magnitude() > 0.001) { MATHVECTOR <float, 3> trimdirection_back = backvector.Normalize(); newbl = patch.GetPoint(3,0) + trimdirection_back*trimleft_back; newbr = patch.GetPoint(3,3) - trimdirection_back*trimright_back; } patch.SetFromCorners(newfl, newfr, newbl, newbr); }
BEZIER AI::RevisePatch(const BEZIER * origpatch, bool use_racingline) { BEZIER patch = *origpatch; //take into account the racing line //use_racingline = false; if (use_racingline && patch.GetNextPatch() && patch.HasRacingline()) { float widthfront = std::min((patch.GetNextPatch()->GetRacingLine()-patch.GetPoint(0,0)).Magnitude(), (patch.GetNextPatch()->GetRacingLine()-patch.GetPoint(0,3)).Magnitude()); float widthback = std::min((patch.GetRacingLine()-patch.GetPoint(3,0)).Magnitude(), (patch.GetRacingLine()-patch.GetPoint(3,3)).Magnitude()); float trimleft_front = (patch.GetNextPatch()->GetRacingLine() - patch.GetPoint(0,0)).Magnitude()-widthfront; float trimright_front = (patch.GetNextPatch()->GetRacingLine() - patch.GetPoint(0,3)).Magnitude()-widthfront; float trimleft_back = (patch.GetRacingLine() - patch.GetPoint(3,0)).Magnitude()-widthback; float trimright_back = (patch.GetRacingLine() - patch.GetPoint(3,3)).Magnitude()-widthback; TrimPatch(patch, trimleft_front, trimright_front, trimleft_back, trimright_back); } //check for revisions due to other cars /*const float trim_falloff_distance = 100.0; //trim fallof distance in meters per (meters per second) const MATHVECTOR <float, 3> throttle_axis(-1,0,0); //positive is in front of the car std::map <const CAR *, PATH_REVISION> & revmap = path_revisions; for (std::map <const CAR *, PATH_REVISION>::iterator i = revmap.begin(); i != revmap.end(); i++) { if (i->first != c->car) { //compute relative info MATHVECTOR <float, 3> myvel = c->car->GetVelocity(); MATHVECTOR <float, 3> othervel = i->first->GetVelocity(); (-c->car->GetOrientation()).RotateVector(myvel); (-i->first->GetOrientation()).RotateVector(othervel); float speed_diff = myvel.dot(throttle_axis) - othervel.dot(throttle_axis); //positive if other car is faster //actually positive if my car is faster, right? float cardist_back = patch.dist_from_start - i->second.car_pos_along_track; //positive if patch is ahead of car float patchlen = GetPatchDirection(patch).Magnitude(); float cardist_front = (patch.dist_from_start+patchlen) - i->second.car_pos_along_track; const float minfalloff = 10; const float maxfalloff = 60; float cur_trim_falloff_distance_fwd = minfalloff; float cur_trim_falloff_distance_rear = minfalloff; float falloff = clamp(trim_falloff_distance*std::abs(speed_diff),minfalloff,maxfalloff); if (speed_diff > 0) { //cur_trim_falloff_distance_fwd = falloff; } else cur_trim_falloff_distance_rear = falloff; float scale_front = clamp(1.0f-cardist_front/cur_trim_falloff_distance_fwd, 0, 1); if (cardist_front < 0) scale_front = clamp(1.0f+cardist_front/cur_trim_falloff_distance_rear, 0, 1); float scale_back = clamp(1.0f-cardist_back/cur_trim_falloff_distance_fwd, 0, 1); if (cardist_back < 0) scale_back = clamp(1.0f+cardist_back/cur_trim_falloff_distance_rear, 0, 1); std::cout << speed_diff << ", " << cur_trim_falloff_distance_fwd << ", " << cur_trim_falloff_distance_rear << ", " << cardist_front << ", " << cardist_back << ", " << scale_front << ", " << scale_back << std::endl; float trimleft_front = i->second.trimleft_front*scale_front; float trimright_front = i->second.trimright_front*scale_front; float trimleft_back = i->second.trimleft_back*scale_back; float trimright_back = i->second.trimright_back*scale_back; TrimPatch(patch, trimleft_front, trimright_front, trimleft_back, trimright_back); } }*/ return patch; }
MATHVECTOR <float, 3> GetPatchWidthVector(const BEZIER & patch) { return ((patch.GetPoint(0,0) + patch.GetPoint(3,0)) - (patch.GetPoint(0,3) + patch.GetPoint(3,3))) * 0.5; }
MATHVECTOR <float, 3> GetPatchBackCenter(const BEZIER & patch) { return (patch.GetPoint(3,0) + patch.GetPoint(3,3)) * 0.5; }
MATHVECTOR <float, 3> GetPatchFrontCenter(const BEZIER & patch) { return (patch.GetPoint(0,0) + patch.GetPoint(0,3)) * 0.5; }
MATHVECTOR <float, 3> AI_Car_Experimental::GetPatchWidthVector(const BEZIER & patch) { return ((patch.GetPoint(0,0) + patch.GetPoint(3,0)) - (patch.GetPoint(0,3) + patch.GetPoint(3,3))) * 0.5; }
MATHVECTOR <float, 3> AI_Car_Experimental::GetPatchBackCenter(const BEZIER & patch) { return (patch.GetPoint(3,0) + patch.GetPoint(3,3)) * 0.5; }