/// <summary> /// 画一条直线 /// </summary> /// <param name="point0"></param> /// <param name="point1"></param> /// <param name="scene"></param> /// <param name="v1"></param> /// <param name="v2"></param> public void DrawLine(Vector4 point0, Vector4 point1, Scene scene, Vertex v1, Vertex v2) { int x0 = (int)point0.X; int y0 = (int)point0.Y; int x1 = (int)point1.X; int y1 = (int)point1.Y; int dx = x1 - x0; int dy = y1 - y0; int steps = Math.Max(Math.Abs(dx), Math.Abs(dy)); if (steps == 0) { return; } float offsetX = (float)dx / (float)steps; float offsetY = (float)dy / (float)steps; float x = x0; float y = y0; Color vColor = new Color(128, 128, 128); for (int i = 1; i <= steps; i++) { float dt = (float)(i) / (float)steps; vColor = MathUntily.Lerp(v1.Color, v2.Color, dt); float z = MathUntily.Lerp(point0.Z, point1.Z, dt); if (float.IsNaN(z)) { return; } DrawPoint(new Vector4((int)x, (int)y, z, 0), vColor); x += offsetX; y += offsetY; } }
/// <summary> /// 求交点, 返回的pos是裁剪空间下坐标 /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="face"></param> /// <param name="wMin"></param> /// <param name="wMax"></param> /// <returns></returns> Vertex Intersect(Vertex v1, Vertex v2, FaceTypes face, Vector4 wMin, Vector4 wMax) { Vertex vertex = new Vertex(); float k1 = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0, k6 = 0; Vector4 p1 = v1.ClipPosition; Vector4 p2 = v2.ClipPosition; if (p1.X != p2.X) { k1 = (wMin.X - p1.X) / (p2.X - p1.X); k2 = (wMax.X - p1.X) / (p2.X - p1.X); } else { k1 = k2 = 1; } if (p1.Y != p2.Y) { k3 = (wMin.Y - p1.Y) / (p2.Y - p1.Y); k4 = (wMax.Y - p1.Y) / (p2.Y - p1.Y); } else { k3 = k4 = 1; } if (p1.Z != p2.Z) { k5 = (wMin.Z - p1.Z) / (p2.Z - p1.Z); k6 = (wMax.Z - p1.Z) / (p2.Z - p1.Z); } else { k5 = k6 = 1; } Vector4 clipPos = new Vector4(); Vector4 pos = new Vector4(); Color col = new Color(0, 0, 0); Vector4 normal = new Vector4(); Vector2 uv = new Vector2(); switch (face) { case FaceTypes.LEFT: clipPos.X = wMin.X; clipPos.Y = p1.Y + (p2.Y - p1.Y) * k1; clipPos.Z = p1.Z + (p2.Z - p1.Z) * k1; clipPos.W = p1.W + (p2.W - p1.W) * k1; col = MathUntily.Lerp(v1.Color, v2.Color, k1); normal = MathUntily.Lerp(v1.Normal, v2.Normal, k1); pos = MathUntily.Lerp(v1.Position, v2.Position, k1); uv = MathUntily.Lerp(v1.UV, v2.UV, k1); break; case FaceTypes.RIGHT: clipPos.X = wMax.X; clipPos.Y = p1.Y + (p2.Y - p1.Y) * k2; clipPos.Z = p1.Z + (p2.Z - p1.Z) * k2; clipPos.W = p1.W + (p2.W - p1.W) * k2; col = MathUntily.Lerp(v1.Color, v2.Color, k2); normal = MathUntily.Lerp(v1.Normal, v2.Normal, k2); pos = MathUntily.Lerp(v1.Position, v2.Position, k2); uv = MathUntily.Lerp(v1.UV, v2.UV, k2); break; case FaceTypes.BUTTOM: clipPos.Y = wMin.Y; clipPos.X = p1.X + (p2.X - p1.X) * k3; clipPos.Z = p1.Z + (p2.Z - p1.Z) * k3; clipPos.W = p1.W + (p2.W - p1.W) * k3; col = MathUntily.Lerp(v1.Color, v2.Color, k3); normal = MathUntily.Lerp(v1.Normal, v2.Normal, k3); pos = MathUntily.Lerp(v1.Position, v2.Position, k3); uv = MathUntily.Lerp(v1.UV, v2.UV, k3); break; case FaceTypes.TOP: clipPos.Y = wMax.Y; clipPos.X = p1.X + (p2.X - p1.X) * k4; clipPos.Z = p1.Z + (p2.Z - p1.Z) * k4; clipPos.W = p1.W + (p2.W - p1.W) * k4; col = MathUntily.Lerp(v1.Color, v2.Color, k4); normal = MathUntily.Lerp(v1.Normal, v2.Normal, k4); pos = MathUntily.Lerp(v1.Position, v2.Position, k4); uv = MathUntily.Lerp(v1.UV, v2.UV, k4); break; case FaceTypes.NEAR: clipPos.Z = wMin.Z; clipPos.X = p1.X + (p2.X - p1.X) * k5; clipPos.Y = p1.Y + (p2.Y - p1.Y) * k5; clipPos.W = p1.W + (p2.W - p1.W) * k5; col = MathUntily.Lerp(v1.Color, v2.Color, k5); normal = MathUntily.Lerp(v1.Normal, v2.Normal, k5); pos = MathUntily.Lerp(v1.Position, v2.Position, k5); uv = MathUntily.Lerp(v1.UV, v2.UV, k5); break; case FaceTypes.FAR: clipPos.Z = wMax.Z; clipPos.X = p1.X + (p2.X - p1.X) * k6; clipPos.Y = p1.Y + (p2.Y - p1.Y) * k6; clipPos.W = p1.W + (p2.W - p1.W) * k6; col = MathUntily.Lerp(v1.Color, v2.Color, k6); normal = MathUntily.Lerp(v1.Normal, v2.Normal, k6); pos = MathUntily.Lerp(v1.Position, v2.Position, k6); uv = MathUntily.Lerp(v1.UV, v2.UV, k6); break; } vertex.Position = pos; vertex.ClipPosition = clipPos; vertex.ScreenPosition = this.mDevice.ViewPort(clipPos); vertex.Normal = normal; vertex.UV = uv; vertex.Color = col; return(vertex); }