Add front/back face detection
This commit is contained in:
3
demo.c
3
demo.c
@@ -4,6 +4,7 @@
|
|||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
#include "vec3.h"
|
#include "vec3.h"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -34,7 +35,7 @@ static vec3_t raycol(ray_t ray)
|
|||||||
{
|
{
|
||||||
hit_t hit;
|
hit_t hit;
|
||||||
for (unsigned i = 0; i < NELEMS(scene); ++i) {
|
for (unsigned i = 0; i < NELEMS(scene); ++i) {
|
||||||
if (scene[i].intersect(scene[i].params, ray, &hit))
|
if (scene[i].intersect(scene[i].params, ray, &hit, 0.0, DBL_MAX))
|
||||||
return vec3_scale(vec3_add(hit.normal, white), 0.5);
|
return vec3_scale(vec3_add(hit.normal, white), 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
vec3_t point, normal;
|
vec3_t point, normal;
|
||||||
double t;
|
double t;
|
||||||
|
bool front;
|
||||||
} hit_t;
|
} hit_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -25,11 +26,17 @@ typedef union {
|
|||||||
sphere_params_t sphere;
|
sphere_params_t sphere;
|
||||||
} obj_params_t;
|
} obj_params_t;
|
||||||
|
|
||||||
|
typedef bool intersect_fn_t(
|
||||||
|
obj_params_t params, ray_t ray, hit_t *hit_out, double t_min,
|
||||||
|
double t_max);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool (*intersect)(obj_params_t params, ray_t ray, hit_t *hit_out);
|
intersect_fn_t *intersect;
|
||||||
obj_params_t params;
|
obj_params_t params;
|
||||||
} obj_t;
|
} obj_t;
|
||||||
|
|
||||||
bool intersect_sphere(obj_params_t params, ray_t ray, hit_t *hit_out);
|
bool intersect_sphere(
|
||||||
|
obj_params_t params, ray_t ray, hit_t *hit_out, double t_min,
|
||||||
|
double t_max);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
24
src/obj.c
24
src/obj.c
@@ -2,28 +2,34 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
bool intersect_sphere(obj_params_t params, ray_t ray, hit_t *hit_out)
|
bool intersect_sphere(
|
||||||
|
obj_params_t params, ray_t ray, hit_t *hit_out, double t_min,
|
||||||
|
double t_max)
|
||||||
{
|
{
|
||||||
const vec3_t centre = params.sphere.centre;
|
const vec3_t centre = params.sphere.centre;
|
||||||
const double r = params.sphere.radius;
|
const double r = params.sphere.radius;
|
||||||
const vec3_t disp = vec3_sub(centre, ray.orig);
|
const vec3_t disp = vec3_sub(centre, ray.orig);
|
||||||
|
|
||||||
const double a = vec3_dot(ray.dir, ray.dir);
|
const double a = vec3_dot(ray.dir, ray.dir);
|
||||||
const double b = -2.0 * vec3_dot(ray.dir, disp);
|
const double h = vec3_dot(ray.dir, disp);
|
||||||
const double c = vec3_dot(disp, disp) - r * r;
|
const double c = vec3_dot(disp, disp) - r * r;
|
||||||
|
|
||||||
const double discriminant = b * b - 4 * a * c;
|
const double discriminant = h * h - a * c;
|
||||||
if (discriminant < 0)
|
if (discriminant < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const double t = (-b - sqrt(discriminant)) / (2.0 * a);
|
const double sqrtd = sqrt(discriminant);
|
||||||
|
const double low = (h - sqrtd) / a;
|
||||||
|
const double t = low > t_min ? low : (h + sqrtd) / a;
|
||||||
|
if (t < t_min || t_max < t)
|
||||||
|
return false;
|
||||||
|
|
||||||
const vec3_t point = vec3_add(ray.orig, vec3_scale(ray.dir, t));
|
const vec3_t point = vec3_add(ray.orig, vec3_scale(ray.dir, t));
|
||||||
const vec3_t normal = vec3_unit(vec3_sub(point, centre));
|
const vec3_t normal = vec3_unit(vec3_sub(point, centre));
|
||||||
|
|
||||||
if (hit_out != nullptr) {
|
hit_out->point = point;
|
||||||
hit_out->point = point;
|
hit_out->normal = normal;
|
||||||
hit_out->normal = normal;
|
hit_out->t = t;
|
||||||
hit_out->t = t;
|
hit_out->front = vec3_dot(ray.dir, normal) < 0.0;
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user