public static Vec3D VectorNormalise(Vec3D v) { float l = VectorLength(v); return(new Vec3D { x = v.x / l, y = v.y / l, z = v.z / l }); }
private void Render(object sender, EventArgs e) { PainterHelper.ClearScreen(bm); camera.vForward = Vec3D.VectorMul(camera.vLookDir, 0.05F); List <Triangle> trianglesToRaster = new List <Triangle>(); Matrix matView = camera.RotateCamera(); foreach (var tri in scene.triangles) { Triangle triProjected, triTransformed, triViewed; triViewed = new Triangle(3); triTransformed = Triangle.TransformTriangle(tri, transformations.matWorld); Vec3D vCameraRay = Vec3D.VectorSub(triTransformed.points[0], camera.vCamera); if (Vec3D.VectorDotProduct(triTransformed.Normal, vCameraRay) < 0.0F) { float lightIntensity = light.GetLightIntensityForSurface(triTransformed.Normal); Color color = PainterHelper.ChangeColorBrightness(Color.Black, lightIntensity); triViewed = Triangle.TransformTriangle(triTransformed, matView); triProjected = Triangle.ProjectTriangle(transformations.matProj, triViewed); triProjected.InvertXAndY(); //// Scale into view Vec3D vOffsetView = new Vec3D { x = 1, y = 1, z = 0 }; triProjected.Offset(vOffsetView, bm); triProjected.color = color; triProjected.zTotal = (triProjected.points[0].z + triProjected.points[1].z + triProjected.points[2].z) / 3.0F; trianglesToRaster.Add(triProjected); } } trianglesToRaster.Sort((p, q) => q.zTotal.CompareTo(p.zTotal)); foreach (var triangle in trianglesToRaster) { PainterHelper.DrawTriangle(triangle, bm); pictureBoxCanvas.Image = bm; } }
public static Vec3D VectorCrossProduct(Vec3D v1, Vec3D v2) { Vec3D v = new Vec3D(); v.x = v1.y * v2.z - v1.z * v2.y; v.y = v1.z * v2.x - v1.x * v2.z; v.z = v1.x * v2.y - v1.y * v2.x; return(v); }
public static Vec3D MatrixMultiplyVector(Vec3D i, Matrix m) { Vec3D v; v = new Vec3D(); v.x = i.x * m.matrix[0, 0] + i.y * m.matrix[1, 0] + i.z * m.matrix[2, 0] + i.w * m.matrix[3, 0]; v.y = i.x * m.matrix[0, 1] + i.y * m.matrix[1, 1] + i.z * m.matrix[2, 1] + i.w * m.matrix[3, 1]; v.z = i.x * m.matrix[0, 2] + i.y * m.matrix[1, 2] + i.z * m.matrix[2, 2] + i.w * m.matrix[3, 2]; v.w = i.x * m.matrix[0, 3] + i.y * m.matrix[1, 3] + i.z * m.matrix[2, 3] + i.w * m.matrix[3, 3]; return(v); }
public Camera() { vCamera = new Vec3D(); vLookDir = new Vec3D(); vForward = new Vec3D(); vUp = new Vec3D { x = 0, y = 1, z = 0 }; vTarget = new Vec3D { x = 0, y = 0, z = 1 }; }
public void Offset(Vec3D vOffsetView, Bitmap bm) { points[0] = Vec3D.VectorAdd(points[0], vOffsetView); points[1] = Vec3D.VectorAdd(points[1], vOffsetView); points[2] = Vec3D.VectorAdd(points[2], vOffsetView); points[0].x *= 0.5F * (float)bm.Width; points[0].y *= 0.5F * (float)bm.Height; points[1].x *= 0.5F * (float)bm.Width; points[1].y *= 0.5F * (float)bm.Height; points[2].x *= 0.5F * (float)bm.Width; points[2].y *= 0.5F * (float)bm.Height; }
public static Triangle ProjectTriangle(Matrix matProj, Triangle triToProject) { Triangle triProjected = new Triangle(3); triProjected.points[0] = Matrix.MatrixMultiplyVector(triToProject.points[0], matProj); triProjected.points[1] = Matrix.MatrixMultiplyVector(triToProject.points[1], matProj); triProjected.points[2] = Matrix.MatrixMultiplyVector(triToProject.points[2], matProj); triProjected.points[0] = Vec3D.VectorDiv(triProjected.points[0], triProjected.points[0].w); triProjected.points[1] = Vec3D.VectorDiv(triProjected.points[1], triProjected.points[1].w); triProjected.points[2] = Vec3D.VectorDiv(triProjected.points[2], triProjected.points[2].w); return(triProjected); }
public Matrix RotateCamera() { vTarget = new Vec3D { x = 0, y = 0, z = 1 }; Matrix matCameraRot = Matrix.Matrix_MakeRotationY(fYaw); vLookDir = Matrix.MatrixMultiplyVector(vTarget, matCameraRot); vTarget = Vec3D.VectorAdd(vCamera, vLookDir); Matrix matCamera = Matrix.Matrix_PointAt(vCamera, vTarget, vUp); Matrix matView = Matrix.Matrix_QuickInverse(matCamera); return(matView); }
public Mesh(string sFileName) { List <Vec3D> verts = new List <Vec3D>(); triangles = new List <Triangle>(); using (StreamReader sr = new StreamReader(sFileName)) { string line = sr.ReadLine(); while (!String.IsNullOrEmpty(line)) { if (line[0] == 'v') { Vec3D vect; vect = new Vec3D(); string[] parts = line.Split(' '); vect.x = float.Parse(parts[1], CultureInfo.InvariantCulture.NumberFormat); vect.y = float.Parse(parts[2], CultureInfo.InvariantCulture.NumberFormat); vect.z = float.Parse(parts[3], CultureInfo.InvariantCulture.NumberFormat); verts.Add(vect); } if (line[0] == 'f') { int[] f = new int[3]; string[] parts = line.Split(' '); f[0] = Convert.ToInt32(parts[1]); f[1] = Convert.ToInt32(parts[2]); f[2] = Convert.ToInt32(parts[3]); triangles.Add(new Triangle { points = new Vec3D[] { verts[f[0] - 1], verts[f[1] - 1], verts[f[2] - 1] } }); } line = sr.ReadLine(); } } }
public void MoveCamera(Keys key) { if (key == Keys.Up) { vCamera.y += 0.05F; } if (key == Keys.Down) { vCamera.y -= 0.05F; } if (key == Keys.Left) { vCamera.x += 0.05F; } if (key == Keys.Right) { vCamera.x -= 0.05F; } if (key == Keys.W) { vCamera = Vec3D.VectorAdd(vCamera, vForward); } if (key == Keys.S) { vCamera = Vec3D.VectorSub(vCamera, vForward); } if (key == Keys.A) { fYaw -= 0.05F; } if (key == Keys.D) { fYaw += 0.05F; } }
public static Matrix Matrix_PointAt(Vec3D pos, Vec3D target, Vec3D up) { Vec3D newForward = Vec3D.VectorSub(target, pos); newForward = Vec3D.VectorNormalise(newForward); Vec3D a = Vec3D.VectorMul(newForward, Vec3D.VectorDotProduct(up, newForward)); Vec3D newUp = Vec3D.VectorSub(up, a); newUp = Vec3D.VectorNormalise(newUp); Vec3D newRight = Vec3D.VectorCrossProduct(newUp, newForward); Matrix matrix = new Matrix(4); matrix.matrix[0, 0] = newRight.x; matrix.matrix[0, 1] = newRight.y; matrix.matrix[0, 2] = newRight.z; matrix.matrix[0, 3] = 0.0f; matrix.matrix[1, 0] = newUp.x; matrix.matrix[1, 1] = newUp.y; matrix.matrix[1, 2] = newUp.z; matrix.matrix[1, 3] = 0.0f; matrix.matrix[2, 0] = newForward.x; matrix.matrix[2, 1] = newForward.y; matrix.matrix[2, 2] = newForward.z; matrix.matrix[2, 3] = 0.0f; matrix.matrix[3, 0] = pos.x; matrix.matrix[3, 1] = pos.y; matrix.matrix[3, 2] = pos.z; matrix.matrix[3, 3] = 1.0f; return(matrix); }
public static Vec3D VectorMul(Vec3D v1, float k) { return(new Vec3D { x = v1.x * k, y = v1.y * k, z = v1.z * k }); }
public float GetLightIntensityForSurface(Vec3D surfaceNormal) { float intensity = (float)Math.Max(0.1f, Vec3D.VectorDotProduct(lightDirection, surfaceNormal)); return(intensity); }
public Light(Vec3D lightDirection) { this.lightDirection = lightDirection; this.lightDirection = Vec3D.VectorNormalise(lightDirection); }
public static Vec3D VectorSub(Vec3D v1, Vec3D v2) { return(new Vec3D { x = v1.x - v2.x, y = v1.y - v2.y, z = v1.z - v2.z }); }
public static Vec3D VectorAdd(Vec3D v1, Vec3D v2) { return(new Vec3D { x = v1.x + v2.x, y = v1.y + v2.y, z = v1.z + v2.z }); }
public static Vec3D VectorDiv(Vec3D v1, float k) { return(new Vec3D { x = v1.x / k, y = v1.y / k, z = v1.z / k }); }
public static float VectorDotProduct(Vec3D v1, Vec3D v2) { return(v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); }
public static float VectorLength(Vec3D v) { return((float)Math.Sqrt(VectorDotProduct(v, v))); }