public void DrawHUD(ReplayBoat boat, GraphicsDevice device, XnaCameraMan cameraMan, DateTime time, float coordinateDivisor) { device.RenderState.DepthBufferEnable = false; Camera camera = cameraMan.Camera; float angle = boat.Angle; if (boat.Direction == ReplayBoat.BoatDirection.Backwards) { angle = AngleHelper.NormalizeAngle(boat.Angle + MathHelper.Pi); } camera.ConfigureBasicEffect(_hudEffect); _hudEffect.World = Matrix.Identity; _hudEffect.Begin(); foreach (EffectPass pass in _hudEffect.CurrentTechnique.Passes) { pass.Begin(); if (cameraMan.DrawPastPath || cameraMan.DrawFuturePath) { DateTime startTime = boat.SensorReadings[boat.CurrentSensorReadingIndex].datetime; DateTime endTime = boat.SensorReadings[boat.CurrentSensorReadingIndex].datetime; int startIndex = boat.CurrentSensorReadingIndex; int endIndex = boat.CurrentSensorReadingIndex; if (cameraMan.DrawPastPath) { startTime = startTime - new TimeSpan(0, 0, cameraMan.DrawPathLength); while (startIndex > 0 && boat.SensorReadings[startIndex].datetime > startTime) { startIndex--; } } if (cameraMan.DrawFuturePath) { endTime = endTime + new TimeSpan(0, 0, cameraMan.DrawPathLength); while (endIndex < boat.SensorReadings.Count && boat.SensorReadings[endIndex].datetime < endTime) { endIndex++; } } if (_boatDataRowsCurveMap[boat].ContainsKey(startIndex) && _boatDataRowsCurveMap[boat].ContainsKey(endIndex)) { int curveStart = _boatDataRowsCurveMap[boat][startIndex] * 2; int curveEnd = _boatDataRowsCurveMap[boat][endIndex] * 2; int curveLength = (curveEnd - curveStart) / 2; int curveMidPoint = _boatDataRowsCurveMap[boat][boat.CurrentSensorReadingIndex] * 2; for (int i = curveStart; i < curveEnd; i++) { float distance; if (i < boat.CurrentSensorReadingIndex) { distance = (float)Math.Abs(i - curveMidPoint) / (float)Math.Abs(curveStart - curveMidPoint); } else if (i > boat.CurrentSensorReadingIndex) { distance = (float)Math.Abs(i - curveMidPoint) / (float)Math.Abs(curveEnd - curveMidPoint); } else { distance = 1f; } float alpha = 1 - distance; Color c = new Color(new Vector4(boat.Color.R, boat.Color.G, boat.Color.B, alpha)); _boatPathCurve[boat][i].Color = c; } device.VertexDeclaration = VertexDeclarationHelper.Get(typeof(VertexPositionColor)); device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleStrip, _boatPathCurve[boat], curveStart, curveLength * 2); } } pass.End(); } _hudEffect.End(); if (boat.CurrentRacingStatus != ReplayBoat.RacingStatus.Finished && cameraMan.DrawAngleToMark) { //float angleToMark = AngleHelper.FindAngle(CurrentMarkLocation.ToWorld(), ProjectedPoint.ToWorld()); DrawInstrument(device, InstrumentDrawing.OutwardArrow, Microsoft.Xna.Framework.Graphics.Color.Orange, ProjectedPointToWorld(boat.ProjectedPoint), boat.Angle, 0.5f, 0.5f); } if (cameraMan.DrawAngleToWind) { DrawInstrument(device, InstrumentDrawing.InwardArrow, Microsoft.Xna.Framework.Graphics.Color.Green, ProjectedPointToWorld(boat.ProjectedPoint), Replay.WindAngle + MathHelper.Pi, 0.5f, 0.5f); } if (cameraMan.DrawAbsoluteAngleReference || cameraMan.DrawRelativeAngleReference) { int line = 0; for (float a = 0f; a < MathHelper.TwoPi; a = a + (MathHelper.PiOver4 / 2.0f)) { float length = 0.1f; if (line == 0) length = 0.4f; else if (line % 4 == 0) length = 0.3f; else if (line % 2 == 0) length = 0.2f; if (cameraMan.DrawRelativeAngleReference) { InstrumentDrawing id = InstrumentDrawing.Line; if (line == 0) { id = InstrumentDrawing.OutwardArrow; } DrawInstrument(device, id, Microsoft.Xna.Framework.Graphics.Color.Gray, ProjectedPointToWorld(boat.ProjectedPoint), a + boat.Angle, 1.0f - length, length); } if (cameraMan.DrawAbsoluteAngleReference) { DrawInstrument(device, InstrumentDrawing.Line, Microsoft.Xna.Framework.Graphics.Color.LightGray, ProjectedPointToWorld(boat.ProjectedPoint), a, 1.0f, length); } line++; } } device.RenderState.DepthBufferEnable = true; }
public void DrawBoat(ReplayBoat boat, GraphicsDevice device, XnaCameraMan cameraMan, DateTime time) { if (boat.ProjectedPoint != null) { Camera camera = cameraMan.Camera; float angle = boat.Angle; if (boat.Direction == ReplayBoat.BoatDirection.Backwards) { angle = AngleHelper.NormalizeAngle(boat.Angle + MathHelper.Pi); } foreach (ModelMesh mesh in _boatModel.Meshes) { foreach (BasicEffect mfx in mesh.Effects) { mfx.EnableDefaultLighting(); mfx.AmbientLightColor = DrawingToXnaColor(boat.Color).ToVector3(); mfx.World = Matrix.CreateScale(0.02f) * Matrix.CreateTranslation(new Vector3(0f, 0f, -0.25f)) * Matrix.CreateRotationZ(MathHelper.ToRadians(boat.Heel)) * Matrix.CreateRotationY(MathHelper.ToRadians(90.0f)) * Matrix.CreateRotationY(angle) * Matrix.CreateTranslation(ProjectedPointToWorld(boat.ProjectedPoint)); camera.ConfigureBasicEffect(mfx); } mesh.Draw(); } camera.ConfigureBasicEffect(_sailEffect); _sailEffect.World = Matrix.CreateScale(0.1f) * Matrix.CreateRotationY(boat.BoomAngle) * Matrix.CreateTranslation(new Vector3(0f, 0f, 0.25f)) * Matrix.CreateTranslation(new Vector3(0, 0, -0.36f)) * Matrix.CreateRotationZ(MathHelper.ToRadians(-boat.Heel)) * Matrix.CreateRotationY(MathHelper.ToRadians(270.0f) + angle) * Matrix.CreateTranslation(ProjectedPointToWorld(boat.ProjectedPoint)); _sailEffect.Begin(); foreach (EffectPass pass in _sailEffect.CurrentTechnique.Passes) { pass.Begin(); _boatMains[boat].Draw(device, boat.SailCurve, 0); pass.End(); } _sailEffect.End(); camera.ConfigureBasicEffect(_sailEffect); _sailEffect.World = Matrix.CreateScale(0.1f) /** Matrix.CreateRotationY(currentBoomAngle)*/ * Matrix.CreateTranslation(new Vector3(0f, 0f, 0.25f)) * Matrix.CreateTranslation(new Vector3(0, 0, -0.36f)) * Matrix.CreateRotationZ(MathHelper.ToRadians(-boat.Heel)) * Matrix.CreateRotationY(MathHelper.ToRadians(270.0f) + angle) * Matrix.CreateTranslation(ProjectedPointToWorld(boat.ProjectedPoint)); _sailEffect.Begin(); foreach (EffectPass pass in _sailEffect.CurrentTechnique.Passes) { pass.Begin(); _boatJibs[boat].Draw(device, boat.SailCurve, (boat.BoomAngle * 80f) * 0.02f); pass.End(); } _sailEffect.End(); } }
//private CoordinatePoint.ProjectedPoint ProjectedPointFromWorld(Vector3 v) //{ // CoordinatePoint.ProjectedPoint pp = new CoordinatePoint.ProjectedPoint(); // pp.northing = (v.X + _xOffset) * _coordinateDivisor; // pp.easting = (v.Z + _zOffset) * _coordinateDivisor; // pp.height = (v.Y * _coordinateDivisor); // return pp; //} private string ExtractBoatStatisticString(ReplayBoat b, IViewPort target, string name, DateTime time) { string speedString = name + ": "; speedString = speedString + string.Format("{0:0.##}", b.TotalStatistics.GetValue<float>(name, time, target.StatisticUnitType)); if (target.StatisticUnitType == StatisticUnitType.metric) { speedString = speedString + " " + b.TotalStatistics.GetStatisticMetricUnit(typeof(float), name); } else if (target.StatisticUnitType == StatisticUnitType.standard) { speedString = speedString + " " + b.TotalStatistics.GetStatisticStandardUnit(typeof(float), name); } return speedString; }
public void BuildBoatPathCurve(ReplayBoat boat) { SortedList<int, int> tempBoatDataRowsCurveMap = new SortedList<int, int>(); List<Vector3> tempControlPoints = new List<Vector3>(); List<float> tempDistances = new List<float>(); List<Vector3> controlPoints = new List<Vector3>(); for (int i = 0; i < boat.SensorReadings.Count; i++) { CoordinatePoint cp = new CoordinatePoint(new Coordinate(boat.SensorReadings[i].latitude), new Coordinate(boat.SensorReadings[i].longitude), 0); controlPoints.Add(ProjectedPointToWorld(cp.Project())); } List<Vector3> curvePoints = BezierHelper.CreateSmoothedLine(controlPoints, out tempBoatDataRowsCurveMap, out tempControlPoints, out tempDistances); _boatDataRowsCurveMap[boat] = tempBoatDataRowsCurveMap; _boatPathCurve[boat] = new VertexPositionColor[(curvePoints.Count * 2) - 2]; _boatPathControlPoints[boat] = tempControlPoints; _boatDataRowsDistances[boat] = tempDistances; float maxWidth = 0.2f;//meters/coord divisor float minWidth = 0.01f;//meters/coord divisor float maxSpeed = 20f;//kmh //float minSpeed = 0f;//kmh int vertexIndex = 0; for (int i = 0; i < boat.SensorReadings.Count - 2; i++) { int curveStart = _boatDataRowsCurveMap[boat][i]; int curveEnd = _boatDataRowsCurveMap[boat][i + 1]; float startDistance = _boatDataRowsDistances[boat][i]; float endDistance = _boatDataRowsDistances[boat][i + 1]; float startSpeed = (startDistance / 1000) / (float)(boat.SensorReadings[i + 1].datetime - boat.SensorReadings[i].datetime).TotalHours; float endSpeed = (endDistance / 1000) / (float)(boat.SensorReadings[i + 2].datetime - boat.SensorReadings[i + 1].datetime).TotalHours; float speedDelta = endSpeed - startSpeed; int curvePointCount = curveEnd - curveStart; for (int c = curveStart; c < curveEnd; c++) { float percentThrough = ((float)c - (float)curveStart) / (float)curvePointCount; float speed = startSpeed + (percentThrough * speedDelta); float width = minWidth + ((speed / maxSpeed) * (maxWidth - minWidth)); width = maxWidth - width; float angleToNext = -(float)Math.Atan2(curvePoints[c + 1].Z - curvePoints[c].Z, curvePoints[c + 1].X - curvePoints[c].X); float angleRight = angleToNext + MathHelper.PiOver2; float angleLeft = angleToNext - MathHelper.PiOver2; float rightX = curvePoints[c].X + (float)Math.Cos(angleRight) * (width / 2f); float rightZ = curvePoints[c].Z - (float)Math.Sin(angleRight) * (width / 2f); VertexPositionColor right = new VertexPositionColor(); right.Position = new Vector3(rightX, 0, rightZ); _boatPathCurve[boat][vertexIndex] = right; vertexIndex++; float leftX = curvePoints[c].X + (float)Math.Cos(angleLeft) * (width / 2f); float leftZ = curvePoints[c].Z - (float)Math.Sin(angleLeft) * (width / 2f); VertexPositionColor left = new VertexPositionColor(); left.Position = new Vector3(leftX, 0, leftZ); _boatPathCurve[boat][vertexIndex] = left; vertexIndex++; } } }