orbit.c (2088B)
1 2 #include "orbit.h" 3 #include "node.h" 4 #include "vec3.h" 5 #include "mat4.h" 6 #include "quat.h" 7 #include "util.h" 8 #include <math.h> 9 10 float *spherical_to_cartesian(struct spherical *s, float *v3) 11 { 12 float theta = s->inclination; 13 float phi = s->azimuth; 14 15 float sin_theta = sin(theta); 16 float cos_phi = cos(phi); 17 float cos_theta = cos(theta); 18 19 // to cartesian 20 v3[0] = s->radius * sin_theta * cos_phi; 21 v3[1] = s->radius * sin_theta * sin(phi); 22 v3[2] = s->radius * cos_theta; 23 24 return v3; 25 } 26 27 vec3 *spherical_dir(struct spherical s, vec3 *dir) { 28 s.radius = 1.0; 29 spherical_to_cartesian(&s, dir); 30 return dir; 31 } 32 33 // from: in 34 // to: out 35 vec3 *spherical_pos(struct spherical *s, vec3 *from, vec3 *to) { 36 float spherical_offset[3]; 37 spherical_to_cartesian(s, spherical_offset); 38 vec3_add(from, spherical_offset, to); 39 return to; 40 } 41 42 vec3 *spherical_look_at(struct spherical *s, vec3 *target, mat4 *mat) { 43 float eye[3]; 44 45 spherical_pos(s, target, eye); 46 look_at(eye, target, V3(0.0, 0.0, 1.0), mat); 47 return mat; 48 } 49 50 51 static void orbit_node_update(struct node *node) { 52 struct node *parent = get_node(&node->parent_id); 53 54 if (!parent) 55 return; 56 57 float *a = parent->mat; 58 float *b = node->pos; 59 float *dst = node->mat; 60 61 float b30 = b[0], b31 = b[1], b32 = b[2], b33 = 1.0; 62 63 float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; 64 float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; 65 float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; 66 float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; 67 68 69 dst[12] = b30*a00 + b31*a10 + b32*a20 + b33*a30; 70 dst[13] = b30*a01 + b31*a11 + b32*a21 + b33*a31; 71 dst[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32; 72 dst[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33; 73 } 74 75 76 void new_orbit(struct orbit *orbit) { 77 init_id(&orbit->node_id); 78 struct node *node = new_node(&orbit->node_id); 79 node_set_label(node, "orbcam"); 80 /* orbit->node.custom_update = orbit_node_update; */ 81 /* orbit->node.custom_update_data = orbit; */ 82 }