matrix_4x4 m44_view_look_at(vector3 position, vector3 target, vector3 up) { /* Taken From: http://www.opengl.org/wiki/GluLookAt_code */ vector3 zaxis = v3_normalize( v3_sub(target, position) ); vector3 xaxis = v3_normalize( v3_cross(up, zaxis) ); vector3 yaxis = v3_cross(zaxis, xaxis); matrix_4x4 view_matrix = m44_id(); view_matrix.xx = xaxis.x; view_matrix.xy = xaxis.y; view_matrix.xz = xaxis.z; view_matrix.yx = yaxis.x; view_matrix.yy = yaxis.y; view_matrix.yz = yaxis.z; view_matrix.zx = -zaxis.x; view_matrix.zy = -zaxis.y; view_matrix.zz = -zaxis.z; // Also unsure of this. view_matrix = m44_mul_m44(view_matrix, m44_translation(v3_neg(position)) ); return view_matrix; }
mat4_t mat4_look_at(v3_t eye, v3_t center, v3_t up) { v3_t fwd = { center.x - eye.x, center.y - eye.y, center.z - eye.z }; fwd = v3_normalize(fwd); v3_t right = v3_normalize(v3_cross(fwd, up)); up = v3_normalize(v3_cross(right, fwd)); mat4_t v; v.m11 = right.x; v.m12 = right.y; v.m13 = right.z; v.m14 = -v3_scalar(right, eye); v.m21 = up.x; v.m22 = up.y; v.m23 = up.z; v.m24 = -v3_scalar(up, eye); v.m31 = -fwd.x; v.m32 = -fwd.y; v.m33 = -fwd.z; v.m34 = v3_scalar(fwd, eye); v.m41 = 0.f; v.m42 = 0.f; v.m43 = 0.f; v.m44 = 1.f; return v; }
int triangle_intersects(const triangle_t *triangle, const ray_t *ray, intersection_t *result) { const v3_t* edge1; const v3_t* edge2; v3_t tvec; v3_t pvec; v3_t qvec; float det; float inv_det; float t; float u; float v; result->hit = 0; //v3_sub(&edge1, &triangle->pt2, &triangle->pt1); //v3_sub(&edge2, &triangle->pt3, &triangle->pt1); edge1 = &triangle->edge1; edge2 = &triangle->edge2; v3_cross(&pvec, &ray->direction, edge2); det = v3_dot(edge1, &pvec); //No culling version if(det > -EPSILON && det < EPSILON) return 0; inv_det = 1.0f / det; v3_sub(&tvec, &ray->origin, &triangle->v0); u = v3_dot(&tvec, &pvec) * inv_det; if(u < 0.0f || u > 1.0f) return 0; v3_cross(&qvec, &tvec, edge1); v = v3_dot(&ray->direction, &qvec) * inv_det; if(v < 0.0f || u + v > 1.0f + EPSILON) //add EPSILON to offset small precision errors return 0; t = v3_dot(edge2, &qvec) * inv_det; if(t > EPSILON) { result->hit = 1; result->distance = t; return 1; } /* v3_copy(&result->normal, &triangle->normal); v3_copy(&result->hit_point, &r->direction); v3_mul_scalar(&result->hit_point, t); v3_add(&result->hit_point, &result->hit_point, &r->origin); */ return 0; }
t_mat4 m4_look_at(t_vec3 from, t_vec3 to, t_vec3 up) { t_vec3 x; t_vec3 y; t_vec3 z; z = v3_muls(v3_norm(v3_sub(to, from)), -1); x = v3_norm(v3_cross(up, z)); y = v3_cross(z, x); return (mat4( x.x, x.y, x.z, -v3_dot(from, x), y.x, y.y, y.z, -v3_dot(from, y), z.x, z.y, z.z, -v3_dot(from, z), 0, 0, 0, 1 )); }
Color bump_map(void *info, Vector3 t, Vector3 n, Vector3 ds, Vector3 dt) { TextureSrc *src = info; Real h = 0.0005; Real fo = texture_c1((*src->texfunc)(src->texdata, t)); Real fu = texture_c1((*src->texfunc)(src->texdata, v3_add(t,v3_make(h,0,0)))); Real fv = texture_c1((*src->texfunc)(src->texdata, v3_add(t,v3_make(0,h,0)))); Real du = fderiv(fo, fu, h); Real dv = fderiv(fo, fv, h); Vector3 u = v3_scale(du, v3_cross(n, dt)); Vector3 v = v3_scale(-dv, v3_cross(n, ds)); return v3_add(u, v); }
void triangle_update(triangle_t* triangle) { v3_sub(&triangle->edge1, &triangle->v1, &triangle->v0); v3_sub(&triangle->edge2, &triangle->v2, &triangle->v0); v3_cross(&triangle->normal, &triangle->edge1, &triangle->edge2); v3_normalize(&triangle->normal); }
void scotland_update() { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); static_object* skydome = entity_get("skydome"); landscape* world = entity_get("world"); sun_orbit += frame_time() * 0.01; sun->position.x = 512 + sin(sun_orbit) * 512; sun->position.y = cos(sun_orbit) * 512; sun->position.z = 512; sun->target = v3(512, 0, 512); if (w_held || s_held) { vector3 cam_dir = v3_normalize(v3_sub(cam->target, cam->position)); float speed = 0.5; if (!freecam) speed = 0.05; if (w_held) { cam->position = v3_add(cam->position, v3_mul(cam_dir, speed)); } if (s_held) { cam->position = v3_sub(cam->position, v3_mul(cam_dir, speed)); } if (!freecam) { float height = terrain_height(world->terrain, v2(cam->position.x, cam->position.z)); cam->position.y = height + 1; } cam->target = v3_add(cam->position, cam_dir); } Uint8 keystate = SDL_GetMouseState(NULL, NULL); if(keystate & SDL_BUTTON(1)){ float a1 = -(float)mouse_x * 0.005; float a2 = (float)mouse_y * 0.005; vector3 cam_dir = v3_normalize(v3_sub(cam->target, cam->position)); cam_dir.y += -a2; vector3 side_dir = v3_normalize(v3_cross(cam_dir, v3(0,1,0))); cam_dir = v3_add(cam_dir, v3_mul(side_dir, -a1)); cam_dir = v3_normalize(cam_dir); cam->target = v3_add(cam->position, cam_dir); } mouse_x = 0; mouse_y = 0; ui_button* framerate = ui_elem_get("framerate"); ui_button_set_label(framerate, frame_rate_string()); }
void makeviewVi(void) { Vector3 n,u,v,t; n = view->normal; v = v3_sub(view->up, v3_scale(v3_dot(view->up, n), n)); if (v3_norm(v) < ROUNDOFF) error("view up parallel to view normal"); v = v3_unit(v); u = v3_cross(n, v); v = v3_cross(u, n); n = v3_scale(-1.0, n); t = view->center; view->Vinv = m4_ident(); view->Vinv.r1.x = u.x; view->Vinv.r2.x = u.y; view->Vinv.r3.x = u.z; view->Vinv.r1.y = v.x; view->Vinv.r2.y = v.y; view->Vinv.r3.y = v.z; view->Vinv.r1.z = n.x; view->Vinv.r2.z = n.y; view->Vinv.r3.z = n.z; view->Vinv.r1.w = t.x; view->Vinv.r2.w = t.y; view->Vinv.r3.w = t.z; }
void sea_update() { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); wave_time += frame_time(); static_object* corvette = entity_get("corvette"); corvette->position.y = (sin(wave_time) + 1) / 2; corvette->rotation = v4_quaternion_pitch(sin(wave_time * 1.123) / 50); corvette->rotation = v4_quaternion_mul(corvette->rotation, v4_quaternion_yaw(sin(wave_time * 1.254) / 25)); corvette->rotation = v4_quaternion_mul(corvette->rotation, v4_quaternion_roll(sin(wave_time * 1.355) / 100)); static_object* center_sphere = entity_get("center_sphere"); physics_object* balls[100]; int num_balls; entities_get(balls, &num_balls, physics_object); for(int i = 0; i < num_balls; i++) { physics_object_collide_static(balls[i], center_sphere, frame_time()); physics_object_collide_static(balls[i], corvette, frame_time()); physics_object_update(balls[i], frame_time()); } Uint8 keystate = SDL_GetMouseState(NULL, NULL); if(keystate & SDL_BUTTON(1)) { float a1 = -(float)mouse_x * 0.01; float a2 = (float)mouse_y * 0.01; cam->position = v3_sub(cam->position, cam->target); cam->position = m33_mul_v3(m33_rotation_y( a1 ), cam->position ); cam->position = v3_add(cam->position, cam->target); cam->position = v3_sub(cam->position, cam->target); vector3 rotation_axis = v3_normalize(v3_cross( v3_sub(cam->position, v3_zero()) , v3(0,1,0) )); cam->position = m33_mul_v3(m33_rotation_axis_angle(rotation_axis, a2 ), cam->position ); cam->position = v3_add(cam->position, cam->target); } if(keystate & SDL_BUTTON(3)) { sun->position.x += (float)mouse_y / 2; sun->position.z -= (float)mouse_x / 2; } mouse_x = 0; mouse_y = 0; ui_button* framerate = ui_elem_get("framerate"); ui_button_set_label(framerate, frame_rate_string()); }
void metaballs_update() { camera* cam = entity_get("camera"); light* sun = entity_get("sun"); Uint8 keystate = SDL_GetMouseState(NULL, NULL); if(keystate & SDL_BUTTON(1)){ float a1 = -(float)mouse_x * frame_time() * 0.25; float a2 = (float)mouse_y * frame_time() * 0.25; cam->position = v3_sub(cam->position, cam->target); cam->position = m33_mul_v3(m33_rotation_y( a1 ), cam->position ); cam->position = v3_add(cam->position, cam->target); cam->position = v3_sub(cam->position, cam->target); vector3 rotation_axis = v3_normalize(v3_cross( v3_sub(cam->position, v3_zero()) , v3(0,1,0) )); cam->position = m33_mul_v3(m33_rotation_axis_angle(rotation_axis, a2 ), cam->position ); cam->position = v3_add(cam->position, cam->target); } if(keystate & SDL_BUTTON(3)){ sun->position.x += (float)mouse_y / 2; sun->position.z -= (float)mouse_x / 2; } mouse_x = 0; mouse_y = 0; particles_update(frame_time()); ui_button* framerate = ui_elem_get("framerate"); ui_button_set_label(framerate, frame_rate_string()); #ifdef MARCHING_CUBES marching_cubes_metaball_data( particle_positions_memory(), particles_count() ); marching_cubes_clear(); marching_cubes_update(); #endif #ifdef VOLUME_RENDERER volume_renderer_metaball_data( particle_positions_memory(), particles_count() ); volume_renderer_update(); #endif }
/* Returns true if the image becomes disconnected under the given * homography */ int img_disconnected_under_homography(img_t *img, double *H) { /* Check if any point in the img maps to infinity under H. This * is true for p if Hp = [x y 0], so if w is the third row of H, * w^T * p = 0. We check if this line intersects the image */ v2_t origin = img->origin; int w = img->w, h = img->h; v3_t line = v3_new(H[6], H[7], H[8]); /* The bottom line is where y = Vy(origin) */ v3_t bottom_line = v3_cross(v3_new(0.0, Vy(origin), 1.0), v3_new(1.0, Vy(origin), 1.0)); v3_t top_line = v3_cross(v3_new(0.0, Vy(origin) + h - 1, 1.0), v3_new(1.0, Vy(origin) + h - 1, 1.0)); v3_t left_line = v3_cross(v3_new(Vx(origin), 0.0, 1.0), v3_new(Vx(origin), 1.0, 1.0)); v3_t right_line = v3_cross(v3_new(Vx(origin) + w - 1, 0.0, 1.0), v3_new(Vx(origin) + w - 1, 1.0, 1.0)); v3_t isect; /* Do four intersection tests */ isect = v3_homogenize(v3_cross(line, bottom_line)); if (Vx(isect) > 0 && Vx(isect) < w - 1) return 1; isect = v3_homogenize(v3_cross(line, top_line)); if (Vx(isect) > 0 && Vx(isect) < w - 1) return 1; isect = v3_homogenize(v3_cross(line, left_line)); if (Vy(isect) > 0 && Vy(isect) < h - 1) return 1; isect = v3_homogenize(v3_cross(line, right_line)); if (Vy(isect) > 0 && Vy(isect) < h - 1) return 1; return 0; }
void display_generate_line(int subDiv, t_v3* min, t_v3* max, float sphere_radius, uint8* vb, t_mesh_definition* def, uint16* ib, uint16 start) { t_v3 direction; t_v3 normal; v3_set(&normal, 0, 0, 1); v3_sub(max, min, &direction); v3_norm(&direction, &direction); v3_cross(&direction, &normal, &normal); normal.x *= sphere_radius; normal.y *= sphere_radius; normal.z *= sphere_radius; float vs[] = { min->x - normal.x, min->y - normal.y, min->z, min->x + normal.x, min->y + normal.y, min->z, max->x - normal.x, max->y - normal.y, max->z, max->x + normal.x, max->y + normal.y, max->z, }; float* vsp = vs; int32 i; for (i = 0; i < 4; ++i) { t_v3* v = (t_v3*)(vb + def->vertex_offset); t_v3* n = (t_v3*)(vb + def->normal_offset); v3_set(v, *vsp, *(vsp + 1), *(vsp + 2)); vsp += 3; if (def->normal_offset != -1) v3_set(n, 0.0f, 0.0f, 1.0f); vb += def->stride; } *ib++ = start + 0; *ib++ = start + 1; *ib++ = start + 3; *ib++ = start + 0; *ib++ = start + 3; *ib++ = start + 2; }
//Computes the angular momentum about the general center of mass void Computation::computeAngularMomentum() { double translation[3], rotation[3]; double R[4][4],Rx[4][4],Ry[4][4],Rz[4][4]; double mean_w[3]; Bone * root; Mass * mass; if(m_pSkeletonList != NULL) { for (int i = 0; i < numOfSkeletons && i < MAX_SKELS; i++) { double transform[4][4]; identity(transform); double r_i_cm[m_pSkeletonList[i]->NUM_BONES_IN_ASF_FILE][3]; //stores previous position of local center of mass in global cs root = m_pSkeletonList[i]->getRoot(); if(m_pMassDistributionList[i] != NULL) { //reset angular momentum m_pSkeletonList[i]->H[0] = 0.; m_pSkeletonList[i]->H[1] = 0.; m_pSkeletonList[i]->H[2] = 0.; //store old local cm in global cs of each bone: for( int k = 0; k < m_pSkeletonList[i]->NUM_BONES_IN_ASF_FILE; k++) { //store previous position of local cm in global cs in r_i_cm r_i_cm[k][0] = m_pSkeletonList[i]->getBone(root, k)->r_i[0]; r_i_cm[k][1] = m_pSkeletonList[i]->getBone(root, k)->r_i[1]; r_i_cm[k][2] = m_pSkeletonList[i]->getBone(root, k)->r_i[2]; } //compute current position of lcm in global cs m_pSkeletonList[i]->GetTranslation(translation); m_pSkeletonList[i]->GetRotationAngle(rotation); //creating Rotation matrix for initial rotation of Skeleton rotationX(Rx, rotation[0]); rotationY(Ry, rotation[1]); rotationZ(Rz, rotation[2]); matrix4_mult(Rz, Ry, R); matrix4_mult(R, Rx, R); matrix4_mult(transform, R, transform); transform[0][3] += (MOCAP_SCALE*translation [0]); transform[1][3] += (MOCAP_SCALE*translation [1]); transform[2][3] += (MOCAP_SCALE*translation [2]); traverse(root, i, transform, 'h'); //TODO delete mean_w[0] = 0; mean_w[1] = 0; mean_w[2] = 0; for(int j = 0; j < m_pSkeletonList[i]->NUM_BONES_IN_ASF_FILE; j++) { //for every bone compute: (r_i - r_cm) x m_i(v_i - v_cm) + I_i*w_i double rel_pos[3], v_i[3], v_cm[3], v_rel[3], I_G[3][3], w_i[3], local_inertia[3], cross[3], S[3][3], S_transpose[3][3]; Bone * bone; bone = m_pSkeletonList[i]->getBone(root, j); if(m_pMassDistributionList[i]->getMass(bone->name) != NULL) { mass = m_pMassDistributionList[i]->getMass(bone->name); //rel_pos = r_i - r_cm rel_pos[0] = bone->r_i[0] - m_pSkeletonList[i]->cm[0]; rel_pos[1] = bone->r_i[1] - m_pSkeletonList[i]->cm[1]; rel_pos[2] = bone->r_i[2] - m_pSkeletonList[i]->cm[2]; //v_i = r_i - r_i_cm v_i[0] = (bone->r_i[0] - r_i_cm[j][0]); v_i[1] = (bone->r_i[1] - r_i_cm[j][1]); v_i[2] = (bone->r_i[2] - r_i_cm[j][2]); //if v_i is zero switch flag checkLegSwing(v_i, bone, i); // if(mass->mass != 0 && ((strcmp(mass->segName, "rfoot") == 0) || (strcmp(mass->segName, "lfoot") == 0))) printf("v_i_%s: %f %f %f\n",mass->segName, v_i[0], v_i[1], v_i[2]); //v_cm = r_cm - r_cm_prev v_cm[0] = (m_pSkeletonList[i]->cm[0] - m_pSkeletonList[i]->cm_prev[0]); v_cm[1] = (m_pSkeletonList[i]->cm[1] - m_pSkeletonList[i]->cm_prev[1]); v_cm[2] = (m_pSkeletonList[i]->cm[2] - m_pSkeletonList[i]->cm_prev[2]); //v_rel = v_i - v_cm v_rel[0] = v_i[0] - v_cm[0]; v_rel[1] = v_i[1] - v_cm[1]; v_rel[2] = v_i[2] - v_cm[2]; //Inertia tensor double Ri[4][4], Ri_transpose[4][4], I_i[4][4]; //rotation from global to local rotationX(Rx, -bone->axis_x); rotationY(Ry, -bone->axis_y); rotationZ(Rz, -bone->axis_z); matrix4_mult(Rz, Ry, Ri); matrix4_mult(Ri, Rx, Ri); matrix4_transpose(Ri, Ri_transpose); I_i[0][0] = mass->Ixx; I_i[0][1] = I_i[1][0] =(-1)*mass->Ixy; I_i[0][2] = I_i[2][0] = (-1)*mass->Ixz; I_i[1][1] = mass->Iyy; I_i[1][2] = I_i[2][1] = (-1)*mass->Iyz; I_i[2][2] = mass->Izz; I_i[0][3] = I_i[1][3] = I_i[2][3] = 0; I_i[3][0] = I_i[3][1] = I_i[3][2] = 0; I_i[3][3] = 1.0; //~I_G = R_i^T * I_i * R_i //~I_G is inertia tensor relative to bone's cm in rotation of global cs. matrix4_mult(Ri_transpose, I_i, I_i); matrix4_mult(I_i, Ri, I_i); //parallel axes theorem // I_G = I_i + m_i * S^T(rel_pos)* S(rel_pos) with S is skew matrix for cross product cross_matrix(rel_pos, S); //works matrix3_transpose(S, S_transpose);//works matrix3_mult(S_transpose, S, S); //works matrix3_scalar_mult(S, mass->mass); //works //copy entries into I_G identity3(I_G); for (int x = 0; x < 3; x++) for (int y = 0; y < 3; y++) I_G[x][y] = I_i[x][y] + S[x][y]; //w_i = R_i^T * ({rx,ry,rz} - {rx_prev, ry_prev, rz_prev}); w_i[0] = (bone->rx - bone->rx_prev); w_i[1] = (bone->ry - bone->ry_prev); w_i[2] = (bone->rz - bone->rz_prev); //clamping if(absolute_value(w_i[0]) > 1.5) w_i[0] = 0; if(absolute_value(w_i[1]) > 1.5) w_i[1] = 0; if(absolute_value(w_i[2]) > 1.5) w_i[2] = 0; mean_w[0] += absolute_value(w_i[0]); mean_w[1] += absolute_value(w_i[1]); mean_w[2] += absolute_value(w_i[2]); vector_rotationXYZ(w_i, bone->axis_x, bone->axis_y, bone->axis_z); //local_inertia = I_i*w_i matrix3_v3_mult(I_G,w_i, local_inertia); //cross = (r_i - r_cm) x m_i(v_i - v_cm) v_rel[0] *= m_pMassDistributionList[i]->getMass(bone->name)->mass; v_rel[1] *= m_pMassDistributionList[i]->getMass(bone->name)->mass; v_rel[2] *= m_pMassDistributionList[i]->getMass(bone->name)->mass; v3_cross(rel_pos, v_rel, cross); //H is sum of angular momentum of every bone m_pSkeletonList[i]->H[0] += (cross[0] + local_inertia[0]); m_pSkeletonList[i]->H[1] += (cross[1] + local_inertia[1]); m_pSkeletonList[i]->H[2] += (cross[2] + local_inertia[2]); } //if end }//for bones end setLegSwing(i); mean_w[0] /= m_pSkeletonList[i]->NUM_BONES_IN_ASF_FILE; mean_w[1] /= m_pSkeletonList[i]->NUM_BONES_IN_ASF_FILE; mean_w[2] /= m_pSkeletonList[i]->NUM_BONES_IN_ASF_FILE; //normalization N=M*H*V // to make H dimensionless, divide by subject's height (in m), subject's mass (in kg) and subject's average velocity(0.012 m/frame or 1.44 m/s) double n = m_pSkeletonList[i]->totalMass*m_pSkeletonList[i]->height*(1.44); m_pSkeletonList[i]->H[0] /= n; m_pSkeletonList[i]->H[1] /= n; m_pSkeletonList[i]->H[2] /= n; //printf("mean w values: %f %f %f\n", mean_w[0], mean_w[1], mean_w[2]); //printf("angular momentum: %f %f %f\n", m_pSkeletonList[i]->H[0],m_pSkeletonList[i]->H[1],m_pSkeletonList[i]->H[2]); //printf("position cm: %f %f %f\n", m_pSkeletonList[i]->cm[0], m_pSkeletonList[i]->cm[1], m_pSkeletonList[i]->cm[2]); }//if end }// for Skeletons end } }
/* M A I N */ int main(int argc, char *argv[]) { FILE *starfile; FILE *posnfile; double lat, lon; struct star_rec_str star_rec; /* time, UTC */ struct ymdhms tstar = {PLOTYEAR, PLOTMONTH, PLOTDAY, PLOTHOUR, PLOTMINUTE, PLOTSECOND}; struct starData stardat; double east, north; struct v3_str p0x, p0y; /* vector normal to ceiling */ struct v3_str n; /* compute normal to ceiling */ p0x = px; v3_sub(&p0x, &p0); p0y = py; v3_sub(&p0y, &p0); n = p0x; v3_cross(&n, &p0y); /* read in latitude, longitude */ posnfile = fopen(POSNFILE, "r"); if (posnfile != NULL) { if (read_latlon(posnfile, &lat, &lon) != 0) { lat = DFLT_LAT; lon = DFLT_LON; } fclose(posnfile); } else { lat = DFLT_LAT; lon = DFLT_LON; } #if 1 printf("lat: %f, lon: %f\n", lat, lon); #endif starfile = fopen(STARFILE, "r"); while (read_star(starfile, &star_rec) != -1) { /* dn is anchored in ne corner, ds in se corner */ /* * dn is wall measurement using NE anchor point * ds is wall measurement using SE anchor point * N, S walls measured from east side * W wall measured from S side _from_both_anchors_ */ double dn, ds; char wn, ws; /* wall on which line terminates */ double bri; /* brightness of dot (relative to mag 0) */ double dia; /* diameter of dot */ double dist; /* observer to dot distance */ /* unit vector in direction of star, spherical coords */ struct crd_sph_str u_sph; struct v3_str u_crt; /* same in cartesian coords */ /* calculate altitude, azimuth */ /* * note: these calculations don't quite agree with stellarium's. * I suspect it's due to "RA/DE (of date)" calculation * (proper motion) */ ephStarPos(&tstar, lat, lon, star_rec.ra, star_rec.dec, &stardat); #if 0 //printf("\nStar %d:\n", star_rec.hip); //ephStarDump(&stardat); printf("%d,%10.6f,%10.6f\n", star_rec.hip, stardat.az, stardat.alt); #endif /* create unit vector in direction of star */ u_sph.r = 1.0; u_sph.phi = ephDegToRad(ephAltToPhi(stardat.alt)); u_sph.theta = ephDegToRad(ephAzToTheta(stardat.az)); crd_sph2cart(&u_sph, &u_crt); /* distance from origin to dot */ dist = v3_dist_line_plane(&origin, &u_crt, &p0, &n); /* CLEANED UP TO HERE */ /* skip stars too low (or below horizon) */ if (stardat.alt < ALT_MIN) continue; /* * convert to cartesian coords: * observer is OBS_TO_CEIL below ceiling * OBS_TO_WALL from middle of east wall */ east = OBS_TO_CEIL * ephSin(stardat.az) / ephTan(stardat.alt); north = OBS_TO_CEIL * ephCos(stardat.az) / ephTan(stardat.alt); east -= OBS_TO_WALL; /* skip those not on ceiling */ if ((north > ROOM_NS / 2.0) || (north < -ROOM_NS / 2.0) || (east > 0) || (east < -ROOM_EW)) continue; #if 0 printf("%d %6.1f %6.1f %5.2f\n", star_rec.hip, east, north, star_rec.vmag); #endif if (-east / (ROOM_NS / 2.0 - north) <= ROOM_EW / ROOM_NS) { dn = -east * ROOM_NS / (ROOM_NS / 2.0 - north); wn = 's'; } else { dn = ROOM_NS - ROOM_EW * (ROOM_NS / 2.0 - north) / -east; wn = 'W'; } if (-east / (ROOM_NS / 2.0 + north) <= ROOM_EW / ROOM_NS) { ds = -east * ROOM_NS / (ROOM_NS / 2.0 + north); ws = 'n'; } else { ds = ROOM_EW * (ROOM_NS / 2.0 + north) / -east; ws = 'W'; } /* brightness ratio, relative to mag 0: m = -2.5log_10(F/F0) */ /* this could be more accurate: 5th root of 100 */ /* see Wikipedia: apparent magnitude */ bri = pow(10.0, star_rec.vmag / -2.5); /* compensate for distance from observer to dot */ bri *= dist * dist / (OBS_TO_CEIL * OBS_TO_CEIL); /* compensate for view angle */ bri /= ephSin(stardat.alt); /* brightness proportional to square of diameter */ dia = DIA_0 * sqrt(bri); #if 1 printf("%6d %5.2f %010.6f %09.6f %6.1f %6.1f %05.1f %c %05.1f %c %4.1f 0\n", star_rec.hip, star_rec.vmag, stardat.az, stardat.alt, east, north, dn, wn, ds, ws, dia); #endif } fclose(starfile); exit(0); }
void GLWidget::keyPressEvent(QKeyEvent *event) { Matrix4 M; Vector3 Dir; switch (event->key()) { case Qt::Key_Q: case Qt::Key_A: M = m4_rotate('y', 0.5); scene->view->center = v3_m4mult(scene->view->center,M); scene->view->normal = v3_m4mult(scene->view->normal,M); makeviewV(); setview(scene->view); break; case Qt::Key_D: M = m4_rotate('y', -0.5); scene->view->center = v3_m4mult(scene->view->center,M); scene->view->normal = v3_m4mult(scene->view->normal,M); makeviewV(); setview(scene->view); break; case Qt::Key_W: M = m4_rotate('x', 0.5); scene->view->center = v3_m4mult(scene->view->center,M); scene->view->up = v3_m4mult(scene->view->up,M); scene->view->normal = v3_m4mult(scene->view->normal,M); makeviewV(); setview(scene->view); break; case Qt::Key_S: M = m4_rotate('x', -0.5); scene->view->center = v3_m4mult(scene->view->center,M); scene->view->up = v3_m4mult(scene->view->up,M); scene->view->normal = v3_m4mult(scene->view->normal,M); makeviewV(); setview(scene->view); break; case Qt::Key_Left: Dir = v3_cross(scene->view->up,scene->view->normal); scene->view->center = v3_add(scene->view->center,v3_scale(0.5,Dir)); makeviewV(); setview(scene->view); break; case Qt::Key_Right: Dir = v3_cross(scene->view->up,scene->view->normal); scene->view->center = v3_sub(scene->view->center,v3_scale(0.5,Dir)); makeviewV(); setview(scene->view); break; case Qt::Key_Up: scene->view->center = v3_add(scene->view->center,v3_scale(0.5,scene->view->up)); makeviewV(); setview(scene->view); break; case Qt::Key_Down: scene->view->center = v3_sub(scene->view->center,v3_scale(0.5,scene->view->up)); makeviewV(); setview(scene->view); break; case Qt::Key_Escape: exit(0); break; case Qt::Key_R: if (!lastfile.isEmpty()) load_scene_file(lastfile.toLatin1().data()); break; } update(); }
void camera_setup( camera_t * const c, v3_t eye, v3_t lookat, v3_t up, float fov ) { // compute the basis for the camera // negative look direction from eye to destination v3_t w = v3_norm(v3_sub(eye, lookat)); // compute the side axis v3_t u = v3_norm(v3_cross(up, w)); // and the "up" normal v3_t v = v3_norm(v3_cross(w, u)); m44_t cam = {{ { u.p[0], u.p[1], u.p[2], -v3_dot(u,eye) }, { v.p[0], v.p[1], v.p[2], -v3_dot(v,eye) }, { w.p[0], w.p[1], w.p[2], -v3_dot(w,eye) }, { 0, 0, 0, 1 }, }}; fprintf(stderr, "Camera:\n"); for(int i = 0 ; i < 4 ; i++) { for(int j = 0 ; j < 4 ; j++) fprintf(stderr, " %+5.3f", cam.m[i][j]); fprintf(stderr, "\n"); } // now compute the perspective projection matrix if(1) { float s = 1000.0 / tan(fov * M_PI / 180 / 2); c->near = 1; c->far = 200; float f1 = - c->far / (c->far - c->near); float f2 = - c->far * c->near / (c->far - c->near); m44_t pers = {{ { s, 0, 0, 0 }, { 0, s, 0, 0 }, { 0, 0, f2, -1 }, { 0, 0, f1, 0 }, }}; fprintf(stderr, "Perspective:\n"); for(int i = 0 ; i < 4 ; i++) { for(int j = 0 ; j < 4 ; j++) fprintf(stderr, " %+5.3f", pers.m[i][j]); fprintf(stderr, "\n"); } m44_mult(&c->r, &pers, &cam); } else { // no perspective m44_t pers = {{ { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, }}; // and apply it to the camera matrix to generate transform m44_mult(&c->r, &pers, &cam); } fprintf(stderr, "Cam*Pers\n"); for(int i = 0 ; i < 4 ; i++) { for(int j = 0 ; j < 4 ; j++) fprintf(stderr, " %+5.3f", c->r.m[i][j]); fprintf(stderr, "\n"); } }