RaytracerEngine/triangle.cs

119 lines
3.8 KiB
C#
Executable File

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;
}
}
}