static void paint_normal_and_height_maps(float min, float max) { int f, i, j; float rad; char red, green, blue; int p; for (f = 0; f < 6; f++) { for (i = 0; i < DIM; i++) { for (j = 0; j < DIM; j++) { p = (j * DIM + i) * 4; rad = vec3_magnitude(&vertex[f][i][j]); rad = (rad - min) / (max - min); heightmap_image[f][p + 0] = (unsigned char) (255.0 * rad); heightmap_image[f][p + 1] = (unsigned char) (255.0 * rad); heightmap_image[f][p + 2] = (unsigned char) (255.0 * rad); heightmap_image[f][p + 3] = 255; if (rad > sealevel) { red = normal[f][i][j].v.x * 255; green = normal[f][i][j].v.y * 255; blue = normal[f][i][j].v.z * 255; normal_image[f][p + 0] = red; normal_image[f][p + 1] = green; normal_image[f][p + 2] = blue; } else { normal_image[f][p + 0] = 127; normal_image[f][p + 1] = 127; normal_image[f][p + 2] = 255; } normal_image[f][p + 3] = 255; } } } }
void set_light(t_vec3 hit, t_obj *obj, t_lgt *light) { double theta; double epsilon; light->ray.pos = hit; if (light->type == DIRECTIONAL) { light->ray.dir = vec3_fmul(light->dir, -1); obj->dist_attenuation = 1.0; } else { light->ray.dir = vec3_sub(light->pos, hit); obj->t = vec3_magnitude(light->ray.dir); obj->dist_attenuation = (1.0 + obj->t * obj->t * light->attenuation); } if (light->type == SPOT) { theta = vec3_dot(light->dir, vec3_norm(vec3_fmul(light->ray.dir, -1))); epsilon = light->cutoff - light->cutoff_outer; light->cutoff_intensity = ft_clampf((theta - light->cutoff_outer) / epsilon, 0, 1); } vec3_normalize(&light->ray.dir); }
void plane_normalize(plane_t *p) { float len = 1.f / vec3_magnitude(&p->normal); vec3_scale(&p->normal, len); p->dist *= len; }
void quat_vector_vector(quat_t *q, const vec3_t *a, const vec3_t *b) { float cost = vec3_dot(a, b); if (cost > 0.99999f) { /* parallel */ *q = QUAT_IDENT; } else if (cost < -0.99999f) { /* opposite */ vec3_t t = VEC3(0, a->x, -a->y); /* cross with (1,0,0) */ if (vec3_magnitude(&t) < EPSILON) t = VEC3(-a->z, 0, a->x); /* nope, use (0,1,0) */ vec3_normalize(&t); q->v = t; q->w = 0.f; } else { vec3_t t; vec3_cross(&t, a, b); vec3_normalize(&t); /* sin^2 t = (1 - cos(2t)) / 2 */ float ss = sqrt(.5f * (1.f - cost)); vec3_scale(&t, ss); q->v = t; /* cos^2 t = (1 + cos(2t) / 2 */ q->w = sqrt(.5f * (1.f + cost)); } }
/** * Component of the support function for a cylinder collider. **/ static void object_support_component_cylinder(object_t *object, float direction[3], float out[3]) { float top[3] = { 0, object->h / 2, 0 }; float bottom[3] = { 0, -object->h / 2, 0 }; float axis[3]; float dir_perp[3]; float trans[16]; float dot_top; object_get_transform_mat(object, trans); /* Top and bottom are set to points in the middle of the top and the * bottom faces of the cylinder respectively. We transform them to * their worldspace positions. */ matrix_vec3_mul(trans, top, 1.0, top); matrix_vec3_mul(trans, bottom, 1.0, bottom); /* We get an axis vector that runs down the middle of the cylinder. */ vec3_subtract(top, bottom, axis); /* Part of another process, but useful now for a reason... */ vec3_cross(axis, direction, dir_perp); /* If the cross product is zero, our direction is aligned with the * cylinder and top and bottom are our two final candidates. */ if (vec3_magnitude(dir_perp) > 0) { /* This completes what we started with the last cross product. * dir_perp is now a vector perpendicular to the cylinder's * axis, but as close to our selected direction as possible. */ vec3_cross(dir_perp, axis, dir_perp); /* Scale dir_perp to be the radius of our cylinder. */ vec3_normalize(dir_perp, dir_perp); vec3_scale(dir_perp, dir_perp, object->r); /* Finally, move top and bottom to the edges of our cylinder in * the appropriate direction. We now have our two final * candidates. */ vec3_add(dir_perp, top, top); vec3_add(dir_perp, bottom, bottom); } /* We now have two candidates, top and bottom. We can just use largest * dot product to determine which is furthest. */ dot_top = vec3_dot(top, direction); if (dot_top > vec3_dot(bottom, direction)) memcpy(out, top, 3 * sizeof(float)); else memcpy(out, bottom, 3 * sizeof(float)); }
t_vect3d vec3_norm(t_vect3d v3) { float magnitude; t_vect3d r; magnitude = vec3_magnitude(v3); r.x = v3.x / magnitude; r.y = v3.y / magnitude; r.z = v3.z / magnitude; return (r); }
void vec3_normalize(vec3_t *v) { float len = vec3_magnitude(v); if (len < 1.e-5) return; len = 1.f / len; vec3_scale(v, len); }
t_vec3 bump_normal(t_obj *obj, t_ray *ray) { t_vec3 normal; t_vec3 tangent; t_vec3 binormal; t_vec3 bump; t_vec3 c[2]; normal = obj->normal; bump = texture_mapping(obj, obj->mat.texture.bump, ray->hit); bump = vec3_sub(vec3_fmul(bump, 2), vec3(1, 1, 1)); c[0] = vec3_cross(normal, vec3(0, 0, 1)); c[1] = vec3_cross(normal, vec3(0, 1, 0)); tangent = (vec3_magnitude(c[0]) > vec3_magnitude(c[1]) ? c[0] : c[1]); tangent = vec3_sub(tangent, vec3_fmul(normal, vec3_dot(tangent, normal))); vec3_normalize(&tangent); binormal = vec3_norm(vec3_cross(normal, tangent)); normal.x = vec3_dot(bump, vec3(tangent.x, binormal.x, normal.x)); normal.y = vec3_dot(bump, vec3(tangent.y, binormal.y, normal.y)); normal.z = vec3_dot(bump, vec3(tangent.z, binormal.z, normal.z)); vec3_normalize(&normal); return (normal); }
static void paint_terrain_colors(float min, float max) { int f, i, j; float r, n; int p; for (f = 0; f < 6; f++) { for (i = 0; i < DIM; i++) { for (j = 0; j < DIM; j++) { p = (j * DIM + i) * 4; r = vec3_magnitude(&vertex[f][i][j]); r = (r - min) / (max - min); n = (noise[f][i][j] - minn) / (maxn - minn); color_output(f, p, r, n); } } } }
static void paint_height_maps(float min, float max) { int f, i, j; float r; unsigned char c; int p; for (f = 0; f < 6; f++) { for (i = 0; i < DIM; i++) { for (j = 0; j < DIM; j++) { p = (j * DIM + i) * 4; r = vec3_magnitude(&vertex[f][i][j]); r = (r - min) / (max - min); c = (unsigned char) (r * 255.0f); output_image[f][p + 0] = c; output_image[f][p + 1] = c; output_image[f][p + 2] = c; output_image[f][p + 3] = 255; } } } }
static void find_min_max_height(float *min, float *max) { int f, i, j; float mmin, mmax; float h; printf("Finding min and max height\n"); mmin = 1000000.0f; mmax = 0.0f; for (f = 0; f < 6; f++) { for (i = 0; i < DIM; i++) { for (j = 0; j < DIM; j++) { h = vec3_magnitude(&vertex[f][i][j]); if (h < mmin) mmin = h; if (h > mmax) mmax = h; } } } *min = mmin; *max = mmax; }