static int main_da_motion_notify(int x, int y) { float cx, cy, lx, ly; union vec3 v1, v2; union quat rotation; if (!isDragging) { lastcount = 0; } else { if (lastcount < MOUSE_HISTORY) { last++; lastx[last % MOUSE_HISTORY] = 2.0 * (((float) x / (float) real_screen_width) - 0.5); lasty[last % MOUSE_HISTORY] = 2.0 * (((float) y / (float) real_screen_height) - 0.5); lastcount++; return 0; } lastcount++; lx = lastx[(last + 1) % MOUSE_HISTORY]; ly = lasty[(last + 1) % MOUSE_HISTORY]; last = (last + 1) % MOUSE_HISTORY; cx = 2.0 * (((float) x / (float) real_screen_width) - 0.5); cy = 2.0 * (((float) y / (float) real_screen_height) - 0.5); lastx[last] = cx; lasty[last] = cy; v1.v.z = 0; v1.v.y = 0; v1.v.x = -1.0; v2.v.z = cx - lx; v2.v.y = cy - ly; v2.v.x = -1.0; quat_from_u2v(&rotation, &v1, &v2, 0); if (isDraggingLight) { quat_mul(&light_orientation, &rotation, &last_light_orientation); last_light_orientation = light_orientation; } else { quat_mul(&lobby_orientation, &rotation, &last_lobby_orientation); last_lobby_orientation = lobby_orientation; v2.v.z /= 3.0; v2.v.y /= 3.0; quat_from_u2v(&autorotation, &v1, &v2, 0); autospin_initialized = 1; } } return 0; }
static void add_crater(int i, union vec3 p, float r, float h) { struct bump *b; const union vec3 right_at_ya = { { 0.0f, 0.0f, 1.0f } }; const union vec3 up = { { 0.0f, 1.0f, 0.0f } }; float crater_r; b = &craterlist[i]; b->is_crater = 1; b->p = p; b->r = r; b->h = h; b->tx = 512; b->ty = 512; b->ts = 512; b->sampledata = malloc(3 * 1024 * 1024); memset(b->sampledata, crater_base_level, 3 * 1024 * 1024); b->samplew = 1024; b->sampleh = 1024; b->sample_bytes_per_row = 3 * b->samplew; crater_r = (0.5 * (snis_random_float() + 1.0) * 5.5) * (0.5 * (snis_random_float() + 1.0) * 5.5) + 2.5; create_crater_heightmap((unsigned char *) b->sampledata, 1024, 1024, 512, 512, (int) crater_r, 3); quat_from_u2v(&b->texelq, &p, &right_at_ya, &up); }
static void add_bump(union vec3 p, float r, float h) { struct bump *b; const union vec3 right_at_ya = { { 0.0f, 0.0f, 1.0f } }; const union vec3 up = { { 0.0f, 1.0f, 0.0f } }; if (totalbumps >= MAXBUMPS) return; b = &bumplist[totalbumps]; b->p = p; b->r = r; b->h = h; b->tx = (int) ((float) samplew / RADII + 0.5 * snis_random_float() * (RADII - 2.0f) / RADII * (float) samplew); b->ty = (int) ((float) sampleh / RADII + 0.5 * snis_random_float() * (RADII - 2.0f) / RADII * (float) sampleh); if (samplew < sampleh) b->ts = samplew / RADII; else b->ts = sampleh / RADII; b->sampledata = sampledata; b->samplew = samplew; b->sampleh = sampleh; b->sample_bytes_per_row = sample_bytes_per_row; b->is_crater = 0; quat_from_u2v(&b->texelq, &p, &right_at_ya, &up); totalbumps++; }
void quat_decompose_swing_twist(const union quat *q, const union vec3 *v1, union quat *swing, union quat *twist) { union vec3 v2; quat_rot_vec(&v2, v1, q); quat_from_u2v(swing, v1, &v2, 0); union quat swing_inverse; quat_inverse(&swing_inverse, swing); quat_mul(twist, &swing_inverse, q); }