//==========================================================================* // Get information to the point nearest the given position //--------------------------------------------------------------------------* bool TLane::GetLanePoint(double TrackPos, TLanePoint& LanePoint) const { int Count = oTrack->Count(); int Idx0 = oTrack->IndexFromPos(TrackPos); int Idxp = (Idx0 - 1 + Count) % Count; int Idx1 = (Idx0 + 1) % Count; int Idx2 = (Idx0 + 2) % Count; double Dist0 = oPathPoints[Idx0].Dist(); double Dist1 = oPathPoints[Idx1].Dist(); if (Idx1 == 0) Dist1 = oTrack->Length(); TVec3d P0 = oPathPoints[Idxp].CalcPt(); TVec3d P1 = oPathPoints[Idx0].CalcPt(); TVec3d P2 = oPathPoints[Idx1].CalcPt(); TVec3d P3 = oPathPoints[Idx2].CalcPt(); double Crv1 = TUtils::CalcCurvatureXY(P0, P1, P2); double Crv2 = TUtils::CalcCurvatureXY(P1, P2, P3); double Crv1z = TUtils::CalcCurvatureZ(P0, P1, P2); double Crv2z = TUtils::CalcCurvatureZ(P1, P2, P3); double Tx = (TrackPos - Dist0) / (Dist1 - Dist0); LanePoint.Index = Idx0; LanePoint.Crv = (1.0 - Tx) * Crv1 + Tx * Crv2; LanePoint.Crvz = (1.0 - Tx) * Crv1z + Tx * Crv2z; LanePoint.T = Tx; LanePoint.Offset = (oPathPoints[Idx0].Offset) + Tx * (oPathPoints[Idx1].Offset - oPathPoints[Idx0].Offset); double Ang0 = TUtils::VecAngXY(oPathPoints[Idx1].CalcPt() - oPathPoints[Idx0].CalcPt()); double Ang1 = TUtils::VecAngXY(oPathPoints[Idx2].CalcPt() - oPathPoints[Idx1].CalcPt()); double DeltaAng = Ang1 - Ang0; DOUBLE_NORM_PI_PI(DeltaAng); LanePoint.Angle = Ang0 + LanePoint.T * DeltaAng; TVec2d Tang1, Tang2; TUtils::CalcTangent(P0.GetXY(), P1.GetXY(), P2.GetXY(), Tang1); TUtils::CalcTangent(P1.GetXY(), P2.GetXY(), P3.GetXY(), Tang2); //TVec2d Dir = TUtils::VecUnit(Tang1) * (1 - Tx) + TUtils::VecUnit(Tang2) * Tx; Ang0 = TUtils::VecAngle(Tang1); Ang1 = TUtils::VecAngle(Tang2); DeltaAng = Ang1 - Ang0; DOUBLE_NORM_PI_PI(DeltaAng); LanePoint.Speed = oPathPoints[LanePoint.Index].Speed + (oPathPoints[Idx1].Speed - oPathPoints[LanePoint.Index].Speed) * LanePoint.T; LanePoint.AccSpd = oPathPoints[LanePoint.Index].AccSpd + (oPathPoints[Idx1].AccSpd - oPathPoints[LanePoint.Index].AccSpd) * LanePoint.T; return true; }
//==========================================================================* // Update // // ATTENTION oCar ist opponents car, so we can use our shortcuts!!! //--------------------------------------------------------------------------* void TOpponent::Update( const PCarElt MyCar, double MyDirX, double MyDirY, float &MinDistBack, double &MinTimeSlot) { if((CarState & RM_CAR_STATE_NO_SIMU) && // omit cars out of race (CarState & RM_CAR_STATE_PIT) == 0 ) // if not in pit return; oInfo.State.Speed = myhypot(CarSpeedX,CarSpeedY);// Speed of car // Track relative speed of opponents car TVec2d ToRight = oTrack->Normale(DistanceFromStartLine); oInfo.State.TrackVelLong = ToRight.x * CarSpeedY - ToRight.y * CarSpeedX; oInfo.State.TrackVelLat = ToRight.x * CarSpeedX + ToRight.y * CarSpeedY; // Track relative yaw of other car. oInfo.State.TrackYaw = CarYaw - TUtils::VecAngle(ToRight) - PI / 2; DOUBLE_NORM_PI_PI(oInfo.State.TrackYaw); // Average velocity of other car. oInfo.State.AvgVelLong = oInfo.State.AvgVelLong * AVG_KEEP + CarPubGlobVelX * AVG_CHANGE; oInfo.State.AvgVelLat = oInfo.State.AvgVelLat * AVG_KEEP + CarPubGlobVelY * AVG_CHANGE; oInfo.State.CarAvgVelLong = MyDirX * oInfo.State.AvgVelLong + MyDirY * oInfo.State.AvgVelLat; //oInfo.State.CarAvgVelLat = MyDirY * oInfo.State.AvgVelLong - MyDirX * oInfo.State.AvgVelLat; // Average acceleration of other car. oInfo.State.AvgAccLong = oInfo.State.AvgAccLong * AVG_KEEP + CarPubGlobAccX * AVG_CHANGE; oInfo.State.AvgAccLat = oInfo.State.AvgAccLat * AVG_KEEP + CarPubGlobAccY * AVG_CHANGE; oInfo.State.CarAvgAccLong = MyDirX * oInfo.State.AvgAccLong + MyDirY * oInfo.State.AvgAccLat; oInfo.State.CarAvgAccLat = MyDirY * oInfo.State.AvgAccLong - MyDirX * oInfo.State.AvgAccLat; // Offset from track center line. oInfo.State.Offset = -CarToMiddle; if(oCar == MyCar) return; // Car-Car relative calculations ... // calc other cars position, velocity relative to my car (global coords). double DistX = CarPubGlobPosX - MyCar->pub.DynGCg.pos.x; double DistY = CarPubGlobPosY - MyCar->pub.DynGCg.pos.y; double DiffVelX = CarSpeedX - MyCar->_speed_X; double DiffVelY = CarSpeedY - MyCar->_speed_Y; // work out relative position, velocity in local coords (coords of my car). oInfo.State.CarDistLong = MyDirX * DistX + MyDirY * DistY; oInfo.State.CarDistLat = MyDirY * DistX - MyDirX * DistY; oInfo.State.CarDiffVelLong = MyDirX * DiffVelX + MyDirY * DiffVelY; oInfo.State.CarDiffVelLat = MyDirY * DiffVelX - MyDirX * DiffVelY; oInfo.State.MinDistLong = (MyCar->_dimension_x + CarLength) / 2; oInfo.State.MinDistLat = (MyCar->_dimension_y + CarWidth) / 2; double MyVelAng = atan2(MyCar->_speed_Y, MyCar->_speed_X); double MyYaw = MyCar->_yaw - MyVelAng; DOUBLE_NORM_PI_PI(MyYaw); double OppYaw = CarYaw - MyVelAng; DOUBLE_NORM_PI_PI(OppYaw); // Additional distance needed while yawing of both cars double ExtSide = (oInfo.State.MinDistLong - oInfo.State.MinDistLat) * (fabs(sin(MyYaw)) + fabs(sin(OppYaw))); oInfo.State.MinDistLat += ExtSide + SIDE_MARGIN; oInfo.State.MinDistLong += TDriver::LengthMargin; // Distance of car from start of track. double MyPos = RtGetDistFromStart((tCarElt*)MyCar); double HisPos = RtGetDistFromStart((tCarElt*)oCar); double RelPos = HisPos - MyPos; double TrackLen = oTrack->Length(); if (RelPos > TrackLen / 2) RelPos -= TrackLen; else if (RelPos < -TrackLen / 2) RelPos += TrackLen; oInfo.State.RelPos = RelPos; if (fabs(CarToMiddle) - oTrack->Width() > 1.0) // If opponent is outside of track { // we assume it is in the pitlane if ((RelPos > MinDistBack) // Opponent is near && (RelPos < 5)) // and not in front { MinDistBack = (tdble) RelPos; } double T = -RelPos/oInfo.State.TrackVelLong; // Time to start out of pit if ((T > 0) // Opponent is back or aside && (T < 200)) // and arrives within 20 sec { if (MinTimeSlot > T) MinTimeSlot = T; } } }