119 lines
3.8 KiB
C#
119 lines
3.8 KiB
C#
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|