public override void Redraw(float currentTime, float elapsedTime)
		{
			// update camera, tracking test vehicle
			Demo.UpdateCamera(elapsedTime, _vehicle);

			// draw "ground plane"  (make it 4x map size)
			const float S = MapDriver.WORLD_SIZE * 2;
			const float U = -0.2f;
			Drawing.DrawQuadrangle(new Vector3(+S, U, +S),
							new Vector3(+S, U, -S),
							new Vector3(-S, U, -S),
							new Vector3(-S, U, +S),
							new Color((byte)(255.0f * 0.8f), (byte)(255.0f * 0.7f), (byte)(255.0f * 0.5f))); // "sand"

			// draw map and path
			if (MapDriver.DemoSelect == 2) _vehicle.DrawPath();
			_vehicle.DrawMap();

			// draw test vehicle
			_vehicle.Draw();

			// QQQ mark origin to help spot artifacts
			const float TICK = 2;
			Drawing.DrawLine(new Vector3(TICK, 0, 0), new Vector3(-TICK, 0, 0), Color.Green);
			Drawing.DrawLine(new Vector3(0, 0, TICK), new Vector3(0, 0, -TICK), Color.Green);

			// compute conversion factor miles-per-hour to meters-per-second
			const float METERS_PER_MILE = 1609.344f;
			const float SECONDS_PER_HOUR = 3600;
// ReSharper disable InconsistentNaming
			const float MPSperMPH = METERS_PER_MILE / SECONDS_PER_HOUR;
// ReSharper restore InconsistentNaming

			// display status in the upper left corner of the window
			StringBuilder status = new StringBuilder();
			status.AppendFormat("Speed: {0} mps ({1} mph), average: {2:0.0} mps\n\n",
				   (int)_vehicle.Speed,
				   (int)(_vehicle.Speed / MPSperMPH),
				   _vehicle.TotalDistance / _vehicle.TotalTime);
			status.AppendFormat("collisions avoided for {0} seconds",
				   (int)(Demo.Clock.TotalSimulationTime - _vehicle.TimeOfLastCollision));
			if (_vehicle.CountOfCollisionFreeTimes > 0)
			{
				status.AppendFormat("\nmean time between collisions: {0} ({1}/{2})",
					   (int)(_vehicle.SumOfCollisionFreeTimes / _vehicle.CountOfCollisionFreeTimes),
					   (int)_vehicle.SumOfCollisionFreeTimes,
					   _vehicle.CountOfCollisionFreeTimes);
			}

			status.AppendFormat("\n\nStuck count: {0} ({1} cycles, {2} off path)",
				_vehicle.StuckCount,
				_vehicle.StuckCycleCount,
				_vehicle.StuckOffPathCount);
			status.Append("\n\n[F1] ");
			if (1 == MapDriver.DemoSelect) status.Append("wander, ");
			if (2 == MapDriver.DemoSelect) status.Append("follow path, ");
			status.Append("avoid obstacle");

			if (2 == MapDriver.DemoSelect)
			{
				status.Append("\n[F2] path following direction: ");
			    status.Append(_vehicle.PathFollowDirection > 0 ? "+1" : "-1");
			    status.Append("\n[F3] path fence: ");
			    status.Append(_usePathFences ? "on" : "off");
			}

			status.Append("\n[F4] rocks: ");
		    status.Append(_useRandomRocks ? "on" : "off");
		    status.Append("\n[F5] prediction: ");
		    status.Append(_vehicle.CurvedSteering ? "curved" : "linear");
		    if (2 == MapDriver.DemoSelect)
			{
				status.AppendFormat("\n\nLap {0} (completed: {1}%)",
					_vehicle.LapsStarted,
					   ((_vehicle.LapsStarted < 2) ? 0 :
						   (int)(100 * ((float)_vehicle.LapsFinished /
										 (_vehicle.LapsStarted - 1))))
					   );

				status.AppendFormat("\nHints given: {0}, taken: {1}",
					_vehicle.HintGivenCount,
					_vehicle.HintTakenCount);
			}
			status.Append("\n");
			qqqRange("WR ", MapDriver.SavedNearestWR, status);
			qqqRange("R  ", MapDriver.SavedNearestR, status);
			qqqRange("L  ", MapDriver.SavedNearestL, status);
			qqqRange("WL ", MapDriver.SavedNearestWL, status);
			Vector3 screenLocation = new Vector3(15, 50, 0);
			Vector3 color = new Vector3(0.15f, 0.15f, 0.5f);
			Drawing.Draw2dTextAt2dLocation(status.ToString(), screenLocation, new Color(color.ToXna()));

			{
				float v = Drawing.GetWindowHeight() - 5;
				const float M = 10;
				float w = Drawing.GetWindowWidth();
				float f = w - (2 * M);

				// limit tick mark
				float l = _vehicle.AnnoteMaxRelSpeed;
				Drawing.Draw2dLine(new Vector3(M + (f * l), v - 3, 0), new Vector3(M + (f * l), v + 3, 0), Color.Black);
				// two "inverse speedometers" showing limits due to curvature and
				// path alignment
				if (Math.Abs(l) > float.Epsilon)
				{
					float c = _vehicle.AnnoteMaxRelSpeedCurve;
					float p = _vehicle.AnnoteMaxRelSpeedPath;
					Drawing.Draw2dLine(new Vector3(M + (f * c), v + 1, 0), new Vector3(w - M, v + 1, 0), Color.Red);
					Drawing.Draw2dLine(new Vector3(M + (f * p), v - 2, 0), new Vector3(w - M, v - 1, 0), Color.Green);
				}
				// speedometer: horizontal line with length proportional to speed
				Drawing.Draw2dLine(new Vector3(M, v, 0), new Vector3(M + (f * S), v, 0), Color.White);
				// min and max tick marks
				Drawing.Draw2dLine(new Vector3(M, v, 0), new Vector3(M, v - 2, 0), Color.White);
				Drawing.Draw2dLine(new Vector3(w - M, v, 0), new Vector3(w - M, v - 2, 0), Color.White);
			}
		}
Exemple #2
0
        public override void Redraw(float currentTime, float elapsedTime)
        {
            // update camera, tracking test vehicle
            Demo.UpdateCamera(elapsedTime, _vehicle);

            // draw "ground plane"  (make it 4x map size)
            const float S = MapDriver.WORLD_SIZE * 2;
            const float U = -0.2f;

            Drawing.DrawQuadrangle(new Vector3(+S, U, +S),
                                   new Vector3(+S, U, -S),
                                   new Vector3(-S, U, -S),
                                   new Vector3(-S, U, +S),
                                   new Color((byte)(255.0f * 0.8f), (byte)(255.0f * 0.7f), (byte)(255.0f * 0.5f)));                      // "sand"

            // draw map and path
            if (MapDriver.DemoSelect == 2)
            {
                _vehicle.DrawPath();
            }
            _vehicle.DrawMap();

            // draw test vehicle
            _vehicle.Draw();

            // QQQ mark origin to help spot artifacts
            const float TICK = 2;

            Drawing.DrawLine(new Vector3(TICK, 0, 0), new Vector3(-TICK, 0, 0), Color.Green);
            Drawing.DrawLine(new Vector3(0, 0, TICK), new Vector3(0, 0, -TICK), Color.Green);

            // compute conversion factor miles-per-hour to meters-per-second
            const float METERS_PER_MILE  = 1609.344f;
            const float SECONDS_PER_HOUR = 3600;
// ReSharper disable InconsistentNaming
            const float MPSperMPH = METERS_PER_MILE / SECONDS_PER_HOUR;
// ReSharper restore InconsistentNaming

            // display status in the upper left corner of the window
            StringBuilder status = new StringBuilder();

            status.AppendFormat("Speed: {0} mps ({1} mph), average: {2:0.0} mps\n\n",
                                (int)_vehicle.Speed,
                                (int)(_vehicle.Speed / MPSperMPH),
                                _vehicle.TotalDistance / _vehicle.TotalTime);
            status.AppendFormat("collisions avoided for {0} seconds",
                                (int)(Demo.Clock.TotalSimulationTime - _vehicle.TimeOfLastCollision));
            if (_vehicle.CountOfCollisionFreeTimes > 0)
            {
                status.AppendFormat("\nmean time between collisions: {0} ({1}/{2})",
                                    (int)(_vehicle.SumOfCollisionFreeTimes / _vehicle.CountOfCollisionFreeTimes),
                                    (int)_vehicle.SumOfCollisionFreeTimes,
                                    _vehicle.CountOfCollisionFreeTimes);
            }

            status.AppendFormat("\n\nStuck count: {0} ({1} cycles, {2} off path)",
                                _vehicle.StuckCount,
                                _vehicle.StuckCycleCount,
                                _vehicle.StuckOffPathCount);
            status.Append("\n\n[F1] ");
            if (1 == MapDriver.DemoSelect)
            {
                status.Append("wander, ");
            }
            if (2 == MapDriver.DemoSelect)
            {
                status.Append("follow path, ");
            }
            status.Append("avoid obstacle");

            if (2 == MapDriver.DemoSelect)
            {
                status.Append("\n[F2] path following direction: ");
                status.Append(_vehicle.PathFollowDirection > 0 ? "+1" : "-1");
                status.Append("\n[F3] path fence: ");
                status.Append(_usePathFences ? "on" : "off");
            }

            status.Append("\n[F4] rocks: ");
            status.Append(_useRandomRocks ? "on" : "off");
            status.Append("\n[F5] prediction: ");
            status.Append(_vehicle.CurvedSteering ? "curved" : "linear");
            if (2 == MapDriver.DemoSelect)
            {
                status.AppendFormat("\n\nLap {0} (completed: {1}%)",
                                    _vehicle.LapsStarted,
                                    ((_vehicle.LapsStarted < 2) ? 0 :
                                     (int)(100 * ((float)_vehicle.LapsFinished /
                                                  (_vehicle.LapsStarted - 1))))
                                    );

                status.AppendFormat("\nHints given: {0}, taken: {1}",
                                    _vehicle.HintGivenCount,
                                    _vehicle.HintTakenCount);
            }
            status.Append("\n");
            qqqRange("WR ", MapDriver.SavedNearestWR, status);
            qqqRange("R  ", MapDriver.SavedNearestR, status);
            qqqRange("L  ", MapDriver.SavedNearestL, status);
            qqqRange("WL ", MapDriver.SavedNearestWL, status);
            Vector3 screenLocation = new Vector3(15, 50, 0);
            Vector3 color          = new Vector3(0.15f, 0.15f, 0.5f);

            Drawing.Draw2dTextAt2dLocation(status.ToString(), screenLocation, new Color(color.ToXna()));

            {
                float       v = Drawing.GetWindowHeight() - 5;
                const float M = 10;
                float       w = Drawing.GetWindowWidth();
                float       f = w - (2 * M);

                // limit tick mark
                float l = _vehicle.AnnoteMaxRelSpeed;
                Drawing.Draw2dLine(new Vector3(M + (f * l), v - 3, 0), new Vector3(M + (f * l), v + 3, 0), Color.Black);
                // two "inverse speedometers" showing limits due to curvature and
                // path alignment
                if (Math.Abs(l) > float.Epsilon)
                {
                    float c = _vehicle.AnnoteMaxRelSpeedCurve;
                    float p = _vehicle.AnnoteMaxRelSpeedPath;
                    Drawing.Draw2dLine(new Vector3(M + (f * c), v + 1, 0), new Vector3(w - M, v + 1, 0), Color.Red);
                    Drawing.Draw2dLine(new Vector3(M + (f * p), v - 2, 0), new Vector3(w - M, v - 1, 0), Color.Green);
                }
                // speedometer: horizontal line with length proportional to speed
                Drawing.Draw2dLine(new Vector3(M, v, 0), new Vector3(M + (f * S), v, 0), Color.White);
                // min and max tick marks
                Drawing.Draw2dLine(new Vector3(M, v, 0), new Vector3(M, v - 2, 0), Color.White);
                Drawing.Draw2dLine(new Vector3(w - M, v, 0), new Vector3(w - M, v - 2, 0), Color.White);
            }
        }
Exemple #3
0
		// draw the GCRoute as a series of circles and "wide lines"
		// (QQQ this should probably be a method of Path (or a
		// closely-related utility function) in which case should pass
		// color in, certainly shouldn't be recomputing it each draw)
		public void DrawPath()
		{
			Vector3 pathColor = new Vector3(0, 0.5f, 0.5f);
			Vector3 sandColor = new Vector3(0.8f, 0.7f, 0.5f);
			Vector3 vColor = Vector3.Lerp(sandColor, pathColor, 0.1f);
			Color color = new Color(vColor.ToXna());

			Vector3 down = new Vector3(0, -0.1f, 0);
			for (int i = 0; i < Path.PointCount; i++)
			{
				Vector3 endPoint0 = Path.Points[i] + down;
				if (i > 0)
				{
					Vector3 endPoint1 = Path.Points[i - 1] + down;

					float legWidth = Path.Radii[i];

					Drawing.DrawXZWideLine(endPoint0, endPoint1, color, legWidth * 2);
					Drawing.DrawLine(Path.Points[i], Path.Points[i - 1], new Color(pathColor.ToXna()));
					Drawing.DrawXZDisk(legWidth, endPoint0, color, 24);
					Drawing.DrawXZDisk(legWidth, endPoint1, color, 24);
				}
			}
		}