public Triangle(Vec3D pa, Vec3D pb, Vec3D pc) { p = new Vec3D[3]; p[0] = pa; p[1] = pb; p[2] = pc; color = 0; c = ConsoleCharacter.Null; }
public static Vec3D Cross(Vec3D a, Vec3D b) { Vec3D n = new Vec3D { x = a.y * b.z - a.z * b.y, y = a.z * b.x - a.x * b.z, z = a.x * b.y - a.y * b.x }; return(n); }
public static Matrix Translation(Vec3D t) { Matrix mat = new Matrix(); mat.m[0, 0] = 1.0f; mat.m[1, 1] = 1.0f; mat.m[2, 2] = 1.0f; mat.m[3, 3] = 1.0f; mat.m[3, 0] = t.x; mat.m[3, 1] = t.y; mat.m[3, 2] = t.z; return(mat); }
public static Vec3D MultiplyVector(Vec3D i, Matrix m) { Vec3D v = new Vec3D(); float w = 0; v.x = i.x * m.m[0, 0] + i.y * m.m[1, 0] + i.z * m.m[2, 0] + m.m[3, 0]; v.y = i.x * m.m[0, 1] + i.y * m.m[1, 1] + i.z * m.m[2, 1] + m.m[3, 1]; v.z = i.x * m.m[0, 2] + i.y * m.m[1, 2] + i.z * m.m[2, 2] + m.m[3, 2]; w = i.x * m.m[0, 3] + i.y * m.m[1, 3] + i.z * m.m[2, 3] + m.m[3, 3]; if (w != 0.0f) { v.x /= w; v.y /= w; v.z /= w; } return(v); }
public bool LoadFromObj(string filename) { StreamReader s = new StreamReader(filename); List <Vec3D> verts = new List <Vec3D>(); List <Triangle> tris = new List <Triangle>(); while (!s.EndOfStream) { string line = s.ReadLine(); if (line[0] == 'v') { Vec3D v = new Vec3D(); //AWV //string[] str = line.Replace('.', ',').Split(); string[] str = line.Split(); v.x = float.Parse(str[1]); v.y = float.Parse(str[2]); v.z = float.Parse(str[3]); verts.Add(v); } if (line[0] == 'f') { Triangle t = new Triangle(); string[] str = line.Split(); t.p = new Vec3D[3]; t.color = 6; t.p[0] = verts[Convert.ToInt32(str[1]) - 1]; t.p[1] = verts[Convert.ToInt32(str[2]) - 1]; t.p[2] = verts[Convert.ToInt32(str[3]) - 1]; tris.Add(t); } } Vertices = verts.ToArray(); Triangles = tris.ToArray(); return(true); }
public static Matrix PointAtMatrix(Vec3D pos, Vec3D target, Vec3D up) { // ny frammåt Vec3D newForward = target - pos; newForward.Normalize(); // ny uppåt Vec3D a = newForward * Vec3D.Dot(up, newForward); Vec3D newUp = up - a; newUp.Normalize(); Vec3D newRight = Vec3D.Cross(newUp, newForward); Matrix mat = new Matrix(); mat.m[0, 0] = newRight.x; mat.m[0, 1] = newRight.y; mat.m[0, 2] = newRight.z; mat.m[0, 3] = 0.0f; mat.m[1, 0] = newUp.x; mat.m[1, 1] = newUp.y; mat.m[1, 2] = newUp.z; mat.m[1, 3] = 0.0f; mat.m[2, 0] = newForward.x; mat.m[2, 1] = newForward.y; mat.m[2, 2] = newForward.z; mat.m[2, 3] = 0.0f; mat.m[3, 0] = pos.x; mat.m[2, 1] = pos.y; mat.m[2, 2] = pos.z; mat.m[2, 3] = 1.0f; return(mat); }
public override void Update() { if (Engine.GetKeyDown(ConsoleKey.Y)) { drawWireframe = !drawWireframe; } if (Engine.GetKeyDown(ConsoleKey.H)) { drawSolid = !drawSolid; } if (Engine.GetMouseLeft()) { Point delta = Engine.GetMousePos() - lastMousePos; yRot += delta.X / 80f; xRot += delta.Y / 80f; } lastMousePos = Engine.GetMousePos(); // matriserar Matrix transformMat, rotationMat; rotationMat = Matrix.RotationMatrixY(yRot); rotationMat *= Matrix.RotationMatrixX(xRot); transformMat = Matrix.Translation(modelPosition); // generera trianglar for (int i = 0; i < mesh.Triangles.Length; i++) { Triangle vertex = mesh.Triangles[i]; Triangle rotated = vertex.MatMul(rotationMat); Triangle transformed = rotated.MatMul(transformMat); // beräknar kryssprodukt av line1 och line2 för att hitta normal. Vec3D normal, line1, line2; line1 = transformed.p[1] - transformed.p[0]; line2 = transformed.p[2] - transformed.p[0]; normal = Vec3D.Cross(line1, line2); normal.Normalize(); // testar ifall vi kan se ytan if (Vec3D.Dot(normal, transformed.p[0] - camera) < 0.0f) { // beräknar ljus float l = Vec3D.Dot(lightDirection, normal); ConsoleCharacter character = ConsoleCharacter.Light; if (l > 0.4) { character = ConsoleCharacter.Medium; } if (l > 0.7) { character = ConsoleCharacter.Dark; } if (l > 1) { character = ConsoleCharacter.Full; } // projekterar från 3D -> 2D Triangle projected = new Triangle(null); projected = transformed.MatMul(projectionMatrix); // transformerar och skalar projektionen Vec3D offsetView = new Vec3D(1, 1, 0); projected.p[0] += offsetView; projected.p[1] += offsetView; projected.p[2] += offsetView; projected.p[0].x *= 0.5f * consoleWidth; projected.p[0].y *= 0.5f * consoleHeight; projected.p[1].x *= 0.5f * consoleWidth; projected.p[1].y *= 0.5f * consoleHeight; projected.p[2].x *= 0.5f * consoleWidth; projected.p[2].y *= 0.5f * consoleHeight; projected.c = character; trianglesToRaster.Add(projected); } } // sortera trianglesToRaster.Sort((t1, t2) => ((t2.p[0].z + t2.p[1].z + t2.p[2].z).CompareTo((t1.p[0].z + t1.p[1].z + t1.p[2].z)))); }
public void Translate(Vec3D delta) { p[0] += delta; p[1] += delta; p[2] += delta; }
// skalärprodukt https://sv.wikipedia.org/wiki/Skalärprodukt public static float Dot(Vec3D a, Vec3D b) { return(a.x * b.x + a.y * b.y + a.z * b.z); }