void calc_torque(struct vec3 *dst, const struct vec3 *v1, const struct vec3 *v2, float torque, float min_adjust, float t) { struct vec3 line, dir; float orig_dist, torque_dist, adjust_dist; if (vec3_close(v1, v2, EPSILON)) { vec3_copy(dst, v1); return; } vec3_sub(&line, v2, v1); orig_dist = vec3_len(&line); vec3_mulf(&dir, &line, 1.0f/orig_dist); torque_dist = orig_dist*torque; /* use distance to determine speed */ if (torque_dist < min_adjust) /* prevent from going too slow */ torque_dist = min_adjust; adjust_dist = torque_dist*t; if (adjust_dist <= (orig_dist-LARGE_EPSILON)) { vec3_mulf(dst, &dir, adjust_dist); vec3_add(dst, dst, v1); /* add torque */ } else { vec3_copy(dst, v2); /* clamp if overshoot */ } }
/* calculate sphere that goes through 4 points */ struct sphere* sphere_circum(struct sphere* rs, const struct vec4f* v0, const struct vec4f* v1, const struct vec4f* v2, const struct vec4f* v3) { struct vec4f a; vec3_sub(&a, v1, v0); struct vec4f b; vec3_sub(&b, v2, v0); struct vec4f c; vec3_sub(&c, v3, v0); struct vec4f o; struct vec4f tmp; struct mat3f m; mat3_setf(&m, a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, 0.0f, 0.0f, 0.0f); float denom = 2.0f * mat3_det(&m); vec3_muls(&o, vec3_cross(&tmp, &a, &b), vec3_dot(&c, &c)); vec3_add(&o, &o, vec3_muls(&tmp, vec3_cross(&tmp, &c, &a), vec3_dot(&b, &b))); vec3_add(&o, &o, vec3_muls(&tmp, vec3_cross(&tmp, &b, &c), vec3_dot(&a, &a))); vec3_muls(&o, &o, 1.0f/denom); return sphere_setf(rs, v0->x + o.x, v0->y + o.y, v0->z + o.z, vec3_len(&o) + EPSILON); }
inline void bsp_split_polygon_edge_with_plane(const vertex_t* src, const vertex_t* dest, const vec3_t normal, vec_t dist, bool* split, vertex_t* r, vec_t* t) { vec3_t edge, dir; vec_t len; vec3_sub(edge, dest->coords, src->coords); len = vec3_len(edge); vec3_scale(dir, edge, 1 / len); tr_trace_vs_plane(src->coords, dir, normal, dist, r->coords, t); if(fabs(*t) > len) { *split = false; return; } vec3_t sn, dn; vec3_scale(dn, dest->normal, (*t) / len); vec3_scale(sn, src->normal, (len - (*t)) / len); vec3_add(r->normal, sn, dn); vec3_normalize(r->normal, r->normal); *split = true; }
t_vec3 vec3_normal(t_vec3 vec) { float len; len = vec3_len(vec); return (vec3(vec.x / len, vec.y / len, vec.z / len)); }
// Utility function for vol_draw_mandel_box (). double _vol_draw_mandel_box_equation (double *v, double s, double r, double f, double *c) { //printf ("TEST %lf %lf %lf: %lf %lf %lf, %lf %lf %lf\n", v[0], v[1], v[2], s, r, f, c[0], c[1], c[2]); vec3_clone (fold, v); int i; for (i = 0; i < 3; i++) { if (fold[i] > 1) fold[i] = (double) 2.0 - fold[i]; else if (fold[i] < -1) fold[i] = (double) -2.0 - fold[i]; } vec3_s_mul (fold, f); double m = vec3_len (fold); if (m < r) { vec3_s_mul (fold, 4); } else if (m < 1) { vec3_s_div (fold, m * m); } vec3_assign (v, fold); vec3_s_mul (v, s); vec3_add (v, c); return vec3_len (v); }
static void get_lum(double *col, t_scene *s, t_intersect *inter, int m) { t_vec3 l; t_vec3 r; double ln; int i; double is; double id; double dist; double rv; double tmp; t_ray ray; t_intersect shadow; i = -1; if (s->lights[m].light.type == DIRECTIONNAL) { while (++i < 3) { ln = dot_vec3(inter->norm, s->lights[m].light.dir); col[i] = MAX(ln, 0) * s->lights[m].light.color.argb[i] / 255.0 * s->lights[m].light.power; } return ; } l = sub_vec3(s->lights[m].pos, inter->pos); dist = vec3_len(l); l = div_vec3(l, dist); dist -= s->lights[m].light.radius; ln = dot_vec3(l, inter->norm); ln = MAX(ln, 0.0); r = vec3_normalize(sub_vec3(mult_vec3(inter->norm, 2 * ln), l)); is = s->lights[m].light.power / dist; id = s->lights[m].light.radius * is; rv = -dot_vec3(r, inter->dir); rv = MAX(rv, 0.0); ray.pos = add_vec3(inter->pos, mult_vec3(inter->norm, 0.00001)); ray.dir = l; ray.env = NULL; scene_intersect(s, &ray, &shadow); if (shadow.dist < dist - 0.0001) return ; while (++i < 3) { tmp = inter->mat->diffuse * MAX(ln, 0) * id * s->lights[m].light.color.argb[i] / 255.0; col[i] += MAX(tmp, 0); tmp = inter->mat->specular * pow(rv, inter->mat->shininess) * is * s->lights[m].light.color.argb[i] / 255.0; col[i] += MAX(tmp, 0); } }
void cart_to_polar(struct vec3 *dst, const struct vec3 *v) { struct vec3 polar; polar.z = vec3_len(v); if (close_float(polar.z, 0.0f, EPSILON)) { vec3_zero(&polar); } else { polar.x = asinf(v->y / polar.z); polar.y = atan2f(v->x, v->z); } vec3_copy(dst, &polar); }
bool bounds_intersection_line(const struct bounds *b, const struct vec3 *p1, const struct vec3 *p2, float *t) { struct vec3 dir; float length; vec3_sub(&dir, p2, p1); length = vec3_len(&dir); if (length <= TINY_EPSILON) return false; vec3_mulf(&dir, &dir, 1.0f/length); if (!bounds_intersection_ray(b, p1, &dir, t)) return false; *t /= length; return true; }
void csm_calc_minsphere(struct sphere* bounds, const struct frustum* f, const struct mat3f* view, const struct mat3f* view_inv) { /* reference: * http://www.gamedev.net/topic/604797-minimum-bounding-sphere-of-a-frustum/ */ struct vec3f a; struct vec3f b; struct vec3f p; struct vec3f tmp; vec3_transformsrt(&a, &f->points[1], view); vec3_transformsrt(&b, &f->points[5], view); float z = (vec3_dot(&b, &b) - vec3_dot(&a, &a))/(2.0f*(b.z - a.z)); vec3_setf(&p, 0.0f, 0.0f, z); vec3_transformsrt(&p, &p, view_inv); sphere_setf(bounds, p.x, p.y, p.z, vec3_len(vec3_sub(&tmp, &f->points[5], &p)) + 0.01f); }
void Camera_update(Camera* const camera, Input* const input) { Camera_offset_orientation( camera, toRadians((-input->mouse_dx * input->mouse_sensitivity)), toRadians((-input->mouse_dy * input->mouse_sensitivity)) ); // TODO: Delta time vec3 dir = {0.0f, 0.0f, 0.0f}; float vel = 0.2f; vec3 forward, backward, left, right; Camera_relative_directions(camera, forward, backward, left, right); if (input->forward_key) { vec3 f = {forward[0], 0.0f, forward[2]}; vec3_norm(f, f); vec3_add(dir, dir, f); } if (input->back_key) { vec3 b = {backward[0], 0.0f, backward[2]}; vec3_norm(b, b); vec3_add(dir, dir, b); } if (input->left_key) { vec3_add(dir, dir, left); } if (input->right_key) { vec3_add(dir, dir, right); } if (vec3_len(dir) > 0.0f) { vec3_norm(dir, dir); } vec3 movement; vec3_scale(movement, dir, vel); vec3_add(camera->transform.position, camera->transform.position, movement); }
void vol_draw_fill_sphere (float x, float y, float z, float size) { float cntr = size / 2; vec3_init (center, x + cntr, y + cntr, z + cntr); float j, k, l; for (j = 0; j < size; j++) for (k = 0; k < size; k++) for (l = 0; l < size; l++) { vec3_init (cur, x + j, y + k, z + l); vec3_sub (cur, center); float vlen = vec3_len (cur); float diff = vlen - (cntr - (size / 10)); if (diff < 0) { double sphere_val = (-diff / cntr); vol_draw_op (x + j, y + k, z + l, sphere_val); } } }
static int _llfunc_vec3_len(lua_State *L) { vec3 *v = (vec3*)userdata_get_or_die(L, 1); lua_pushnumber(L, vec3_len(v)); return 1; }
vec3_t vec3_normalize(const vec3_t v) { if (vec3_equal(v, vec3zero)) return vec3zero; else return vec3_div(v, vec3_len(v)); }