11 static int null_isect(struct erb_surf *surf, struct erb_ray *ray, struct erb_hit *hit);
12 static void null_hitgeom(struct erb_surf *surf, struct erb_hit *hit);
13 static void null_sample(struct erb_surf *surf, cgm_vec3 *pos);
14 static void null_bbox(struct erb_surf *surf, struct erb_aabb *bb);
16 static int sph_isect(struct erb_surf *surf, struct erb_ray *ray, struct erb_hit *hit);
17 static void sph_hitgeom(struct erb_surf *surf, struct erb_hit *hit);
18 static void sph_sample(struct erb_surf *surf, cgm_vec3 *pos);
19 static void sph_bbox(struct erb_surf *surf, struct erb_aabb *bb);
21 static int box_isect(struct erb_surf *surf, struct erb_ray *ray, struct erb_hit *hit);
22 static void box_hitgeom(struct erb_surf *surf, struct erb_hit *hit);
23 static void box_sample(struct erb_surf *surf, cgm_vec3 *pos);
24 static void box_bbox(struct erb_surf *surf, struct erb_aabb *bb);
27 struct erb_surf *erb_surface(int datasz)
29 struct erb_surf *surf;
31 if(!(surf = calloc(1, sizeof *surf - sizeof surf->data + datasz))) {
32 fprintf(stderr, "failed to allocate surface\n");
35 surf->isect = null_isect;
36 surf->hitgeom = null_hitgeom;
37 surf->sample = null_sample;
38 surf->calc_bbox = null_bbox;
42 void erb_free_surface(struct erb_surf *surf)
45 erb_node_rmsurf(surf->node, surf);
50 struct erb_surf *erb_surf_sphere(float rad)
52 struct erb_surf *surf;
53 struct sph_data *sdata;
55 if(!(surf = erb_surface(sizeof *sdata))) {
58 surf->isect = sph_isect;
59 surf->hitgeom = sph_hitgeom;
60 surf->sample = sph_sample;
61 surf->calc_bbox = sph_bbox;
62 sdata = (struct sph_data*)surf->data;
67 struct erb_surf *erb_surf_box(float xsz, float ysz, float zsz)
69 struct erb_surf *surf;
70 struct box_data *bdata;
72 if(!(surf = erb_surface(sizeof *bdata))) {
75 surf->isect = box_isect;
76 surf->hitgeom = box_hitgeom;
77 surf->sample = box_sample;
78 surf->calc_bbox = box_bbox;
79 bdata = (struct box_data*)surf->data;
80 cgm_vcons(&bdata->sz, xsz, ysz, zsz);
85 static int null_isect(struct erb_surf *surf, struct erb_ray *ray, struct erb_hit *hit)
90 static void null_hitgeom(struct erb_surf *surf, struct erb_hit *hit)
92 fprintf(stderr, "BUG: null_hitgeom called\n");
95 static void null_sample(struct erb_surf *surf, cgm_vec3 *pos)
97 pos->x = pos->y = pos->z = 0;
100 static void null_bbox(struct erb_surf *surf, struct erb_aabb *bb)
102 bb->pos.x = bb->pos.y = bb->pos.z = 0;
103 bb->sz.x = bb->sz.y = bb->sz.z = 0;
106 static int sph_isect(struct erb_surf *surf, struct erb_ray *ray, struct erb_hit *hit)
108 float a, b, c, d, sqrt_d, q, t, t0, t1;
110 struct sph_data *sdata = (struct sph_data*)surf->data;
113 erb_xform_ray(ray, surf->node->inv_xform, &org, &dir);
119 a = cgm_vdot(&dir, &dir);
120 b = 2.0f * cgm_vdot(&org, &dir);
121 c = cgm_vdot(&org, &org) - sdata->rad * sdata->rad;
123 d = b * b - 4.0f * a * c;
124 if(d <= 0.0f) return 0;
127 q = b < 0.0f ? -0.5f * (b - sqrt_d) : -0.5f * (b + sqrt_d);
137 if(t0 > ray->tmax || t1 < ray->tmin) {
140 t = t0 < ray->tmin ? t1 : t0;
147 hit->err = 5e-4f * t; /* PBR 3.2.6 */
150 cgm_vadd_scaled(&hit->pos, &ray->d, t);
152 cgm_vadd_scaled(&hit->lpos, &dir, t);
153 hit->total_dist = ray->total_dist + t;
159 static void sph_hitgeom(struct erb_surf *surf, struct erb_hit *hit)
163 hit->norm = hit->lpos;
164 cgm_vnormalize(&hit->norm);
166 cgm_uvec_to_sph(&theta, &phi, &hit->norm);
168 hit->u = (theta + M_PI) / (2.0 * M_PI);
171 hit->tang.x = hit->norm.z;
172 hit->tang.y = hit->norm.y;
173 hit->tang.z = -hit->norm.x;
176 cgm_vmul_m3v3(&hit->norm, surf->node->xform);
177 cgm_vmul_m3v3(&hit->tang, surf->node->xform);
181 static void sph_sample(struct erb_surf *surf, cgm_vec3 *pos)
186 static void sph_bbox(struct erb_surf *surf, struct erb_aabb *bb)
188 struct sph_data *sdata = (struct sph_data*)surf->data;
190 cgm_vcons(&bb->pos, 0, 0, 0);
191 bb->sz.x = bb->sz.y = bb->sz.z = sdata->rad;
195 static int box_isect(struct erb_surf *surf, struct erb_ray *ray, struct erb_hit *hit)
200 static void box_hitgeom(struct erb_surf *surf, struct erb_hit *hit)
204 static void box_sample(struct erb_surf *surf, cgm_vec3 *pos)
208 static void box_bbox(struct erb_surf *surf, struct erb_aabb *bb)