Tachyon (current)  Current Main Branch
quadric.c
Go to the documentation of this file.
1 /*
2  * quadric.c - This file contains the functions for dealing with quadrics.
3  *
4  * (C) Copyright 1994-2022 John E. Stone
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * $Id: quadric.c,v 1.28 2022/02/18 17:55:28 johns Exp $
8  *
9  */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <math.h>
15 
16 #define TACHYON_INTERNAL 1
17 #include "tachyon.h"
18 #include "macros.h"
19 #include "quadric.h"
20 #include "vector.h"
21 #include "intersect.h"
22 #include "util.h"
23 
24 int quadric_bbox(void * obj, vector * min, vector * max) {
25  return 0;
26 }
27 
28 static object_methods quadric_methods = {
29  (void (*)(const void *, void *))(quadric_intersect),
30  (void (*)(const void *, const void *, const void *, void *))(quadric_normal),
31  quadric_bbox,
32  free
33 };
34 
36  quadric * q;
37 
38  q=(quadric *) malloc(sizeof(quadric));
39  memset(q, 0, sizeof(quadric));
40  q->ctr.x=0.0;
41  q->ctr.y=0.0;
42  q->ctr.z=0.0;
43  q->methods = &quadric_methods;
44 
45  return q;
46 }
47 
48 void quadric_intersect(const quadric * q, ray * ry) {
49  flt Aq, Bq, Cq;
50  flt t1, t2;
51  flt disc;
52  vector rd;
53  vector ro;
54 
55  rd=ry->d;
56  VNorm(&rd);
57 
58  ro.x = ry->o.x - q->ctr.x;
59  ro.y = ry->o.y - q->ctr.y;
60  ro.z = ry->o.z - q->ctr.z;
61 
62 
63  Aq = (q->mat.a*(rd.x * rd.x)) +
64  (2.0 * q->mat.b * rd.x * rd.y) +
65  (2.0 * q->mat.c * rd.x * rd.z) +
66  (q->mat.e * (rd.y * rd.y)) +
67  (2.0 * q->mat.f * rd.y * rd.z) +
68  (q->mat.h * (rd.z * rd.z));
69 
70  Bq = 2.0 * (
71  (q->mat.a * ro.x * rd.x) +
72  (q->mat.b * ((ro.x * rd.y) + (rd.x * ro.y))) +
73  (q->mat.c * ((ro.x * rd.z) + (rd.x * ro.z))) +
74  (q->mat.d * rd.x) +
75  (q->mat.e * ro.y * rd.y) +
76  (q->mat.f * ((ro.y * rd.z) + (rd.y * ro.z))) +
77  (q->mat.g * rd.y) +
78  (q->mat.h * ro.z * rd.z) +
79  (q->mat.i * rd.z)
80  );
81 
82  Cq = (q->mat.a * (ro.x * ro.x)) +
83  (2.0 * q->mat.b * ro.x * ro.y) +
84  (2.0 * q->mat.c * ro.x * ro.z) +
85  (2.0 * q->mat.d * ro.x) +
86  (q->mat.e * (ro.y * ro.y)) +
87  (2.0 * q->mat.f * ro.y * ro.z) +
88  (2.0 * q->mat.g * ro.y) +
89  (q->mat.h * (ro.z * ro.z)) +
90  (2.0 * q->mat.i * ro.z) +
91  q->mat.j;
92 
93  if (Aq == 0.0) {
94  t1 = - Cq / Bq;
95  ry->add_intersection(t1, (object *) q, ry);
96  }
97  else {
98  disc=(Bq*Bq - 4.0 * Aq * Cq);
99  if (disc > 0.0) {
100  disc=SQRT(disc);
101  t1 = (-Bq + disc) / (2.0 * Aq);
102  t2 = (-Bq - disc) / (2.0 * Aq);
103  ry->add_intersection(t1, (object *) q, ry);
104  ry->add_intersection(t2, (object *) q, ry);
105  }
106  }
107 }
108 
109 void quadric_normal(const quadric * q, const vector * pnt, const ray * incident, vector * N) {
110  flt invlen;
111 
112  N->x = (q->mat.a*(pnt->x - q->ctr.x) +
113  q->mat.b*(pnt->y - q->ctr.y) +
114  q->mat.c*(pnt->z - q->ctr.z) + q->mat.d);
115 
116  N->y = (q->mat.b*(pnt->x - q->ctr.x) +
117  q->mat.e*(pnt->y - q->ctr.y) +
118  q->mat.f*(pnt->z - q->ctr.z) + q->mat.g);
119 
120  N->z = (q->mat.c*(pnt->x - q->ctr.x) +
121  q->mat.f*(pnt->y - q->ctr.y) +
122  q->mat.h*(pnt->z - q->ctr.z) + q->mat.i);
123 
124  invlen = 1.0 / SQRT(N->x*N->x + N->y*N->y + N->z*N->z);
125  N->x *= invlen;
126  N->y *= invlen;
127  N->z *= invlen;
128 
129  /* Flip surface normal to point toward the viewer if necessary */
130  if (VDot(N, &(incident->d)) > 0.0) {
131  N->x=-N->x;
132  N->y=-N->y;
133  N->z=-N->z;
134  }
135 }
136 
137 
flt a
Definition: quadric.h:12
void quadric_normal(const quadric *q, const vector *pnt, const ray *incident, vector *N)
Definition: quadric.c:109
flt h
Definition: quadric.h:14
flt c
Definition: quadric.h:12
flt b
Definition: quadric.h:12
quadric * newquadric(void)
Definition: quadric.c:35
static object_methods quadric_methods
Definition: quadric.c:28
void VNorm(apivector *)
flt f
Definition: quadric.h:13
flt e
Definition: quadric.h:13
flt i
Definition: quadric.h:14
flt VDot(apivector *a, apivector *b)
double flt
generic floating point number, using double
Definition: tachyon.h:47
void quadric_intersect(const quadric *q, ray *ry)
Definition: quadric.c:48
RT_OBJECT_HEAD vector ctr
center of quadric object
Definition: quadric.h:20
Tachyon cross-platform timers, special math function wrappers, and RNGs.
flt g
Definition: quadric.h:14
#define SQRT(x)
Definition: util.h:31
quadmatrix mat
quadric function coefficient matrix
Definition: quadric.h:21
flt d
Definition: quadric.h:13
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...
int quadric_bbox(void *obj, vector *min, vector *max)
Definition: quadric.c:24
flt j
Definition: quadric.h:14