private List <GraphicsTriangle> projectVisibleTriangles() { //create a look at matrix to transfrom the environment objects from world space to view space Matrix4x4 viewMatrix = Matrix4x4.CreateLookAt(Position, Position + Direction, new Vector3(0, 1, 0)); List <GraphicsTriangle> trianglesToRaster = new List <GraphicsTriangle>(); //loops through each object in the environment and if any triangle of the object can be seen, it gets projected //to view space and clips them against the near plane (so objects behind the camera aren't rendered) foreach (EnvironmentObject e in Environment.EnvironmentObjects) { List <GraphicsTriangle> triangles = e.Mesh.GraphicsTriangles; for (int i = 0; i < triangles.Count; ++i) { GraphicsTriangle t = triangles[i]; //Current triangle //Creates vector from the camera position to the triangle, if the dot product is less than 0 then the camera //can see the triangle so the projection and clipping can be done if (GraphicsVector3.Dot(t.Normal, t.Points[0] - Position) < 0.0f) { GraphicsTriangle projected = t.Copy(); //Convert from world space to view space (Still 3D) projected.TransformMatrix4x4(viewMatrix); //Clip the triangle against the near plane while adding it to the list of triangles to raster trianglesToRaster.AddRange(ClipTriangleAgainstPlane(new Vector3(0f, 0f, 0.1f), new Vector3(0f, 0f, 1f), projected)); } } } return(trianglesToRaster); }
public void TransformMatrix4x4(Matrix4x4 matrix) { for (int i = 0; i < 3; ++i) { Points[i] = GraphicsVector3.Transform(Points[i], matrix); } }
public static GraphicsVector3 Transform(GraphicsVector3 vec1, Matrix4x4 matrix) { GraphicsVector3 v = new GraphicsVector3(Vector3.Transform(vec1.Value, matrix)); v.Value += new Vector3(vec1.W * matrix.M14, vec1.W * matrix.M24, vec1.W * matrix.M34); v.W = vec1.Value.X * matrix.M14 + vec1.Value.Y * matrix.M24 + vec1.Value.Z * matrix.M34 + vec1.Value.Z * matrix.M44; return(v); }
public GraphicsTriangle(GraphicsVector3 point1, GraphicsVector3 point2, GraphicsVector3 point3, Vector3 normal, Color color) { Points = new GraphicsVector3[3]; TexturePoints = new TextureVector[3]; Points[0] = point1; Points[1] = point2; Points[2] = point3; Normal = normal; Color = color; }
public GraphicsTriangle(GraphicsVector3 point1, GraphicsVector3 point2, GraphicsVector3 point3, Color color) { Points = new GraphicsVector3[3]; TexturePoints = new TextureVector[3]; Points[0] = point1; Points[1] = point2; Points[2] = point3; generateNormal(); Color = color; }
public GraphicsTriangle(Triangle triangle, TextureVector[] texturePoints) { Points = new GraphicsVector3[3]; TexturePoints = texturePoints; for (int i = 0; i < 3; ++i) { Points[i] = new GraphicsVector3(triangle.Points[i]); } Normal = triangle.Normal; Color = triangle.Color; }
public GraphicsTriangle Copy() { GraphicsVector3[] newPoints = new GraphicsVector3[3]; TextureVector[] newTexturePoints = new TextureVector[3]; for (int i = 0; i < 3; ++i) { newPoints[i] = new GraphicsVector3(Points[i]); newTexturePoints[i] = new TextureVector(TexturePoints[i]); } return(new GraphicsTriangle(newPoints, newTexturePoints, Normal, Color)); }
private GraphicsTriangle ConvertToScreenSpace(GraphicsTriangle triangle, float frameWidth, float frameHeight) { GraphicsVector3[] newPoints = new GraphicsVector3[3]; for (int i = 0; i < 3; ++i) { GraphicsVector3 newPoint = GraphicsVector3.Transform(triangle.Points[i], projectionMatrix); newPoint.Value /= newPoint.W; newPoint.Value.X += 1.0f; newPoint.Value.Y += 1.0f; newPoint.Value.X *= (0.5f * frameWidth); newPoint.Value.Y *= (0.5f * frameHeight); newPoints[i] = newPoint; } return(new GraphicsTriangle(newPoints, triangle.TexturePoints, triangle.Normal, triangle.Color)); }
private void fillTriangle(Graphics graphics, GraphicsTriangle triangle, Color c, float brightness) { c = Color.FromArgb((int)(c.R * brightness), (int)(c.G * brightness), (int)(c.B * brightness)); Array.Sort(triangle.Points, delegate(GraphicsVector3 vec1, GraphicsVector3 vec2) { return(vec1.Value.Y.CompareTo(vec2.Value.Y)); }); if (triangle.Points[1].Value.Y == triangle.Points[2].Value.Y) { fillFlatBottomTriangle(graphics, triangle.Points, c); } else if (triangle.Points[0].Value.Y == triangle.Points[1].Value.Y) { fillFlatTopTriangle(graphics, triangle.Points, c); } else { GraphicsVector3 v4 = new GraphicsVector3(new Vector3((int)(triangle.Points[0].Value.X + (triangle.Points[1].Value.Y - triangle.Points[0].Value.Y) / (triangle.Points[2].Value.Y - triangle.Points[0].Value.Y) * (triangle.Points[2].Value.X - triangle.Points[0].Value.X)), triangle.Points[1].Value.Y, 1)); fillFlatBottomTriangle(graphics, new GraphicsVector3[] { triangle.Points[0], triangle.Points[1], v4 }, c); fillFlatTopTriangle(graphics, new GraphicsVector3[] { triangle.Points[1], v4, triangle.Points[2] }, c); } }
private float GetShortestDistanceToPlane(GraphicsVector3 point, Vector3 planePosition, Vector3 planeNormal) { return(planeNormal.X * -point.Value.X + planeNormal.Y * -point.Value.Y + planeNormal.Z * -point.Value.Z - Vector3.Dot(planeNormal, planePosition)); }
private GraphicsTriangle[] ClipTriangleAgainstPlane(Vector3 planePosition, Vector3 planeNormal, GraphicsTriangle triangle) { planeNormal = Vector3.Normalize(planeNormal); List <GraphicsVector3> insidePoints = new List <GraphicsVector3>(); List <GraphicsVector3> outsidePoints = new List <GraphicsVector3>(); List <TextureVector> insideTexturePoints = new List <TextureVector>(); List <TextureVector> outsideTexturePoints = new List <TextureVector>(); float[] distances = new float[3]; for (int i = 0; i < 3; ++i) { distances[i] = GetShortestDistanceToPlane(triangle.Points[i], planePosition, planeNormal); } for (int i = 0; i < 3; ++i) { if (distances[i] >= 0) { insidePoints.Add(triangle.Points[i]); insideTexturePoints.Add(triangle.TexturePoints[i]); } else { outsidePoints.Add(triangle.Points[i]); outsideTexturePoints.Add(triangle.TexturePoints[i]); } } if (insidePoints.Count == 0) { return(new GraphicsTriangle[] { }); } if (insidePoints.Count == 3) { return(new GraphicsTriangle[] { triangle }); } if (insidePoints.Count == 1 && outsidePoints.Count == 2) { GraphicsVector3 p1 = insidePoints[0]; TextureVector tp1 = insideTexturePoints[0]; float t; GraphicsVector3 p2 = LinePlaneIntersection(planePosition, planeNormal, p1, outsidePoints[0], out t); TextureVector tp2 = clipTextureVector(insideTexturePoints[0], outsideTexturePoints[0], t); GraphicsVector3 p3 = LinePlaneIntersection(planePosition, planeNormal, p1, outsidePoints[1], out t); TextureVector tp3 = clipTextureVector(insideTexturePoints[0], outsideTexturePoints[1], t); return(new GraphicsTriangle[] { new GraphicsTriangle(p1, p2, p3, tp1, tp2, tp3, triangle.Normal, triangle.Color) }); } if (insidePoints.Count == 2 && outsidePoints.Count == 1) { float t; GraphicsVector3 t1p1 = insidePoints[0]; GraphicsVector3 t1p2 = insidePoints[1]; GraphicsVector3 t1p3 = LinePlaneIntersection(planePosition, planeNormal, t1p1, outsidePoints[0], out t); TextureVector t1tp1 = insideTexturePoints[0]; TextureVector t1tp2 = insideTexturePoints[1]; TextureVector t1tp3 = clipTextureVector(t1tp1, outsideTexturePoints[0], t); GraphicsVector3 t2p1 = insidePoints[1]; GraphicsVector3 t2p2 = t1p3; GraphicsVector3 t2p3 = LinePlaneIntersection(planePosition, planeNormal, t2p1, outsidePoints[0], out t); TextureVector t2tp1 = insideTexturePoints[1]; TextureVector t2tp2 = t1tp3; TextureVector t2tp3 = clipTextureVector(t2tp1, outsideTexturePoints[0], t); return(new GraphicsTriangle[] { new GraphicsTriangle(t1p1, t1p3, t1p2, t1tp1, t1tp2, t1tp3, triangle.Normal, triangle.Color), new GraphicsTriangle(t2p1, t2p2, t2p3, t2tp1, t2tp2, t2tp3, triangle.Normal, triangle.Color) }); } return(null); //To satisfy the compliers :( }
private GraphicsVector3 LinePlaneIntersection(Vector3 planePosition, Vector3 planeNormal, GraphicsVector3 lineStart, GraphicsVector3 lineEnd, out float t) { planeNormal = Vector3.Normalize(planeNormal); float planeDot = Vector3.Dot(planeNormal, planePosition); float ad = Vector3.Dot(lineStart.Value, planeNormal); float bd = Vector3.Dot(lineEnd.Value, planeNormal); t = (-planeDot - ad) / (bd - ad); Vector3 lineToIntersect = (lineEnd.Value - lineStart.Value) * t; return(new GraphicsVector3(lineStart.Value + lineToIntersect)); }
public static float Dot(Vector3 vec1, GraphicsVector3 vec2) { return(Vector3.Dot(vec1, vec2.Value)); }
public static GraphicsVector3 Cross(GraphicsVector3 vec1, GraphicsVector3 vec2) { return(new GraphicsVector3(Vector3.Cross(vec1.Value, vec2.Value))); }
public GraphicsVector3(GraphicsVector3 original) { Value = original.Value; W = original.W; }
private void generateNormal() { Normal = GraphicsVector3.Cross(Points[1] - Points[0], Points[2] - Points[0]).Value; Normal = Vector3.Normalize(Normal); }