using System; using System.Collections.Generic; using System.Text; using Microsoft.DirectX.Direct3D; using System.Drawing; using Microsoft.DirectX; namespace SalsaModel { public class SalsaScene : SalsaModel.IScene { public List Models = new List(); BasicDrawing Helper = new BasicDrawing(); Material FloorMaterial; Texture FloorTexture; Device DXDevice; static readonly Color BoyColor = Color.CornflowerBlue; static readonly Color GirlColor = Color.Pink; public bool DrawFootprints = false; struct Footprint { public Location Foot; public Location Toe; public Color LineColor; public Color BallColor; public Footprint(Location foot, Location toe, Color lineColor, Color ballColor) { Foot = foot.SetZ0(); Toe = toe.SetZ0(); LineColor = lineColor; BallColor = ballColor; } public Footprint(PositionModel.Leg leg, Color lineColor, Color ballColor) : this(leg.Foot, leg.Toe, lineColor, ballColor) { } public override bool Equals(object obj) { if (obj is Footprint) { Footprint rhs = (Footprint)obj; return (rhs.Toe == Toe && rhs.Foot == Foot); } else { return false; } } public override int GetHashCode() { return Foot.GetHashCode() ^ Toe.GetHashCode(); } } List _feet = new List(); const int GhostFootCount = 32; private void MaybeAddFootprint(Footprint newFoot) { for (int i = Math.Max(_feet.Count - 4, 0); i < _feet.Count; ++i) { Footprint foot = _feet[i]; if (foot.Equals(newFoot)) { return; } } _feet.Add(newFoot); } public void Setup(Device dev) { DXDevice = dev; Helper.Setup(dev); string path = System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location))) + "\\wooden_floor_01.jpg"; FloorTexture = TextureLoader.FromFile(DXDevice, path); FloorMaterial = new Material(); FloorMaterial.Ambient = Color.LightGray; FloorMaterial.Diffuse = Color.LightGray; } public void Draw() { DrawFloor(); foreach (PositionModel model in Models) { Color lineColor = model.IsGirl ? GirlColor : BoyColor; DrawModel(model, lineColor); } if (DrawFootprints) { foreach (Footprint foot in _feet) { DrawFootprint(foot); } } foreach (PositionModel model in Models) { Color lineColor = model.IsGirl ? GirlColor : BoyColor; MaybeAddFootprint(new Footprint(model.LLeg, lineColor, Color.Red)); MaybeAddFootprint(new Footprint(model.RLeg, lineColor, Color.Green)); } if (_feet.Count > GhostFootCount) { _feet.RemoveRange(0, _feet.Count - GhostFootCount); } } private void DrawFootprint(Footprint foot) { Helper.FlatLine(foot.Foot, foot.Toe, foot.LineColor); Helper.FlatBall(foot.Foot, foot.BallColor); Helper.FlatBall(foot.Toe, foot.BallColor); } private void DrawFloor() { CustomVertex.PositionTextured[] vertices = new CustomVertex.PositionTextured[4]; float floorSize = 500f; float texScale = 50f; vertices[0] = new CustomVertex.PositionTextured(-floorSize, floorSize, 0f, 0, floorSize / texScale); vertices[1] = new CustomVertex.PositionTextured(-floorSize, -floorSize, 0f, 0, 0); vertices[2] = new CustomVertex.PositionTextured(floorSize, floorSize, 0f, floorSize / texScale, floorSize / texScale); vertices[3] = new CustomVertex.PositionTextured(floorSize, -floorSize, 0f, floorSize / texScale, 0); DXDevice.VertexFormat = CustomVertex.PositionTextured.Format; DXDevice.Material = FloorMaterial; DXDevice.SetTexture(0, FloorTexture); DXDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, vertices); DXDevice.SetTexture(0, null); } private void DrawModel(PositionModel model, Color color) { DrawLeg(model.RLeg, color); DrawLeg(model.LLeg, color); Helper.Line(model.RArm.Shoulder, model.RArm.Elbow, color); Helper.Line(model.RArm.Elbow, model.RArm.Wrist, color); Helper.Line(model.LArm.Shoulder, model.LArm.Elbow, color); Helper.Line(model.LArm.Elbow, model.LArm.Wrist, color); Helper.Line(model.RLeg.Hip, model.LLeg.Hip, color); Helper.Line(model.RArm.Shoulder, model.LArm.Shoulder, color); if (model.IsGirl) { Helper.Line(model.RLeg.Hip, model.LArm.Shoulder, color); Helper.Line(model.LLeg.Hip, model.RArm.Shoulder, color); } else { Helper.Line(model.RLeg.Hip, model.RArm.Shoulder, color); Helper.Line(model.LLeg.Hip, model.LArm.Shoulder, color); } { Location betweenFeet = model.HipMidPoint.SetZ0(); Helper.Line(betweenFeet, betweenFeet.Plus(model.WallForwardsUnit.Scale(30)), Color.BurlyWood); } Helper.Ball(model.RLeg.Toe, Color.Green); Helper.Ball(model.RLeg.Foot, Color.Green); Helper.Ball(model.RLeg.Knee, Color.Green); Helper.Ball(model.RLeg.Hip, Color.Green); Helper.Ball(model.RArm.Shoulder, Color.Green); Helper.Ball(model.RArm.Elbow, Color.Green); Helper.Ball(model.RArm.Wrist, Color.Green); Helper.Ball(model.LLeg.Toe, Color.Red); Helper.Ball(model.LLeg.Foot, Color.Red); Helper.Ball(model.LLeg.Knee, Color.Red); Helper.Ball(model.LLeg.Hip, Color.Red); Helper.Ball(model.LArm.Shoulder, Color.Red); Helper.Ball(model.LArm.Elbow, Color.Red); Helper.Ball(model.LArm.Wrist, Color.Red); Helper.Line(model.Neck, model.Head, color); { //Point center = Map(model.Neck.HalfWayTo(model.Head)); double bigsize = model.Head.Z - model.Neck.Z; double size = bigsize * 0.67; using (Mesh head = Mesh.Sphere(DXDevice, (float)size / 2, 12, 12)) { Helper.SetOriginTo(model.Neck.HalfWayTo(model.Head).Plus(0, 0, (bigsize - size) / 2)); DXDevice.Material = Helper.Material(color); head.DrawSubset(0); Helper.SetOrigin(); } //center.Offset(-size / 2, -bigsize / 2); //g.DrawEllipse(p, new Rectangle(center, new Size(size, size))); } } private void DrawLeg(PositionModel.Leg leg, Color color) { Helper.Line(leg.Foot, leg.Knee, color); Helper.Line(leg.Knee, leg.Hip, color); //Helper.Line(leg.Toe, leg.Foot); // real feet bend at the ball of the foot Location ball = leg.Toe.Minus(leg.Foot).Scale(0.7).Plus(leg.Foot).SetZ(leg.Toe.Z); Helper.Line(leg.Toe, ball, color); Helper.Line(ball, leg.Foot, color); } } }