using System; using System.Collections.Generic; using System.Text; using SalsaModel.Scheduling; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; using System.Drawing; namespace SalsaModel { class ShowTimeLine : IScene { TimeLine _timeLine; Timing _timing; Location _loc; const int _width = 200; public ShowTimeLine(TimeLine timeLine, Timing timing, Location loc) { _timeLine = timeLine; _timing = timing; _loc = loc; } Microsoft.DirectX.Direct3D.Device _dev; BasicDrawing _drawing = new BasicDrawing(); Message3D _helloMsg; public void Setup(Microsoft.DirectX.Direct3D.Device dev) { _dev = dev; _drawing.Setup(dev); _helloMsg = new Message3D(_dev, "hello", 0.05f); } Dictionary _msgs = new Dictionary(); public Message3D Message(string msg) { Message3D rv; if (!_msgs.TryGetValue(msg, out rv)) { rv = new Message3D(_dev, msg, 0.05f); _msgs.Add(msg, rv); } return rv; } public void Draw() { Matrix oldview = _dev.Transform.View; Matrix oldProj = _dev.Transform.Projection; float angle = (float)-Math.PI / 2.0f; _dev.Transform.View = Matrix.LookAtLH(new Vector3((float)(300 * Math.Cos(angle)), 0, (float)(300 * Math.Sin(angle))), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); const int beatsBefore = 8; const int beatsAfter = 8; double midTime = _timing.GlobalBeat() + _timing.Percent(); double startTime = midTime - beatsBefore; double endTime = midTime + beatsAfter; const double barHeight = 5.0; HeightManager hgts = new HeightManager(barHeight * 1.2); foreach (EventRecord evtRec in _timeLine.EventsBetween(startTime, endTime)) { double evtStartPct = ((evtRec.Start - midTime) / (endTime - startTime)); double evtStopPct = ((evtRec.Stop - midTime - evtRec.Duration * 0.1) / (endTime - startTime)); double height = hgts.Add(evtStartPct, evtStopPct); FlatLine(_loc.Plus(_width * evtStartPct, height, 0),_loc.Plus(_width * evtStopPct, height, 0), barHeight/2.0, Color.BlanchedAlmond); Message(evtRec.Event.DescriptiveCode).DrawStartingAt(_dev, _loc.Plus(_width * evtStartPct, height - barHeight * 0.2, -1), barHeight, _drawing.Material(Color.Black)); } for (int beat = -beatsBefore; beat < beatsAfter; ++beat) { int thisBeat = _timing.GlobalBeat() + beat; int beatNum = ((thisBeat - 1) % 8) + 1; double pct = ((thisBeat - midTime) / (endTime - startTime)); Message(beatNum.ToString()).DrawStartingAt(_dev, _loc.Plus(_width * pct, - barHeight * 2, -1), barHeight, _drawing.Material(Color.BlanchedAlmond)); } FlatTriangle(_loc.Plus(0, -10.0, 0), _loc.Plus(0, 15.0, 0), 1.0, Color.Red); _dev.Transform.View = oldview; _dev.Transform.Projection = oldProj; } class HeightManager { class Extent { public Extent(double start, double stop, double height) { Start = start; Stop = stop; Height = height; } public readonly double Start; public readonly double Stop; public readonly double Height; public bool Overlaps(double start, double stop) { return (start < this.Stop && stop > this.Start); } } public HeightManager(double gap) { _gap = gap; } List _extents = new List(); double _gap; public double Add(double start, double stop) { double height = 0.0; foreach (Extent ext in _extents) { if (ext.Overlaps(start, stop)) { height = Math.Max(height, ext.Height + _gap); } } _extents.Add(new Extent(start, stop, height)); return height; } } public void FlatLine(Location a, Location b, double height, Color color) { CustomVertex.PositionOnly[] vertices = new CustomVertex.PositionOnly[4]; Location off = b.Minus(a); Location radius = off.CrossWithZ().Normalised().Scale(height); int v = 0; double raise = 0.0; vertices[v++] = new CustomVertex.PositionOnly(BasicDrawing.Vec3(a.Plus(radius).Plus(0, 0, raise))); vertices[v++] = new CustomVertex.PositionOnly(BasicDrawing.Vec3(a.Minus(radius).Plus(0, 0, raise))); vertices[v++] = new CustomVertex.PositionOnly(BasicDrawing.Vec3(b.Plus(radius).Plus(0, 0, raise))); vertices[v++] = new CustomVertex.PositionOnly(BasicDrawing.Vec3(b.Minus(radius).Plus(0, 0, raise))); _dev.VertexFormat = CustomVertex.PositionOnly.Format; _dev.Material = _drawing.Material(color); _dev.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, vertices); } public void FlatTriangle(Location a, Location b, double height, Color color) { CustomVertex.PositionOnly[] vertices = new CustomVertex.PositionOnly[4]; Location off = b.Minus(a); Location radius = off.CrossWithZ().Normalised().Scale(height); int v = 0; double raise = 0.0; vertices[v++] = new CustomVertex.PositionOnly(BasicDrawing.Vec3(a.Plus(radius).Plus(0, 0, raise))); vertices[v++] = new CustomVertex.PositionOnly(BasicDrawing.Vec3(a.Minus(radius).Plus(0, 0, raise))); vertices[v++] = new CustomVertex.PositionOnly(BasicDrawing.Vec3(b.Plus(0, 0, raise))); _dev.VertexFormat = CustomVertex.PositionOnly.Format; _dev.Material = _drawing.Material(color); _dev.DrawUserPrimitives(PrimitiveType.TriangleStrip, 1, vertices); } } }