using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RaytracerEngine { public class triangle : hitable { vec3 posa; vec3 posb; vec3 posc; int reflect; public triangle() { } public triangle(vec3 a, vec3 b, vec3 c, int r) { posa = a; posb = b; posc = c; reflect = r; } public override bool hit(ray r, float t_min, float t_max, out hit_record rec) { // The three triangle vertices. vec3 verta, vertb, vertc; vec3 vecray, posray; vec3 n = new vec3(0,0,0); // Normal vector float xa, xb, xc, xd, xe, ya, yb, yc, yd, ye, za, zb, zc, zd, ze; // The components to determine t. float m, beta, gamma, t; // Components to determine the Barycentric coordinates. float a, b, c, d, e, f, g, h, i, j, k, l; // Copy the three positions from the triangle class into the x, y, z arrays. verta = posa; vertb = posb; vertc = posc; vecray = r.direction; posray = r.origin; // Set up the a,b, and c components of the 3 vertices. xa = verta[0]; xb = vertb[0]; xc = vertc[0]; xd = vecray[0]; xe = posray[0]; ya = verta[1]; yb = vertb[1]; yc = vertc[1]; yd = vecray[1]; ye = posray[1]; za = verta[2]; zb = vertb[2]; zc = vertc[2]; zd = vecray[2]; ze = posray[2]; // Set up the components. a = xa - xb; b = ya - yb; c = za - zb; d = xa - xc; e = ya - yc; f = za - zc; g = xd; h = yd; i = zd; j = xa - xe; k = ya - ye; l = za - ze; // Calculate M, Beta, Gamma, and t. m = (a * ((e * i) - (h * f))) + (b * ((g * f) - (d * i))) + (c * ((d * h) - (e * g))); t = (-(((f * ((a * k) - (j * b))) + (e * ((j * c) - (a * l))) + (d * ((b * l) - (k * c))))) / m); // Return the result of the intersection. if (t < 0) { t = 0; rec = new hit_record(); return false; } gamma = (((i * ((a * k) - (j * b))) + (h * ((j * c) - (a * l))) + (g * ((b * l) - (k * c)))) / m); if ((gamma < 0) || (gamma > 1)) { t = 0; rec = new hit_record(); return false; } beta = ((j * ((e * i) - (h * f)) + (k * ((g * f) - (d * i))) + (l * ((d * h) - (e * g)))) / m); if ((beta < 0) || (beta > (1-gamma))) { t = 0; rec = new hit_record(); return false; } // Calculate the normal of the triangle vec3 u = new vec3(0, 0, 0); vec3 v = new vec3(0, 0, 0); u = vertb - verta; v = vertc - verta; n = vec3.cross(v, u); // Determine the position that the vector hits the object. vec3 hit_pos = new vec3(0, 0, 0); vecray = vecray * t; hit_pos = posray + vecray; // Set up the normal of the triangle in regards to the hit position. vec3 normal = new vec3(0, 0, 0); normal = hit_pos - n; normal.normalize(); if (t < t_max && t > t_min) { rec.t = t; rec.p = hit_pos; rec.normal = normal; return true; } rec = new hit_record(); return false; } } }