// 设置摄像机 void matrix_set_lookat(matrix_t *m, const vector_t *eye, const vector_t *at, const vector_t *up) { vector_t xaxis, yaxis, zaxis; vector_sub(&zaxis, at, eye); vector_normalize(&zaxis); vector_crossproduct(&xaxis, up, &zaxis); vector_normalize(&xaxis); vector_crossproduct(&yaxis, &zaxis, &xaxis); m->m[0][0] = xaxis.x; m->m[1][0] = xaxis.y; m->m[2][0] = xaxis.z; m->m[3][0] = -vector_dotproduct(&xaxis, eye); m->m[0][1] = yaxis.x; m->m[1][1] = yaxis.y; m->m[2][1] = yaxis.z; m->m[3][1] = -vector_dotproduct(&yaxis, eye); m->m[0][2] = zaxis.x; m->m[1][2] = zaxis.y; m->m[2][2] = zaxis.z; m->m[3][2] = -vector_dotproduct(&zaxis, eye); m->m[0][3] = m->m[1][3] = m->m[2][3] = 0.0f; m->m[3][3] = 1.0f; }
t_bool intersect_cone(t_ray ray, t_cone *obj, float *t) { float a; float b; float c; float tmp; t_vector3 ec; ec = vector_substract(ray.pos, obj->pos); tmp = (1 + obj->radius * obj->radius); a = vector_dotproduct(ray.dir, ray.dir); a = a - (tmp * SQUARE(vector_dotproduct(ray.dir, obj->dir))); b = vector_dotproduct(ray.dir, obj->dir) * vector_dotproduct(ec, obj->dir); b = 2 * (vector_dotproduct(ray.dir, ec) - b * tmp); c = vector_dotproduct(ec, ec); c -= tmp * SQUARE(vector_dotproduct(ec, obj->dir)); if ((*t = compute_len(a, b, c)) > 0.) { ec = vector_substract(create_intersect(ray, *t), obj->pos); if (obj->height == 0 || obj->dir.x > 0) return (TRUE); else if (obj->height > 0. && vector_dotproduct(obj->dir, ec) > 0.) if ((obj->height / cos(atan(obj->radius)) > vector_magnitude(ec))) return (TRUE); } return (FALSE); }
t_bool intersect_sphere(t_ray ray, t_sphere* obj, float *t) { t_vector3 etoc; float radius; float vector_radius; etoc = vector_substract(obj->pos, ray.pos); if ((vector_radius = vector_dotproduct(etoc, ray.dir)) < 0.) return (FALSE); *t = vector_dotproduct(etoc, etoc) - SQUARE(vector_radius); if (*t > (radius = SQUARE(obj->radius))) return (FALSE); *t = sqrt(radius - *t); *t = FT_MIN((vector_radius - *t), (vector_radius + *t)); return (TRUE); }
t_ray create_reflection(t_ray ray, t_intersect inter) { t_ray newray; t_vector3 norm; norm = inter.v_normal; newray.dir = vector_substract(ray.dir, vector_mul(norm, 2.0f * vector_dotproduct(ray.dir, norm))); newray.pos = inter.pos; return (newray); }
t_bool intersect_triangle(t_ray ray, t_triangle *obj, float *out) { t_tri tri; tri.e1 = vector_substract(obj->pos2, obj->pos); tri.e2 = vector_substract(obj->pos3, obj->pos); tri.p = vector_product(ray.dir, tri.e2); tri.det = vector_dotproduct(tri.e1, tri.p); if (tri.det > -1e-4f && tri.det < 1e-4f) return (FALSE); tri.det = 1.f / tri.det; tri.t = vector_substract(ray.pos, obj->pos); tri.u = vector_dotproduct(tri.t, tri.p) * tri.det; if (tri.u < 0. || tri.u > 1.) return (FALSE); tri.q = vector_product(tri.t, tri.e1); tri.v = vector_dotproduct(ray.dir, tri.q) * tri.det; if (tri.v < 0. || (tri.u + tri.v) > 1.) return (FALSE); *out = vector_dotproduct(tri.e2, tri.q) * tri.det; if (*out > 1e-4f) return (TRUE); return (FALSE); }
void matrix_from_vectors (VECTOR direction, VECTOR upvect, MATRIX *m) { VECTOR w; VECTOR v,u; float lambda; v = direction; u = upvect; vector_normalize( &v ); lambda = vector_dotproduct( u,v ); u.x -= lambda*v.x; u.y -= lambda*v.y; u.z -= lambda*v.z; vector_normalize( &u ); w = vector_crossproduct( v,u ); m->el[0][0] = w.x; m->el[0][1] = w.y; m->el[0][2] = w.z; m->el[1][0] = u.x; m->el[1][1] = u.y; m->el[1][2] = u.z; m->el[2][0] = v.x; m->el[2][1] = v.y; m->el[2][2] = v.z; };
t_bool intersect_cylinder(t_ray ray, t_cylinder* obj, float *t) { float a; float b; float c; float d; t_vector3 x; a = vector_dotproduct(ray.dir, ray.dir) - SQUARE(vector_dotproduct(ray.dir, obj->dir)); x = vector_substract(ray.pos, obj->pos); b = (vector_dotproduct(ray.dir, x) - vector_dotproduct(ray.dir, obj->dir) * vector_dotproduct(x, obj->dir))* 2; c = vector_dotproduct(x, x) - SQUARE(vector_dotproduct(x, obj->dir)) - (obj->radius * obj->radius); d = b * b - 4 * a * c; if (d > 0.) { if (((-b - sqrt(d)) / (2 * a)) > 0) *t = (-b - sqrt(d)) / (2 * a); else *t = (-b + sqrt(d)) / (2 * a); return (TRUE); } return (FALSE); }