using System; using System.Collections.Generic; using System.Text; using Microsoft.DirectX.Direct3D; using Microsoft.DirectX; using System.Drawing; namespace SalsaModel { public class BasicDrawing { protected Device DXDevice; public Mesh BallMesh; public Microsoft.DirectX.Direct3D.Font Font; public const double LineWidth = 2.0; public const double BallRadius = 4.0; public Dictionary _materials = new Dictionary(); public Material Material(Color color) { Material ret; if (!_materials.TryGetValue(color, out ret)) { ret = new Material(); ret.Ambient = color; ret.Diffuse = color; ret.Specular = Color.White; _materials.Add(color, ret); } return ret; } public void Setup(Device dev) { DXDevice = dev; float radius = (float)BallRadius; BallMesh = Mesh.Sphere(DXDevice, radius, 4, 4); Font = new Microsoft.DirectX.Direct3D.Font(DXDevice, new System.Drawing.Font(FontFamily.GenericSansSerif, 12)); } public void Line(Location a, Location b, Color color) { float radius = (float)LineWidth; using (Mesh cylinder = Mesh.Cylinder(DXDevice, radius, radius, (float)a.DistanceTo(b), 8, 1)) { SetOriginAndZOrientationTo(a.HalfWayTo(b), b.Minus(a)); DXDevice.Material = Material(color); cylinder.DrawSubset(0); } } public void FlatLine(Location a, Location b, Color color) { CustomVertex.PositionOnly[] vertices = new CustomVertex.PositionOnly[4]; Location off = b.Minus(a); Location radius = off.CrossWithZ().Normalised().Scale(LineWidth); int v = 0; double raise = 0.0; vertices[v++] = new CustomVertex.PositionOnly(Vec3(a.Plus(radius).Plus(0, 0, raise))); vertices[v++] = new CustomVertex.PositionOnly(Vec3(b.Plus(radius).Plus(0, 0, raise))); vertices[v++] = new CustomVertex.PositionOnly(Vec3(a.Minus(radius).Plus(0, 0, raise))); vertices[v++] = new CustomVertex.PositionOnly(Vec3(b.Minus(radius).Plus(0, 0, raise))); //vertices[0] = new CustomVertex.PositionOnly(-floorSize, floorSize, 1f); //vertices[1] = new CustomVertex.PositionOnly(-floorSize, -floorSize, 1f); //vertices[2] = new CustomVertex.PositionOnly(floorSize, floorSize, 1f); //vertices[3] = new CustomVertex.PositionOnly(floorSize, -floorSize, 1f); DXDevice.VertexFormat = CustomVertex.PositionOnly.Format; DXDevice.Material = Material(color); DXDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, vertices); } public void FlatBall(Location a, Color color) { CustomVertex.PositionOnly[] vertices = new CustomVertex.PositionOnly[4]; int v = 0; double raise = 0.01; double radius = BallRadius; vertices[v++] = new CustomVertex.PositionOnly(Vec3(a.Plus(-radius, radius, raise))); vertices[v++] = new CustomVertex.PositionOnly(Vec3(a.Plus(-radius, -radius, raise))); vertices[v++] = new CustomVertex.PositionOnly(Vec3(a.Plus(radius, radius, raise))); vertices[v++] = new CustomVertex.PositionOnly(Vec3(a.Plus(radius, -radius, raise))); //vertices[0] = new CustomVertex.PositionOnly(-floorSize, floorSize, 1f); //vertices[1] = new CustomVertex.PositionOnly(-floorSize, -floorSize, 1f); //vertices[2] = new CustomVertex.PositionOnly(floorSize, floorSize, 1f); //vertices[3] = new CustomVertex.PositionOnly(floorSize, -floorSize, 1f); DXDevice.VertexFormat = CustomVertex.PositionOnly.Format; DXDevice.Material = Material(color); DXDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, vertices); } public void Ball(Location a, Color color) { DXDevice.Material = Material(color); SetOriginTo(a); BallMesh.DrawSubset(0); SetOrigin(); } public static Vector3 Vec3(Location loc) { return new Vector3((float)loc.X, (float)loc.Y, (float)loc.Z); } public void SetOriginTo(Location loc) { DXDevice.Transform.World = OriginTo(loc); } public static Matrix OriginTo(Location loc) { return Matrix.Translation(Vec3(loc)); } public void SetOriginAndZOrientationTo(Location loc, Location direction) { DXDevice.Transform.World = OriginAndZOrientationTo(loc, direction); } public static Matrix OriginAndZOrientationTo(Location loc, Location direction) { Matrix transform = Matrix.Identity; //transform.Multiply(Matrix.RotationZ(angle)); Location zAxis = new Location(0, 0, 1); Location dir = direction.Normalised(); Location axis = dir.CrossProduct(zAxis); float by = (float)Math.Acos(dir.DotProduct(zAxis)); transform.Multiply(Matrix.RotationAxis(Vec3(axis), -by)); transform.Multiply(Matrix.Translation(Vec3(loc))); return transform; } public void SetOrigin() { SetOriginTo(new Location(0, 0, 0)); } public void Status(string text) { Font.DrawText(null, text, 0, 0, Color.WhiteSmoke); } } }