BOOL CConfig::GetCaptureDir( tstring& strCaptureDir ) { strCaptureDir = this->ReadConfig( CONFIG_ENTRY_CAPTURE_DIR, _T("") ); if ( strCaptureDir.empty() ) { // 配置文件中没有记录,返回默认配置。 // 如果手机有存储卡,优先返回存储卡位置。 BOOL bHasCard = ::HasStorageCard(); if( bHasCard ) { strCaptureDir = CONFIG_DEFAULT_CAPTURE_DIR_CARD; } else { strCaptureDir = CONFIG_DEFAULT_CAPTURE_DIR_RAM; } } // 标准化文件夹。 NormalizeDir( strCaptureDir ); // Log() << _T( "CConfig::GetCaptureDir [" ) << strCaptureDir << _T( "]" )<< endl; return ( !strCaptureDir.empty() ); }
//==========================================================================* // Angle //--------------------------------------------------------------------------* double TTrackDescription::ForwardAngle(double TrackPos) const { int Index = IndexFromPos(TrackPos); const tTrackSeg* Seg = oSections[Index].Seg; double X; TVec3d CenterPoint; TVec3d Normale; NormalizeDir(Seg, TrackPos - Seg->lgfromstart, X, CenterPoint, Normale); return TUtils::VecAngXY(Normale) + PI / 2; }
//==========================================================================* // To right //--------------------------------------------------------------------------* TVec2d TTrackDescription::Normale(double TrackPos) const { //int LastPos = 0; int Index = IndexFromPos(TrackPos); const tTrackSeg* Seg = oSections[Index].Seg; double Tmp; TVec3d CenterPoint; TVec3d Normale; NormalizeDir(Seg, TrackPos - Seg->lgfromstart, Tmp, CenterPoint, Normale); return Normale.GetXY(); }
//==========================================================================* // Build new track description //--------------------------------------------------------------------------* void TTrackDescription::InitTrack (tTrack* Track, TCarParam& CarParam, float SmoothSide, PitSideMod* PitSideMod) { if (oTrack != Track) // if used { // free old ones if (oSections != NULL) delete [] oSections; oSections = NULL; oCount = 0; } oTrack = Track; // Save pointer to TORCS data if (PitSideMod) // If defined oPitSideMod = *PitSideMod; // Set Pit side mode Execute(); // Make description tTrackSeg* LastSeg = oTrack->seg; // Save last segment int LastSegType = TR_STR; // Assume straight tTrackSeg* Seg = LastSeg; // Start at last segment // Find usable additional width at sides of the track ... bool ForcePitlane; int N = 0; // Count sections since last curve double WMax = 1.5; {for (int I = 0; I < oCount; I++) { ForcePitlane = false; oSections[I].PitWidthToLeft = oSections[I].WidthToLeft; oSections[I].PitWidthToRight = oSections[I].WidthToRight; LastSeg = Seg; // Save last segment if (LastSeg->type != TR_STR) // if it was a curve { // save last type and LastSegType = LastSeg->type; // reset counter N = 0; } else // increase counter N++; // on straights if (N > 10) // After 10 sections LastSegType = LastSeg->type; // reset Seg = oSections[I].Seg; // Get torcs segment // if (strncmp(Seg->name,"S10",3) == 0) // if (strncmp(Seg->name,"curve 39",8) == 0) // if (strncmp(Seg->name,"end line",8) == 0) // GfOut("%s\n",Seg->name); // if (strncmp(Seg->name,"straight 48",11) == 0) // GfOut("%s\n",Seg->name); double DistFromStart = // Distance from start oSections[I].DistFromStart; // of section double T = (DistFromStart - Seg->lgfromstart)// Part of section / Seg->length; bool InPit = (((oPitEntry < oPitExit) // Check if along pits && (oPitEntry <= I) && (I <= oPitExit)) || ((oPitEntry > oPitExit) && ((I <= oPitExit) || (I >= oPitEntry)))); bool InPitEntryExit = (((oPitEntry < oPitExit) // Check if along pits && (oPitEntryNext <= I) && (I <= oPitExitPrev)) || ((oPitEntry > oPitExit) && ((I <= oPitExitPrev) || (I >= oPitEntryNext)))); // Selections ... double MIN_MU = // min usable mu Seg->surface->kFriction * CarParam.oScaleMinMu; const double MAX_ROUGH = // max usable rough MAX(0.030, Seg->surface->kRoughness * 1.2); const double MAX_RESIST = // max usable resistance MAX(0.06, Seg->surface->kRollRes * 1.3); // Brondehach pit exit! const double SLOPE = Seg->Kzw; // Slope of segment for (int S = 0; S < 2; S++) // Look at both sides { tTrackSeg* PSide = Seg->side[S]; // Side-segment if (PSide == NULL) // If NULL no side continue; // go to next segment double ExtraW = 0; // Initialize add. width double ExtraWpit = 0; // Initialize add. width bool Done = false; // Reset flag bool PitOnly = false; // Reset flag while(PSide) // Loop all side-segments { double Wpit = 0.0; // Initialize double WCurb = 0.0; // additional with double W = PSide->startWidth + T * // Estimate width of section (PSide->endWidth - PSide->startWidth); // at current position float slope = PSide->height/PSide->width;// Slope of border bool outer = ((S == TR_SIDE_LFT) // Is it the outer side? && (Seg->type == TR_RGT)) || ((S == TR_SIDE_RGT) && (Seg->type == TR_LFT)); bool pitlane = (((S == oPitSideMod.side) // If side of pits && (I >= oPitSideMod.start) // and between start && (I <= oPitSideMod.end))); // and end of pitlane //outer = false; tTrackSeg* NextSide = PSide->side[S]; if (pitlane) // if side along pitlane W = 0.0; // Keep out! // __ if (fabs(SLOPE) > 0.1 + fabs(slope)) // __/ { // Keep out! if (InPit && (oPitSide == S)) Wpit = W; W = 0.0; } if (InPitEntryExit && (oPitSide == S)) { bool Force = false; tTrackSeg* PNext = Seg->next; // Next segment tTrackSeg* PNextSide = NULL; if (PNext != NULL) { PNextSide = PNext->side[S]; // Next side segment if (PNextSide != NULL) { if (PNextSide->style == TR_WALL) Force = true; } } if ((PSide->style == TR_WALL) || (Force)) ForcePitlane = true; } if ((PSide->style == TR_CURB) // On curbs with height && (slope > 0.01)) // and great slope { Done = true; // Last possible to use WCurb = 0.8 * W; // Use 80% WCurb = MIN(WCurb,WMax); // Keep a wheel on track if (outer // If outer side and friction lower && (PSide->surface->kFriction < Seg->surface->kFriction)) WCurb = MIN(WCurb, 0.15); // use 15 cm only // Don't go too far up raised curbs if (slope > 0.15) // If more WCurb = 0; // keep off else // less slope WCurb = MIN(WCurb,3.0/slope); // more width used } else if (PSide->style == TR_CURB) // On curbs without height { WCurb = 0.8 * W; // Use 80% if (pitlane) // if side along pitlane { WCurb = 0.15; Done = true; } else if (outer && (PSide->surface->kFriction < Seg->surface->kFriction)) { WCurb = MIN(WCurb,WMax); // Keep two wheels on track Done = true; } else { W = 0; } } else if (PSide->style == TR_PLAN) // On plan { WCurb = 0.8 * W; // Use 80% if ((InPit && (oPitSide == S)) // Exclude pits || (PSide->raceInfo & (TR_SPEEDLIMIT | TR_PITLANE))) { Wpit = MAX(Wpit,W); // Save it for pitlane WCurb = 0; // Use 80% Done = true; } else if (pitlane) { Wpit = MAX(Wpit,W); // Save it for pitlane if (W > 0.15) // Only 15 cm { WCurb = 0.15; Done = true; } } // Selections ... if (outer && ((PSide->surface->kFriction < MIN_MU) || (PSide->surface->kRoughness > MIN(MAX_ROUGH,0.005)) || (PSide->surface->kRollRes > MAX_RESIST) || (fabs(PSide->Kzw - SLOPE) > 0.005))) { WCurb = 0; Done = true; } else if ((PSide->surface->kFriction < MIN_MU) || (PSide->surface->kRoughness > MIN(MAX_ROUGH,0.005)) || (PSide->surface->kRollRes > MAX_RESIST) || (fabs(PSide->Kzw - SLOPE) > 0.005)) { WCurb = 0.15; Done = true; } else if (outer && ((PSide->surface->kFriction < Seg->surface->kFriction) || (PSide->surface->kRoughness > MIN(MAX_ROUGH,0.005)) || (PSide->surface->kRollRes > MAX_RESIST) || (fabs(PSide->Kzw - SLOPE) > 0.005))) { WCurb = 0; Done = true; } else if (outer && (PSide->surface->kFriction < Seg->surface->kFriction)) { WCurb = MIN(WCurb,WMax); Done = true; } else if (PSide->surface->kFriction < MIN_MU) { WCurb = MIN(WCurb,WMax); Done = true; } else if (NextSide == NULL) { WCurb -= 1.0; Done = true; } } else if (NextSide == NULL) { WCurb -= 1.0; Done = true; } else { // Wall of some sort WCurb = (PSide->style >= TR_WALL) ? -1.0 : 0; Done = true; } ExtraWpit += Wpit; if ((!PitOnly) || (WCurb < 0)) { if (Done) ExtraW += WCurb; else ExtraW += W; if (Done) PitOnly = true; } PSide = NextSide; } if (S == TR_SIDE_LFT) { oSections[I].PitWidthToLeft = oSections[I].WidthToLeft + MAX(ExtraW,ExtraWpit); // if ((NEW_VERSION == 307) && (!TDriver::Qualifying)) // oSections[I].WidthToLeft += MIN(1.0,ExtraW); // else oSections[I].WidthToLeft += ExtraW; } else { oSections[I].PitWidthToRight = oSections[I].WidthToRight + MAX(ExtraW,ExtraWpit); oSections[I].WidthToRight += ExtraW; } } if (ForcePitlane) { if (oPitSide == TR_SIDE_LFT) { oSections[I].PitWidthToRight = -(oSections[I].WidthToLeft + 3.0); } else { oSections[I].PitWidthToLeft = -(oSections[I].WidthToRight + 3.0); } } NormalizeDir(Seg, DistFromStart - Seg->lgfromstart, oSections[I].T, oSections[I].Center, oSections[I].ToRight); }} SmoothSides(SmoothSide); }