void mat_lookatv(Mat *m, const Vec *eye, const Vec *center, const Vec *up) { Vec z; vec_subv(center, eye, &z); vec_norm(&z); Vec up_norm; memcpy(&up_norm, up, sizeof(Vec)); vec_norm(&up_norm); Vec x; vec_cross(&z, &up_norm, &x); vec_norm(&x); Vec y; vec_cross(&x, &z, &y); vec_norm(&y); Mat lookat = {{ x.data[0], x.data[1], x.data[2], 0.0, y.data[0], y.data[1], y.data[2], 0.0, -z.data[0], -z.data[1], -z.data[2], 0.0, 0, 0, 0, 1 }}; mat_translate(&lookat, -eye->data[0], -eye->data[1], -eye->data[2]); memcpy(m, &lookat, sizeof(Mat)); }
/* skew_midpoint() finds the middle of the minimal distance segment between skew rays. Undefined for parallel rays. Reference for algorithm: docs/skew_midpoint.pdf Arguments: vec3d vert1, direct1 - vertex and direction unit vector of one ray. vec3d vert2, direct2 - vertex and direction unit vector of other ray. vec3d res - output buffer for midpoint result. Returns: The minimal distance between the skew lines. */ double skew_midpoint(vec3d vert1, vec3d direct1, vec3d vert2, vec3d direct2, vec3d res) { vec3d perp_both, sp_diff, on1, on2, temp; double scale; /* vector between starting points */ vec_subt(vert2, vert1, sp_diff); /* The shortest distance is on a line perpendicular to both rays. */ vec_cross(direct1, direct2, perp_both); scale = vec_dot(perp_both, perp_both); /* position along each ray */ vec_cross(sp_diff, direct2, temp); vec_scalar_mul(direct1, vec_dot(perp_both, temp)/scale, temp); vec_add(vert1, temp, on1); vec_cross(sp_diff, direct1, temp); vec_scalar_mul(direct2, vec_dot(perp_both, temp)/scale, temp); vec_add(vert2, temp, on2); /* Distance: */ scale = vec_diff_norm(on1, on2); /* Average */ vec_add(on1, on2, res); vec_scalar_mul(res, 0.5, res); return scale; }
END_TEST START_TEST(test_cross) { vec3d v1 = {1., 0., 0.}, v2 = {0., 1., 0.}, res = {0., 0., 1.}, out; vec_cross(v1, v2, out); fail_unless(vec_cmp(out, res)); /* parallel vectors cross = 0 */ res[2] = 0; vec_cross(v1, v1, out); fail_unless(vec_cmp(out, res)); }
triangle_t triangle_new3(point_t a, point_t b, point_t c, material_t material) { triangle_t triangle; triangle.points[0] = a; triangle.points[1] = b; triangle.points[2] = c; triangle.material = material; triangle.normal = vec_normalize(vec_cross(point_direction(a, b), point_direction(a, c))); return triangle; }
/** * m Model matrix * x Return x in model space * y Return y in model space * p Mouse pointer at camera z plane * dir Mouse pointer direction vector */ int glw_widget_unproject(Mtx m, float *xp, float *yp, const float *p, const float *dir) { Vector u, v, n, w0, T0, T1, T2, out, I; float b, inv[16]; glw_mtx_mul_vec(T0, m, -1, -1, 0); glw_mtx_mul_vec(T1, m, 1, -1, 0); glw_mtx_mul_vec(T2, m, 1, 1, 0); vec_sub(u, T1, T0); vec_sub(v, T2, T0); vec_cross(n, u, v); vec_sub(w0, p, T0); b = vec_dot(n, dir); if(fabs(b) < 0.000001) return 0; vec_addmul(I, p, dir, -vec_dot(n, w0) / b); if(!glw_mtx_invert(inv, m)) return 0; glw_mtx_mul_vec(out, inv, I[0], I[1], I[2]); *xp = out[0]; *yp = out[1]; return 1; }
void Window::setUpCamera() { //camera setup GLfloat eyeMinusLook[3] = { look[0], look[1], look[2] }; GLfloat eyePlusOffset[3] = { eye[0]+eyeoffset[0], eye[1]+eyeoffset[1], eye[2] }; vec_normalize( eyeMinusLook ); float u[3], v[3]; vec_cross(u, up, eyeMinusLook); vec_normalize(u); vec_cross(v, eyeMinusLook, u); float cam_mat[] = { u[0], v[0], eyeMinusLook[0], 0, u[1], v[1], eyeMinusLook[1], 0, u[2], v[2], eyeMinusLook[2], 0, -dot(u, eyePlusOffset), -dot(v, eyePlusOffset), -dot(eyeMinusLook, eyePlusOffset), 1 }; for(int i = 0; i < 16; i++) { v_matrix[i] = cam_mat[i]; } }
void Window::moveRight() { float right[3]; vec_cross(right, up, look); vec_normalize(right); eye[0] += (right[0] * STEPSIZE); eye[1] += (right[1] * STEPSIZE); eye[2] += (right[2] * STEPSIZE); setUpCamera(); }
void Window::moveLeft() { float left[3]; vec_cross(left, look, up); vec_normalize(left); eye[0] += (left[0] * STEPSIZE); eye[1] += (left[1] * STEPSIZE); eye[2] += (left[2] * STEPSIZE); setUpCamera(); }
bool intersects(hit<T>& h, const ray<T>& r, const Triangle<T>& tri) { return intersects_moller_trumbore(h, r, tri); h.intersects = false; const vector3<T>& v1 = tri.vertices[1] - tri.vertices[0]; const vector3<T>& v2 = tri.vertices[2] - tri.vertices[0]; vector3<T> normal = vec_cross(v1, v2); // backface culling if (vec_dot(normal.normalized(), r.direction) >= -fp_epsilon) return false; T area = normal.magnitude(); T t = (vec_dot(tri.vertices[0], normal) - vec_dot(r.origin, normal)) / vec_dot(r.direction, normal); if (t < 0.0f) return false; h.point = r.origin + t * r.direction; h.distance = t; // now we check that res is inside the triangle vec3 resv0 = h.point - tri.vertices[0]; vec3 v1v0 = v1; vector3<T> subtri_normal = vec_cross(v1v0, resv0); T u = subtri_normal.magnitude() / area; if (vec_dot(normal, subtri_normal) < -fp_epsilon) return false; if (u < 0.0f || u > 1.0f) return false; vec3 v2v1 = tri.vertices[2] - tri.vertices[1]; vec3 resv1 = h.point - tri.vertices[1]; subtri_normal = vec_cross(v2v1, resv1); T v = subtri_normal.magnitude() / area; if (vec_dot(normal, subtri_normal) < -fp_epsilon) return false; if (v < 0.0f || v > 1.0f) return false; T w = 1.0f - u - v; vec3 resv2 = h.point - tri.vertices[2]; vec3 v0v2 = tri.vertices[0] - tri.vertices[2]; subtri_normal = vec_cross(v0v2, resv2); if (vec_dot(normal, subtri_normal) < -fp_epsilon) return false; if (w < 0.0f || w > 1.0f) return false; h.intersects = true; h.normal = normal.normalized(); return true; }
void fakephong_texcoords (float *u, float *v, float reflection[3], const float *light, const float *light_updir, float *transformed_z) { float light_sideways[3], light_realup[3]; float xformed_reflect[3]; vec_cross (light_sideways, light, light_updir); vec_normalize (light_sideways, light_sideways); vec_cross (light_realup, light_sideways, light); light_basis[0][0] = light_sideways[0]; light_basis[1][0] = light_sideways[1]; light_basis[2][0] = light_sideways[2]; light_basis[3][0] = 0.0; light_basis[0][1] = light_realup[0]; light_basis[1][1] = light_realup[1]; light_basis[2][1] = light_realup[2]; light_basis[3][1] = 0.0; light_basis[0][2] = light[0]; light_basis[1][2] = light[1]; light_basis[2][2] = light[2]; light_basis[3][2] = 0.0; light_basis[0][3] = 0.0; light_basis[1][3] = 0.0; light_basis[2][3] = 0.0; light_basis[3][3] = 1.0; vec_transform3_fipr (&xformed_reflect[0], &light_basis[0][0], &reflection[0]); *u = xformed_reflect[0] * 0.5 + 0.5; *v = xformed_reflect[1] * 0.5 + 0.5; *transformed_z = xformed_reflect[2]; #if 0 if (*u < 0.4 || *u > 0.6 || *v < 0.4 || *v > 0.6) *transformed_z = -0.01; #endif }
void tri_normal(vec *p1, vec *p2, vec *p3, int rev, vec *out) { if(rev) { vec *tmp = p1; p1 = p3; p3 = tmp; } vec v1,v2; vec_sub(p2,p1,&v1); vec_sub(p3,p1,&v2); vec_cross(&v1,&v2,out); vec_normalize(out,out); }
void quat_from_vec_pair(const Vec3f a, const Vec3f b, Quat q) { Vec4f axis; vec_cross(a,b,axis); float angle; vec_angle(a,b,&angle); if( (fabs(axis[0]) < CUTE_EPSILON && fabs(axis[1]) < CUTE_EPSILON && fabs(axis[2]) < CUTE_EPSILON) || fabs(angle) < CUTE_EPSILON ) { quat_identity(q); } quat_from_axis_angle(axis, angle, q); }
void print_normal(vec *p1, vec *p2, vec *p3, int rev) { if(rev) { vec *tmp = p1; p1 = p3; p3 = tmp; } vec n1; vec v1,v2; vec_sub(p2,p1,&v1); vec_sub(p3,p1,&v2); vec_cross(&v1,&v2,&n1); vec_normalize(&n1,&n1); printf("%f, %f, %f\n", n1.x, n1.y, n1.z); }
void create_carambol_scene( BallsType * balls ) { int i; myvec vdummy; balls->gametype=GAME_CARAMBOL; /* balls */ balls->nr=3; if( balls->ball != NULL ) billard_free( balls->ball ); balls->ball = billard_malloc(sizeof(BallType)*balls->nr); placecarambolballnrs(balls); for(i=0;i<balls->nr;i++){ balls->ball[i].nr=i; } for(i=0;i<balls->nr;i++){ balls->ball[i].m=BALL_M; /* I_kugel = (m.r^2)2/5 = (m.d^2)/10 */ balls->ball[i].I=BALL_M*BALL_D*BALL_D/10.0/**0.01*/; balls->ball[i].d=BALL_D; balls->ball[i].v=vec_xyz(0.0,0.0,0.0); balls->ball[i].w=vec_xyz(0.0,0.0,0.0); balls->ball[i].b[0]=vec_unit(vec_xyz(rand(),rand(),rand())); vdummy=vec_xyz(rand(),rand(),rand()); balls->ball[i].b[1]=vec_unit(vec_diff(vdummy,vec_proj(vdummy,balls->ball[i].b[0]))); balls->ball[i].b[2]=vec_cross(balls->ball[i].b[0],balls->ball[i].b[1]); balls->ball[i].in_game=1; balls->ball[i].in_hole=0; balls->ball[i].soundplayed=0; } /* white ball */ balls->ball[0].r = vec_xyz( TABLE_W/4.0, -TABLE_L/4.0, 0.0 ); balls->ball[1].r = vec_xyz( 0.0, -TABLE_L/4.0, 0.0 ); balls->ball[2].r = vec_xyz( 0.0, +TABLE_L/4.0, 0.0 ); for( i=0 ; i<balls->nr ; i++ ){ balls->ball[i].path=0; balls->ball[i].pathcnt=0; balls->ball[i].pathsize=0; } }
void solid_hard_normals(const struct Solid* solid, float* normals) { log_assert(normals != NULL); if( solid->vertices && solid->indices ) { for( size_t i = 0; i < solid->indices_size; i+=3 ) { size_t a = solid->indices[i+0]; size_t b = solid->indices[i+1]; size_t c = solid->indices[i+2]; Vec4f u; u[0] = solid->vertices[a*3+0] - solid->vertices[b*3+0]; u[1] = solid->vertices[a*3+1] - solid->vertices[b*3+1]; u[2] = solid->vertices[a*3+2] - solid->vertices[b*3+2]; u[3] = 1.0; Vec4f v; v[0] = solid->vertices[a*3+0] - solid->vertices[c*3+0]; v[1] = solid->vertices[a*3+1] - solid->vertices[c*3+1]; v[2] = solid->vertices[a*3+2] - solid->vertices[c*3+2]; v[3] = 1.0; Vec4f normal; vec_cross(u,v,normal); vec_normalize(normal,normal); normals[a*3+0] = normal[0]; normals[a*3+1] = normal[1]; normals[a*3+2] = normal[2]; normals[b*3+0] = normal[0]; normals[b*3+1] = normal[1]; normals[b*3+2] = normal[2]; normals[c*3+0] = normal[0]; normals[c*3+1] = normal[1]; normals[c*3+2] = normal[2]; } } }
void mesh_compute_normals(struct mesh *mesh) { int i, nr_faces; struct idx *idx; buf_resize(mesh->nbuf, buf_len(mesh->vbuf)); memset(mesh->nbuf, 0, buf_len(mesh->nbuf) * sizeof(*mesh->nbuf)); buf_foreach(idx, mesh->ibuf) idx->ni = idx->vi; nr_faces = mesh_face_count(mesh); for (i = 0; i < nr_faces; i++) { int j, nr_verts; nr_verts = mesh_face_vertex_count(mesh, i); for (j = 0; j < nr_verts; j++) { vector u, v, n; float *v0, *v1, *v2, *vn; v0 = mesh_get_vertex(mesh, i, j); v1 = mesh_get_vertex(mesh, i, (j + 1) % nr_verts); v2 = mesh_get_vertex(mesh, i, (j + nr_verts - 1) % nr_verts); vec_sub(u, v1, v0); vec_sub(v, v2, v0); vec_cross(n, u, v); vec_normalize(n, n); vn = mesh_get_normal(mesh, i, j); vec_add(vn, vn, n); } } for (i = 0; i < buf_len(mesh->nbuf); i += 3) { float *n = mesh->nbuf + i; vec_normalize(n, n); } }
tplane_t::tplane_t(FILE *in, model_t *model, int attrmax) : plane_t(in,model,2) { int mask; char name[32]; vec_t projxdir; //parse tiled plane data tplane_parse[0].loc = &xdir; tplane_parse[1].loc = &dims; //tplane_parse[2].loc = &altname; mask = parser(in, tplane_parse, NUM_ATTRS, 2); assert(mask == 3); fscanf(in,"%s",name); fscanf(in, "%s",altname); //ask material_getbyname to return a pointer to the alt background mat altmat = material_getbyname(model,altname); fscanf(in, "%s", name); assert(name[0] == '}'); //project xdir into the plane and make it a unit vector vec_project(&normal, &xdir, &projxdir); vec_unit(&projxdir, &projxdir); //build a rotation matrix that rotates the plane normal //into the z axis and the projected xdir into the x axis vec_copy(&normal, &rot.row[2]); vec_copy(&projxdir, &rot.row[0]); vec_cross(&rot.row[0], &rot.row[2], &rot.row[1]); //copy tiled plane to objtype strcpy(obj_type, "tiled plane"); }
void tracer_prep(raytracer *tracer,mcconfig *cfg){ if(tracer->n==NULL && tracer->m==NULL && tracer->d==NULL){ if(tracer->mesh!=NULL) tracer_build(tracer); else MESH_ERROR("tracer is not associated with a mesh"); }else if(cfg->srctype==stPencil && cfg->dim.x>0){ int eid=cfg->dim.x-1; float3 vecS={0.f}, *nodes=tracer->mesh->node, vecAB, vecAC, vecN; int i,ea,eb,ec; float s=0.f, *bary=&(cfg->bary0.x); int *elems=(int *)(tracer->mesh->elem+eid); // convert int4* to int* for(i=0;i<4;i++){ ea=elems[out[i][0]]-1; eb=elems[out[i][1]]-1; ec=elems[out[i][2]]-1; vec_diff(&nodes[ea],&nodes[eb],&vecAB); vec_diff(&nodes[ea],&nodes[ec],&vecAC); vec_diff(&nodes[ea],&(cfg->srcpos),&vecS); vec_cross(&vecAB,&vecAC,&vecN); bary[facemap[i]]=-vec_dot(&vecS,&vecN); } if(cfg->debuglevel&dlWeight) fprintf(cfg->flog,"initial bary-centric volumes [%e %e %e %e]\n", bary[0]/6.,bary[1]/6.,bary[2]/6.,bary[3]/6.); for(i=0;i<4;i++){ if(bary[i]<0.f) MESH_ERROR("initial element does not enclose the source!"); s+=bary[i]; } for(i=0;i<4;i++){ bary[i]/=s; if(bary[i]<1e-5f) cfg->dim.y=ifacemap[i]+1; } } }
void palRevoluteLink::Init(palBodyBase *parent, palBodyBase *child, Float x, Float y, Float z, Float axis_x, Float axis_y, Float axis_z) { palLink::Init(parent, child, x, y, z); if (m_pParent && m_pChild) { //Link_rel with the rotation matrix //Link_rel=(link_abs - parent_abs)*R palMatrix4x4 a_PAL = m_pParent->GetLocationMatrix(); palMatrix4x4 b_PAL = m_pChild->GetLocationMatrix(); // Transpose each body's position matrix to get its world-to-body // rotation matrix: palMatrix4x4 a, b; mat_transpose(&a, &a_PAL); // a <- a_PAL' mat_transpose(&b, &b_PAL); // b <- b_PAL' palVector3 link_rel; palVector3 translation; // Compute the position of the link with respect to the parent's // origin, in the parent's coordinate system: palVector3 posVecParent; m_pParent->GetPosition(posVecParent); translation._vec[0] = m_fPosX - posVecParent.x; translation._vec[1] = m_fPosY - posVecParent.y; translation._vec[2] = m_fPosZ - posVecParent.z; //Rotation vec_mat_mul(&link_rel,&a,&translation); m_fRelativePosX = link_rel.x; m_fRelativePosY = link_rel.y; m_fRelativePosZ = link_rel.z; m_pivotA.x = m_fRelativePosX; m_pivotA.y = m_fRelativePosY; m_pivotA.z = m_fRelativePosZ; // Compute the position of the link with respect to the child's // origin, in the child's coordinate system: palVector3 posVecChild; m_pChild->GetPosition(posVecChild); //link relative position with respect to the child //Translation of absolute to relative translation._vec[0] = m_fPosX - posVecChild.x; // first in world coords translation._vec[1] = m_fPosY - posVecChild.y; translation._vec[2] = m_fPosZ - posVecChild.z; vec_mat_mul(&link_rel,&b,&translation); // rotate into child coords m_pivotB.x = link_rel.x; m_pivotB.y = link_rel.y; m_pivotB.z = link_rel.z; //Frames A and B: Bullet method // Define a hinge coordinate system by generating hinge-to-body // transforms for both parent and child bodies. The hinge // coordinate system's +Z axis coincides with the hinge axis, its // +X and +Y axes are perpendicular to the hinge axis, and its // origin is at the hinge's origin. palVector3 axis, m_axisA, m_axisB; vec_set(&axis, axis_x, axis_y, axis_z); vec_mat_mul(&m_axisA, &a, &axis); // axis in parent coords m_fRelativeAxisX = m_axisA.x; m_fRelativeAxisY = m_axisA.y; m_fRelativeAxisZ = m_axisA.z; vec_mat_mul(&m_axisB, &b, &axis); // axis in child coords vec_norm(&m_axisB); // Build m_frameA, which transforms points from hinge coordinates // to parent (body A) coordinates. // Choose basis vectors for the hinge coordinate system wrt parent coords: palVector3 rbAxisA1( 1, 0, 0 ), rbAxisA2; const palVector3 Z_AXIS( 0, 0, 1 ); // XXX debug Float projection = vec_dot( & m_axisA, & Z_AXIS ); if (projection >= 1 - FLOAT_EPSILON) { // The hinge axis coincides with the parent's +Z axis. rbAxisA2 = palVector3( 0, 1, 0 ); } else if (projection <= -1 + FLOAT_EPSILON) { // The hinge axis coincides with the parent's -Z axis. rbAxisA2 = palVector3( 0, -1, 0 ); } else { // The hinge axis crosses the parent's Z axis. vec_cross( & rbAxisA2, & m_axisA, & Z_AXIS ); vec_cross( & rbAxisA1, & rbAxisA2, & m_axisA ); vec_norm( & rbAxisA1 ); vec_norm( & rbAxisA2 ); } vec_norm( & m_axisA ); // Set frameA. Transform m_frameA maps points from hinge coordinate system, // whose +Z axis coincides with the hinge axis, to the parent body's // coordinate system. mat_identity(&m_frameA); mat_set_translation(&m_frameA,m_pivotA.x,m_pivotA.y,m_pivotA.z); // Put the basis vectors in the columns of m_frameA: m_frameA._11 = rbAxisA1.x; m_frameA._12 = rbAxisA1.y; m_frameA._13 = rbAxisA1.z; m_frameA._21 = rbAxisA2.x; m_frameA._22 = rbAxisA2.y; m_frameA._23 = rbAxisA2.z; m_frameA._31 = m_axisA.x; m_frameA._32 = m_axisA.y; m_frameA._33 = m_axisA.z; palVector3 rbAxisB1, rbAxisB2; if (true) { //build frame B, see bullet for algo palQuaternion rArc; q_shortestArc(&rArc,&m_axisA,&m_axisB); vec_q_rotate(&rbAxisB1,&rArc,&rbAxisA1); vec_cross(&rbAxisB2,&m_axisB,&rbAxisB1); } else { palVector3 tmp; vec_mat_mul( &tmp, &a_PAL, &rbAxisA1 ); vec_mat_mul( &rbAxisB1, &b, &tmp ); vec_mat_mul( &tmp, &a_PAL, &rbAxisA2 ); vec_mat_mul( &rbAxisB2, &b, &tmp ); } // Build m_frameB, which transforms points from hinge coordinates // to parent (body A) coordinates. vec_norm(&rbAxisB1); vec_norm(&rbAxisB2); mat_identity(&m_frameB); mat_set_translation(&m_frameB,m_pivotB.x,m_pivotB.y,m_pivotB.z); // Put the basis vectors in the columns of m_frameB: m_frameB._11 = rbAxisB1.x; m_frameB._12 = rbAxisB1.y; m_frameB._13 = rbAxisB1.z; m_frameB._21 = rbAxisB2.x; m_frameB._22 = rbAxisB2.y; m_frameB._23 = rbAxisB2.z; m_frameB._31 = m_axisB.x; m_frameB._32 = m_axisB.y; m_frameB._33 = m_axisB.z; } }
int32_t pivot_lookat(struct Pivot* pivot, const Vec3f target) { int32_t result = -1; Vec4f right_axis = RIGHT_AXIS; Vec4f up_axis = UP_AXIS; Vec4f forward_axis = FORWARD_AXIS; struct Pivot world_pivot; pivot_combine(pivot->parent, pivot, &world_pivot); Vec4f target_direction; vec_sub(target, world_pivot.position, target_direction); float dot_yaw = vec_dot(target_direction, forward_axis); Quat rotation = {0}; if( fabs(dot_yaw + 1.0f) < CUTE_EPSILON ) { // vector a and b point exactly in the opposite direction, // so it is a 180 degrees turn around the up-axis Quat rotation = {0}; quat_from_axis_angle(up_axis, PI, rotation); quat_mul(world_pivot.orientation, rotation, rotation); } else if( fabs(dot_yaw - (1.0f)) < CUTE_EPSILON ) { // vector a and b point exactly in the same direction // so we return the identity quaternion quat_copy(world_pivot.orientation, rotation); } else { // - I look at the target by turning the pivot orientation using only // yaw and pitch movement // - I always rotate the pivot from its initial orientation (up and forward // basis vectors like initialized above), so this does not incrementally // advance the orientation quat_identity(rotation); // - to find the amount of yaw I project the target_direction into the // up_axis plane, resulting in up_projection which is a vector that // points from the up_axis plane to the tip of the target_direction Vec4f up_projection = {0}; vec_mul1f(up_axis, vec_dot(target_direction, up_axis), up_projection); // - so then by subtracting the up_projection from the target_direction, // I get a vector lying in the up_axis plane, pointing towards the target Vec4f yaw_direction = {0}; vec_sub(target_direction, up_projection, yaw_direction); // - angle between yaw_direction and forward_axis is the amount of yaw we // need to point the forward_axis toward the target float yaw = 0.0f; vec_angle(yaw_direction, forward_axis, &yaw); log_assert( ! isnan(yaw), "vec_angle(%f %f %f, %f %f %f, %f);\n", yaw_direction[0], yaw_direction[1], yaw_direction[2], forward_axis[0], forward_axis[1], forward_axis[2], yaw ); // - I have to compute the cross product between yaw_direction and // forward_axis and use the resulting yaw_axis Vec4f yaw_axis = {0}; vec_cross(yaw_direction, forward_axis, yaw_axis); if( vec_nullp(yaw_axis) ) { vec_copy4f(up_axis, yaw_axis); } // - compute the yaw rotation Quat yaw_rotation = {0}; quat_from_axis_angle(yaw_axis, yaw, yaw_rotation); // - to compute, just as with the yaw, I want an axis that lies on the plane that // is spanned in this case by the right_axis, when the camera points toward the // target // - I could compute an axis, but I already have a direction vector that points // toward the target, the yaw_direction, I just have to normalize it to make it // an axis (and put the result in forward_axis, since it now is the forward_axis // of the yaw turned camera) Vec4f yaw_forward_axis = {0}; vec_normalize(yaw_direction, yaw_forward_axis); // - then use the new forward axis with the old target_direction to compute the angle // between those float pitch = 0.0f; vec_angle(target_direction, yaw_forward_axis, &pitch); log_assert( ! isnan(pitch), "vec_angle(%f %f %f, %f %f %f, %f);\n", target_direction[0], target_direction[1], target_direction[2], yaw_forward_axis[0], yaw_forward_axis[1], yaw_forward_axis[2], pitch ); // - and just as in the yaw case we compute an rotation pitch_axis Vec4f pitch_axis = {0}; vec_cross(target_direction, yaw_forward_axis, pitch_axis); if( vec_nullp(pitch_axis) ) { vec_copy4f(right_axis, pitch_axis); } // - and finally compute the pitch rotation and combine it with the yaw_rotation // in the same step Quat pitch_rotation; quat_from_axis_angle(pitch_axis, pitch, pitch_rotation); Quat yaw_pitch_rotation; quat_mul(yaw_rotation, pitch_rotation, yaw_pitch_rotation); Quat inverted_orientation = {0}; quat_invert(world_pivot.orientation, inverted_orientation); // - the int32_t I want to return indicates the cameras 'flip' status, that is, it is // one when the camera angle was pitched so much that it flipped over and its // up axis is now pointing downwards // - to find out if I am flipped over, I compute the flipped up_axis called // flip_axis and then use the dot product between the flip_axis and up_axis // to decide if I am flipped Vec4f flip_axis = {0}; vec_rotate(up_axis, inverted_orientation, flip_axis); vec_rotate(flip_axis, yaw_pitch_rotation, flip_axis); float dot_pitch = vec_dot(up_axis, flip_axis); Vec4f target_axis = {0}; vec_normalize(target_direction, target_axis); // - check if we are flipped and if we are, set result to 1 meaning we are flipped // - turn the camera around PI so that we can continue pitching, otherwise we just get // stuck when trying to flip the camera over if( dot_pitch < 0.0f ) { result = 1; quat_from_axis_angle(target_axis, PI, rotation); quat_mul(yaw_pitch_rotation, rotation, yaw_pitch_rotation); } quat_copy(yaw_pitch_rotation, rotation); } if( ! isnan(rotation[0]) && ! isnan(rotation[1]) && ! isnan(rotation[2]) && ! isnan(rotation[3]) ) { quat_copy(rotation, pivot->orientation); } pivot->eye_distance = vec_length(target_direction); return result; }
void cart_latt_vecs( double *p_abc, double *p_latt_vec, double *p_recip_latt_vec) { double cell_volume, bx_cx, mag_a, mag_b, mag_c; double a_cross_b[3], b_cross_c[3], c_cross_a[3]; double alpha, beta, gamma; double dot_set[9]; int iloop; /********* make alpha beta gamma in radians ****************************/ mag_a = *p_abc; mag_b = *(p_abc+1); mag_c = *(p_abc+2); alpha = *(p_abc+3)/RAD_TO_DEG; beta = *(p_abc+4)/RAD_TO_DEG; gamma = *(p_abc+5)/RAD_TO_DEG; /********* X indicates that a is to be aligned with the x axis *********/ *p_latt_vec = mag_a; *(p_latt_vec+1)= 0.0; *(p_latt_vec+2)= 0.0; /********* XY indicates that the b axis is to lie in the plane formed ******/ /********* by the y-axis and the x-axis i.e. perp. to Z ******/ *(p_latt_vec+3)= mag_b * cos( gamma); *(p_latt_vec+4)= mag_b * sin( gamma); *(p_latt_vec+5)= 0.0; /******** XYZ indicates that the c vector position is now defined **********/ *(p_latt_vec+6)= mag_c * cos( beta); bx_cx = ( *(p_latt_vec+3)) * ( *(p_latt_vec+6)); *(p_latt_vec+7)= ( mag_b*mag_c*cos( alpha) - bx_cx )/ ( *(p_latt_vec+4)); *(p_latt_vec+8)= sqrt ( mag_c*mag_c - *(p_latt_vec+6) * *(p_latt_vec+6) - *(p_latt_vec+7) * *(p_latt_vec+7)); /****** Print out lattice vectors ******************************************/ printf ("Lattice vectors : \n"); printf ("a: %10.6f %10.6f %10.6f\n", *p_latt_vec , *(p_latt_vec+1), *(p_latt_vec+2)); printf ("b: %10.6f %10.6f %10.6f\n", *(p_latt_vec+3), *(p_latt_vec+4), *(p_latt_vec+5)); printf ("c: %10.6f %10.6f %10.6f\n", *(p_latt_vec+6), *(p_latt_vec+7), *(p_latt_vec+8)); /****** generate reciprocal lattice vectors ********************************/ vec_cross( p_latt_vec, p_latt_vec+3, &a_cross_b[0]); vec_cross( p_latt_vec+3, p_latt_vec+6, &b_cross_c[0]); vec_cross( p_latt_vec+6, p_latt_vec , &c_cross_a[0]); cell_volume= vec_dot(p_latt_vec, &b_cross_c[0]); printf(" a cross b = %10.6f %10.6f %10.6f \n", a_cross_b[0],a_cross_b[1],a_cross_b[2]); printf(" b cross c = %10.6f %10.6f %10.6f \n", b_cross_c[0],b_cross_c[1],b_cross_c[2]); printf(" c cross a = %10.6f %10.6f %10.6f \n", c_cross_a[0],c_cross_a[1],c_cross_a[2]); printf("Cell Volume = %10.6f\n", cell_volume); *p_recip_latt_vec = b_cross_c[0]/cell_volume; *(p_recip_latt_vec+1)= b_cross_c[1]/cell_volume; *(p_recip_latt_vec+2)= b_cross_c[2]/cell_volume; *(p_recip_latt_vec+3)= c_cross_a[0]/cell_volume; *(p_recip_latt_vec+4)= c_cross_a[1]/cell_volume; *(p_recip_latt_vec+5)= c_cross_a[2]/cell_volume; *(p_recip_latt_vec+6)= a_cross_b[0]/cell_volume; *(p_recip_latt_vec+7)= a_cross_b[1]/cell_volume; *(p_recip_latt_vec+8)= a_cross_b[2]/cell_volume; /**************** Check by forming all dot products this should *******/ /**************** give the identity matrix ****************************/ dot_set[0] = vec_dot(p_recip_latt_vec, p_latt_vec); dot_set[1] = vec_dot(p_recip_latt_vec+3, p_latt_vec); dot_set[2] = vec_dot(p_recip_latt_vec+6, p_latt_vec); dot_set[3] = vec_dot(p_recip_latt_vec, p_latt_vec+3); dot_set[4] = vec_dot(p_recip_latt_vec+3, p_latt_vec+3); dot_set[5] = vec_dot(p_recip_latt_vec+6, p_latt_vec+3); dot_set[6] = vec_dot(p_recip_latt_vec, p_latt_vec+6); dot_set[7] = vec_dot(p_recip_latt_vec+3, p_latt_vec+6); dot_set[8] = vec_dot(p_recip_latt_vec+6, p_latt_vec+6); printf ("Check on recip/real lat vecs\n\n"); for (iloop = 0; iloop < 9; iloop++) { printf("%10.6f ", dot_set[iloop]); if (iloop == 2 || iloop == 5 || iloop == 8) printf("\n"); } return; }
bool arcball_event(struct Arcball* arcball, SDL_Event event) { static int32_t mouse_down = 0; static const float rotation_slowness_factor = 0.25f; static int32_t next_flipped = 0; // - arcball rotation is performed by dragging the mouse, so I just keep track of when // a mouse button is pressed and released between calls to this function by setting a // static variable mouse_down to the button number when a button is pressed and back // to 0 when that button is released if( event.type == SDL_MOUSEBUTTONDOWN && mouse_down == 0 ) { mouse_down = event.button.button; } else if( event.type == SDL_MOUSEBUTTONUP && mouse_down == event.button.button ) { arcball->flipped = next_flipped; mouse_down = 0; } if( mouse_down == arcball->translate_button && event.type == SDL_MOUSEMOTION ) { SDL_MouseMotionEvent mouse = event.motion; float eye_distance = arcball->camera.pivot.eye_distance; // - when an mouse motion event occurs, and mouse_down to the translation_button so we compute // a camera translation // - the camera should pan around on the x-z-plane, keeping its height and orientation Quat inverted_orientation = {0}; quat_invert(arcball->camera.pivot.orientation, inverted_orientation); // - the sideways translation is computed by taking the right_axis and orienting it with // the cameras orientation, the way I set up the lookat implementation this should always // result in a vector parallel to the x-z-plane Vec4f right_axis = RIGHT_AXIS; vec_rotate4f(right_axis, inverted_orientation, right_axis); if( mouse.xrel != 0 ) { // - then we'll just multiply the resulting axis with the mouse x relative movement, inversely // scaled by how far we are away from what we are looking at (farer means faster, nearer // means slower), the translation_factor is just a value that felt good when this was implemented Vec4f x_translation = {0}; vec_mul1f(right_axis, (float)mouse.xrel/arcball->translate_factor*eye_distance, x_translation); // - finally just add the x_translation to the target and position so that the whole arcball moves vec_add(arcball->target, x_translation, arcball->target); vec_add(arcball->camera.pivot.position, x_translation, arcball->camera.pivot.position); } // - the z translation can't be done along the orientated forward axis because that would include // the camera pitch, here, same as above, we need an axis that is parallel to the x-z-plane Vec4f up_axis = UP_AXIS; if( mouse.yrel != 0 ) { // - luckily such an axis is easily computed from the crossproduct of the orientated right_axis and // the default up_axis, the result is an axis pointing in the direction of the cameras forward axis, // while still being parallel to the x-z-plane Vec4f forward_axis; vec_cross(right_axis, up_axis, forward_axis); // - same as above Vec4f z_translation; vec_mul1f(forward_axis, (float)mouse.yrel/arcball->translate_factor*eye_distance, z_translation); // - dito vec_add(arcball->target, z_translation, arcball->target); vec_add(arcball->camera.pivot.position, z_translation, arcball->camera.pivot.position); } } else if( mouse_down == arcball->rotate_button && event.type == SDL_MOUSEMOTION ) { SDL_MouseMotionEvent mouse = event.motion; // - above case was translation, this is an rotation occuring: mouse_down is equal to the // rotation_button and the event is a mouse motion // - the camera needs to rotate around the target while keeping its height, orientation and // without _any_ rolling // - we want only yaw and pitch movement // - yaw is easy, just use the fixed up_axis and create a rotation the rotates around it // by the mouse x relative movement (converted to radians) // - the flipped value indicates if the camera is flipped over, so we'll just use that to // change the sign of the yaw to make the mouse movement on the screen always correctly // relates to the movement of the rotation Vec4f up_axis = UP_AXIS; Quat yaw_rotation = {0}; quat_from_axis_angle(up_axis, arcball->flipped * PI/180 * mouse.xrel * rotation_slowness_factor, yaw_rotation); // - pitch is a little more involved, I need to compute the orientated right axis and use // that to compute the pitch_rotation Quat inverted_orientation = {0}; quat_invert(arcball->camera.pivot.orientation, inverted_orientation); Vec4f right_axis = RIGHT_AXIS; vec_rotate4f(right_axis, inverted_orientation, right_axis); Quat pitch_rotation = {0}; quat_from_axis_angle(right_axis, -PI/180 * mouse.yrel * rotation_slowness_factor, pitch_rotation); // - combine yaw and pitch into a single rotation Quat rotation = {0}; quat_mul(yaw_rotation, pitch_rotation, rotation); // - orbit is the position translated to the coordinate root // - the yaw and pitch rotation is applied to the orbit // - orbit is translated back and replaces the camera position Vec4f orbit = {0}; vec_sub(arcball->camera.pivot.position, arcball->target, orbit); vec_rotate4f(orbit, rotation, orbit); vec_add(arcball->target, orbit, arcball->camera.pivot.position); // - after updating the position we just call lookat to compute the new // orientation, and also set the flipped state next_flipped = pivot_lookat(&arcball->camera.pivot, arcball->target); } if( event.type == SDL_MOUSEWHEEL ) { SDL_MouseWheelEvent wheel = event.wheel; // - zooming when mouse wheel event happens float* eye_distance = &arcball->camera.pivot.eye_distance; if( (*eye_distance > arcball->camera.frustum.z_near || wheel.y < 0) && (*eye_distance < arcball->camera.frustum.z_far || wheel.y > 0)) { // - just going back and forth along the oriented forward axis, using wheel // y motion inversly scaled by the eye_distance, similar to what is done // for the translation above (farer == faster zoom, nearer == slower zoom) Quat inverted_orientation = {0}; quat_invert(arcball->camera.pivot.orientation, inverted_orientation); Vec4f forward_axis = FORWARD_AXIS; vec_rotate4f(forward_axis, inverted_orientation, forward_axis); Vec4f zoom = {0}; vec_mul1f(forward_axis, wheel.y/arcball->zoom_factor*(*eye_distance), zoom); vec_add(arcball->camera.pivot.position, zoom, arcball->camera.pivot.position); // - eye_distance is kept in camera state, so we need to update it here *eye_distance = vlength(arcball->camera.pivot.position); } } return true; }
void create_8ball_scene( BallsType * balls ) { int i,j; myvec dball1, dball2, vdummy; VMfloat poserr=0.007; VMfloat ang; myvec verr; balls->gametype=GAME_8BALL; /* balls */ balls->nr=16; if( balls->ball != NULL ) billard_free( balls->ball ); balls->ball = billard_malloc(sizeof(BallType)*balls->nr); place8ballnrs(balls); for(i=0;i<balls->nr;i++){ balls->ball[i].m=BALL_M; /* I_kugel = (m.r^2)2/5 = (m.d^2)/10 */ balls->ball[i].I=BALL_M*BALL_D*BALL_D/10.0/**0.01*/; balls->ball[i].d=BALL_D; balls->ball[i].v=vec_xyz(0.0,0.0,0.0); balls->ball[i].w=vec_xyz(0.0,0.0,0.0); balls->ball[i].b[0]=vec_unit(vec_xyz(rand(),rand(),rand())); vdummy=vec_xyz(rand(),rand(),rand()); balls->ball[i].b[1]=vec_unit(vec_diff(vdummy,vec_proj(vdummy,balls->ball[i].b[0]))); balls->ball[i].b[2]=vec_cross(balls->ball[i].b[0],balls->ball[i].b[1]); balls->ball[i].in_game=1; balls->ball[i].in_hole=0; balls->ball[i].soundplayed=0; } dball1=vec_scale( vec_xyz(-0.5, 0.5*sqrt(3.0), 0.0), (1.0+2.0*poserr)*BALL_D ); dball2=vec_scale( vec_xyz( 1.0, 0.0, 0.0), (1.0+2.0*poserr)*BALL_D ); /* white ball */ balls->ball[0].r = vec_xyz(0.0,-TABLE_L/4.0,0.0); balls->ball[0].w = vec_xyz(0.0,0.0,0.0); /* other balls */ balls->ball[ 1].r = vec_xyz(0.0,TABLE_L/4.0,0.0); balls->ball[ 2].r = vec_add( balls->ball[ 1].r, dball1 ); balls->ball[ 3].r = vec_add( balls->ball[ 2].r, dball2 ); balls->ball[ 4].r = vec_add( balls->ball[ 2].r, dball1 ); balls->ball[ 5].r = vec_add( balls->ball[ 4].r, dball2 ); balls->ball[ 6].r = vec_add( balls->ball[ 5].r, dball2 ); balls->ball[ 7].r = vec_add( balls->ball[ 4].r, dball1 ); balls->ball[ 8].r = vec_add( balls->ball[ 7].r, dball2 ); balls->ball[ 9].r = vec_add( balls->ball[ 8].r, dball2 ); balls->ball[10].r = vec_add( balls->ball[ 9].r, dball2 ); balls->ball[11].r = vec_add( balls->ball[ 7].r, dball1 ); balls->ball[12].r = vec_add( balls->ball[11].r, dball2 ); balls->ball[13].r = vec_add( balls->ball[12].r, dball2 ); balls->ball[14].r = vec_add( balls->ball[13].r, dball2 ); balls->ball[15].r = vec_add( balls->ball[14].r, dball2 ); /* add randomness to init positions */ for( i=1 ; i<balls->nr ; i++ ){ ang = (VMfloat)rand()/(VMfloat)RAND_MAX*2.0*M_PI; //fprintf(stderr,"ball_placemet_err: angle=%f ",ang); verr = vec_scale( vec_xyz(cos(ang),sin(ang),0.0), (poserr*0.95)*BALL_D ); balls->ball[i].r = vec_add( balls->ball[i].r, verr ); } for( i=1 ; i<balls->nr ; i++ ){ for( j=i+1 ; j<balls->nr ; j++ ){ if (vec_abs(vec_diff(balls->ball[i].r,balls->ball[j].r))/BALL_D<1.5){ //fprintf(stderr,"BALLLDISR(%d,%d)=%f\n",balls->ball[i].nr,balls->ball[j].nr,vec_abs(vec_diff(balls->ball[i].r,balls->ball[j].r))/BALL_D); } } } for( i=0 ; i<balls->nr ; i++ ){ balls->ball[i].path=0; balls->ball[i].pathcnt=0; balls->ball[i].pathsize=0; } balls->ball[0].v=vec_xyz(0.0,0.0,0.0); }
void create_6hole_walls_snooker( BordersType * walls ) { int i; /* borders */ // walls->nr=30; walls->nr=32; if( walls->border != NULL ) billard_free( walls->border ); walls->border = billard_malloc( sizeof(BorderType)*walls->nr ); /* bonds */ walls->border[0].pnr = 3; walls->border[0].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[0].r2 = vec_xyz( +TABLE_W/2.0, +HOLE2_W/2.0, 0.0 ); walls->border[0].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[0].n = vec_xyz( -1.0, 0.0, 0.0 ); walls->border[1].pnr = 3; walls->border[1].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[1].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, 0.0 ); walls->border[1].r3 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[1].n = vec_xyz( -1.0, 0.0, 0.0 ); walls->border[2].pnr = 3; walls->border[2].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[2].r2 = vec_xyz( -TABLE_W/2.0, +HOLE2_W/2.0, 0.0 ); walls->border[2].r3 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[2].n = vec_xyz( +1.0, 0.0, 0.0 ); walls->border[3].pnr = 3; walls->border[3].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[3].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, 0.0 ); walls->border[3].r3 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[3].n = vec_xyz( +1.0, 0.0, 0.0 ); walls->border[4].pnr = 3; walls->border[4].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 ); walls->border[4].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, 0.0 ); walls->border[4].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 ); walls->border[4].n = vec_xyz( 0.0, -1.0, 0.0 ); walls->border[5].pnr = 3; walls->border[5].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 ); walls->border[5].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, 0.0 ); walls->border[5].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 ); walls->border[5].n = vec_xyz( 0.0, +1.0, 0.0 ); /* edges */ /* upper right */ walls->border[6].pnr = 2; walls->border[6].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[6].r2 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[18].pnr = 3; walls->border[18].r1 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[18].r2 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[18].r3 = vec_xyz( +TABLE_W/2.0+1.0, +TABLE_L/2.0-HOLE1_W/SQR2+HOLE1_TAN, 0.0 ); walls->border[18].n = vec_unit(vec_cross(vec_diff(walls->border[18].r2,walls->border[18].r1),vec_diff(walls->border[18].r3,walls->border[18].r1))); /* upper right */ walls->border[7].pnr = 2; walls->border[7].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 ); walls->border[7].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 ); walls->border[19].pnr = 3; walls->border[19].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 ); walls->border[19].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 ); walls->border[19].r3 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2+HOLE1_TAN, +TABLE_L/2.0+1.0, 0.0 ); walls->border[19].n = vec_unit(vec_cross(vec_diff(walls->border[19].r1,walls->border[19].r2),vec_diff(walls->border[19].r3,walls->border[19].r1))); /* upper left */ walls->border[8].pnr = 2; walls->border[8].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[8].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[20].pnr = 3; walls->border[20].r1 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[20].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0-HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[20].r3 = vec_xyz( -TABLE_W/2.0-1.0, +TABLE_L/2.0-HOLE1_W/SQR2+HOLE1_TAN, 0.0 ); walls->border[20].n = vec_unit(vec_cross(vec_diff(walls->border[20].r1,walls->border[20].r2),vec_diff(walls->border[20].r3,walls->border[20].r1))); /* upper left */ walls->border[9].pnr = 2; walls->border[9].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 ); walls->border[9].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 ); walls->border[21].pnr = 3; walls->border[21].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, -BALL_D/2.0 ); walls->border[21].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, +TABLE_L/2.0, BALL_D/2.0 ); walls->border[21].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2-HOLE1_TAN, +TABLE_L/2.0+1.0, 0.0 ); walls->border[21].n = vec_unit(vec_cross(vec_diff(walls->border[21].r2,walls->border[21].r1),vec_diff(walls->border[21].r3,walls->border[21].r1))); /* lower right */ walls->border[10].pnr = 2; walls->border[10].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[10].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[22].pnr = 3; walls->border[22].r1 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[22].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[22].r3 = vec_xyz( +TABLE_W/2.0+1.0, -TABLE_L/2.0+HOLE1_W/SQR2-HOLE1_TAN, 0.0 ); walls->border[22].n = vec_unit(vec_cross(vec_diff(walls->border[22].r1,walls->border[22].r2),vec_diff(walls->border[22].r3,walls->border[22].r1))); /* lower right */ walls->border[11].pnr = 2; walls->border[11].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 ); walls->border[11].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 ); walls->border[23].pnr = 3; walls->border[23].r1 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 ); walls->border[23].r2 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 ); walls->border[23].r3 = vec_xyz( +TABLE_W/2.0-HOLE1_W/SQR2+HOLE1_TAN, -TABLE_L/2.0-1.0, 0.0 ); walls->border[23].n = vec_unit(vec_cross(vec_diff(walls->border[23].r2,walls->border[23].r1),vec_diff(walls->border[23].r3,walls->border[23].r1))); /* lower left */ walls->border[12].pnr = 2; walls->border[12].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[12].r2 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[24].pnr = 3; walls->border[24].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, -BALL_D/2.0 ); walls->border[24].r2 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0+HOLE1_W/SQR2, BALL_D/2.0 ); walls->border[24].r3 = vec_xyz( -TABLE_W/2.0-1.0, -TABLE_L/2.0+HOLE1_W/SQR2-HOLE1_TAN, 0.0 ); walls->border[24].n = vec_unit(vec_cross(vec_diff(walls->border[24].r2,walls->border[24].r1),vec_diff(walls->border[24].r3,walls->border[24].r1))); /* lower left */ walls->border[13].pnr = 2; walls->border[13].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 ); walls->border[13].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 ); walls->border[25].pnr = 3; walls->border[25].r1 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, -BALL_D/2.0 ); walls->border[25].r2 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2, -TABLE_L/2.0, BALL_D/2.0 ); walls->border[25].r3 = vec_xyz( -TABLE_W/2.0+HOLE1_W/SQR2-HOLE1_TAN, -TABLE_L/2.0-1.0, 0.0 ); walls->border[25].n = vec_unit(vec_cross(vec_diff(walls->border[25].r1,walls->border[25].r2),vec_diff(walls->border[25].r3,walls->border[25].r1))); /* middle left */ walls->border[14].pnr = 2; walls->border[14].r1 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 ); walls->border[14].r2 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 ); walls->border[26].pnr = 3; walls->border[26].r1 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 ); walls->border[26].r2 = vec_xyz( -TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 ); walls->border[26].r3 = vec_xyz( -TABLE_W/2.0-1.0, HOLE2_W/2.0-HOLE2_TAN, 0.0 ); walls->border[26].n = vec_unit(vec_cross(vec_diff(walls->border[26].r2,walls->border[26].r1),vec_diff(walls->border[26].r3,walls->border[26].r1))); /* middle left */ walls->border[15].pnr = 2; walls->border[15].r1 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 ); walls->border[15].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 ); walls->border[27].pnr = 3; walls->border[27].r1 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 ); walls->border[27].r2 = vec_xyz( -TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 ); walls->border[27].r3 = vec_xyz( -TABLE_W/2.0-1.0, -HOLE2_W/2.0+HOLE2_TAN, 0.0 ); walls->border[27].n = vec_unit(vec_cross(vec_diff(walls->border[27].r1,walls->border[27].r2),vec_diff(walls->border[27].r3,walls->border[27].r1))); /* middle right */ walls->border[16].pnr = 2; walls->border[16].r1 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 ); walls->border[16].r2 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 ); walls->border[28].pnr = 3; walls->border[28].r1 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, -BALL_D/2.0 ); walls->border[28].r2 = vec_xyz( +TABLE_W/2.0, HOLE2_W/2.0, BALL_D/2.0 ); walls->border[28].r3 = vec_xyz( +TABLE_W/2.0+1.0, HOLE2_W/2.0-HOLE2_TAN, 0.0 ); walls->border[28].n = vec_unit(vec_cross(vec_diff(walls->border[28].r1,walls->border[28].r2),vec_diff(walls->border[28].r3,walls->border[28].r1))); /* middle right */ walls->border[17].pnr = 2; walls->border[17].r1 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 ); walls->border[17].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 ); walls->border[29].pnr = 3; walls->border[29].r1 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, -BALL_D/2.0 ); walls->border[29].r2 = vec_xyz( +TABLE_W/2.0, -HOLE2_W/2.0, BALL_D/2.0 ); walls->border[29].r3 = vec_xyz( +TABLE_W/2.0+1.0, -HOLE2_W/2.0+HOLE2_TAN, 0.0 ); walls->border[29].n = vec_unit(vec_cross(vec_diff(walls->border[29].r2,walls->border[29].r1),vec_diff(walls->border[29].r3,walls->border[29].r1))); /* friction constants and loss factors */ for(i=0;i<walls->nr;i++){ walls->border[i].mu = 0.1; walls->border[i].loss0 = 0.2; walls->border[i].loss_max = 0.5; walls->border[i].loss_wspeed = 4.0; /* [m/s] */ } /* table surface */ #define TABLE_W2 (TABLE_W-BALL_D*0.9) #define TABLE_L2 (TABLE_L-BALL_D*0.9) walls->border[30].pnr = 3; walls->border[30].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 ); walls->border[30].r2 = vec_xyz( +TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 ); walls->border[30].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 ); walls->border[30].n = vec_xyz( 0.0, 0.0, 1.0 ); walls->border[31].pnr = 3; walls->border[31].r1 = vec_xyz( -TABLE_W/2.0, -TABLE_L/2.0, -BALL_D/2.0-0.0001 ); walls->border[31].r3 = vec_xyz( +TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 ); walls->border[31].r2 = vec_xyz( -TABLE_W/2.0, +TABLE_L/2.0, -BALL_D/2.0-0.0001 ); walls->border[31].n = vec_xyz( 0.0, 0.0, 1.0 ); #undef TABLE_W2 #undef TABLE_L2 walls->border[30].mu = 0.2; walls->border[30].loss0 = 0.6; walls->border[30].loss_max = 0.99; walls->border[30].loss_wspeed = 1.5; walls->border[31].mu = 0.2; walls->border[31].loss0 = 0.6; walls->border[31].loss_max = 0.99; walls->border[31].loss_wspeed = 1.5; /* holes */ walls->holenr = 6; if( walls->hole != NULL ) billard_free( walls->hole ); walls->hole = billard_malloc(sizeof(HoleType)*walls->holenr); /* middle right */ walls->hole[0].aim = vec_xyz( +TABLE_W/2.0-HOLE2_AIMOFFS, 0.0, 0.0 ); walls->hole[0].pos = vec_xyz( +TABLE_W/2.0+HOLE2_XYOFFS, 0.0, 0.0 ); walls->hole[0].r = HOLE2_R; /* middle left */ walls->hole[1].aim = vec_xyz( -TABLE_W/2.0+HOLE2_AIMOFFS, 0.0, 0.0 ); walls->hole[1].pos = vec_xyz( -TABLE_W/2.0-HOLE2_XYOFFS, 0.0, 0.0 ); walls->hole[1].r = HOLE2_R; /* upper right */ walls->hole[2].aim = vec_xyz( +TABLE_W/2.0-HOLE1_AIMOFFS, +TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 ); walls->hole[2].pos = vec_xyz( +TABLE_W/2.0+HOLE1_XYOFFS, +TABLE_L/2.0+HOLE1_XYOFFS, 0.0 ); walls->hole[2].r = HOLE1_R; /* upper left */ walls->hole[3].aim = vec_xyz( -TABLE_W/2.0+HOLE1_AIMOFFS, +TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 ); walls->hole[3].pos = vec_xyz( -TABLE_W/2.0-HOLE1_XYOFFS, +TABLE_L/2.0+HOLE1_XYOFFS, 0.0 ); walls->hole[3].r = HOLE1_R; /* lower left */ walls->hole[4].aim = vec_xyz( -TABLE_W/2.0+HOLE1_AIMOFFS, -TABLE_L/2.0-HOLE1_AIMOFFS, 0.0 ); walls->hole[4].pos = vec_xyz( -TABLE_W/2.0-HOLE1_XYOFFS, -TABLE_L/2.0-HOLE1_XYOFFS, 0.0 ); walls->hole[4].r = HOLE1_R; /* lower right */ walls->hole[5].aim = vec_xyz( +TABLE_W/2.0-HOLE1_AIMOFFS, -TABLE_L/2.0+HOLE1_AIMOFFS, 0.0 ); walls->hole[5].pos = vec_xyz( +TABLE_W/2.0+HOLE1_XYOFFS, -TABLE_L/2.0-HOLE1_XYOFFS, 0.0 ); walls->hole[5].r = HOLE1_R; }
void write_car( FILE *fp, int *p_header_line, int *p_title_line, char *p_c_title_line, int *p_date_line, atom *p_molecule, int *p_mol_number, int pbc, double *p_abc, int num_atoms, double scale_factor, int start_frame, int *p_super, double *p_latt_vec, double *p_recip_latt_vec, coord_flags *p_fix_flags, int need_draw, win_details *p_win_geom, int num_windows ) { int iii, iwin, iloop, mol_current, this_atom; int iavec, ibvec, icvec; double ta[3],tb[3],t[3], x,y,z; double fract_a, fract_b, fract_c; double rrr, yyy[3], theta, dtheta; char *p_this_char; atom current_atom; atom draw_atom; atom *p_atom; coord_flags *p_this_fix; /*** Drawing variables ***/ int idraw; /*** Use the first element of header_line equal -1 as an indicator that */ /*** the header line has not been read */ if (start_frame) { if (*p_header_line != -1) { put_string( fp, p_header_line,100); } else { fprintf(fp, "!BIOSYM archive 3\n"); } } /* check if periodic boundaries were set */ if (pbc) { if (start_frame) fprintf(fp, "PBC=ON\n"); /* if (*p_title_line != -1) { put_string(fp, p_title_line,100); fprintf(fp, "\n"); } else { fprintf(fp, "%s", p_c_title_line); } */ fprintf(fp, "analyse_hist generated file\n"); /*** Use the first element of date_line equal -1 as an indicator that */ /*** the header line has not been read */ if (*p_date_line != -1) { put_string(fp, p_date_line,100); } else { fprintf(fp, "!DATE Mon Oct 12 12:17:26 1998\n"); } fprintf(fp,"PBC"); for (iloop=0; iloop < 6; iloop++) { if ( iloop <= 2 ) { fprintf(fp,"%10.4f",*(p_abc+iloop) * scale_factor * *(p_super+iloop)); } else { fprintf(fp,"%10.4f",*(p_abc+iloop)*RAD_TO_DEG); } } fprintf(fp," (P1)\n"); } else { if (start_frame) fprintf(fp,"PBC=OFF\n"); put_string(fp, p_title_line,100); put_string(fp, p_date_line,100); } if (need_draw) { idraw=0; } if (pbc) { mol_current=0; p_atom=p_molecule; for (iavec=0; iavec<= (*p_super)-1; iavec++) { ta[0]=iavec * *p_latt_vec; ta[1]=iavec * *(p_latt_vec+1); ta[2]=iavec * *(p_latt_vec+2); for (ibvec=0; ibvec<=*(p_super+1)-1; ibvec++) { tb[0]=ibvec * *(p_latt_vec+3); tb[1]=ibvec * *(p_latt_vec+4); tb[2]=ibvec * *(p_latt_vec+5); for (icvec=0; icvec<=*(p_super+2)-1; icvec++) { t[0]= ta[0] + tb[0] + icvec * *(p_latt_vec+6); t[1]= ta[1] + tb[1] + icvec * *(p_latt_vec+7); t[2]= ta[2] + tb[2] + icvec * *(p_latt_vec+8); p_atom=p_molecule; p_this_fix= p_fix_flags; for (this_atom=0; this_atom < num_atoms; this_atom++) { if (*(p_mol_number+this_atom) != mol_current) { mol_current++; fprintf(fp, "end\n"); } current_atom = *p_atom; current_atom.x += t[0]; current_atom.y += t[1]; current_atom.z += t[2]; if (DEBUG) printf("writing data for atom at %10.6f %10.6f %10.6f\n", current_atom.x,current_atom.y,current_atom.z); write_atom_data(fp, ¤t_atom, scale_factor, p_this_fix ); p_this_fix++; p_atom++; } /*** Add any features requested by drawing options ****/ if (need_draw) { /*** DEBUG, Check centres *********/ sprintf(current_atom.group,"DRAW"); sprintf(current_atom.group_no,"1"); sprintf(current_atom.pot,"dr"); sprintf(current_atom.elem,"S"); current_atom.part_chge=0.0; p_this_fix= p_fix_flags; for (iwin=0; iwin<=num_windows; iwin++) { sprintf(current_atom.label,"%s%d","S",iwin); current_atom.x= p_win_geom->centre[iwin][0]; current_atom.y= p_win_geom->centre[iwin][1]; current_atom.z= p_win_geom->centre[iwin][2]; write_atom_data(fp, ¤t_atom, scale_factor, p_this_fix ); } /*** DEBUG, Check centres end *****/ printf("Drawing circles\n"); sprintf(current_atom.group,"DRAW"); sprintf(current_atom.group_no,"1"); sprintf(current_atom.pot,"dr"); sprintf(current_atom.elem,"H"); current_atom.part_chge=0.0; p_this_fix= p_fix_flags; for (iwin=0; iwin<=num_windows; iwin++) { /*** Form a y axis in the plane ***/ vec_cross(&(p_win_geom->r_vec[iwin][0]), &(p_win_geom->norm[iwin][0]), &yyy[0]); rrr= size_vector(&(p_win_geom->r_vec[iwin][0])); unit_vector(&yyy[0]); printf("yyy: %10.6f %10.6f %10.6f rrr: %10.6f\n", yyy[0],yyy[1],yyy[2],rrr); theta= 0.0; dtheta= two_pi/20; /*** Don't bother with circles just yet ***/ for (iii=0; iii<20; iii++) { idraw++; sprintf(current_atom.label,"%s%d","H",idraw); theta += dtheta; current_atom.x= p_win_geom->centre[iwin][0] + p_win_geom->r_vec[iwin][0]* sin(theta) + rrr*yyy[0]*cos(theta); current_atom.y= p_win_geom->centre[iwin][1] + p_win_geom->r_vec[iwin][1]* sin(theta) + rrr*yyy[1]*cos(theta); current_atom.z= p_win_geom->centre[iwin][2] + p_win_geom->r_vec[iwin][2]* sin(theta) + rrr*yyy[2]*cos(theta); write_atom_data(fp, ¤t_atom, scale_factor, p_this_fix ); } printf("All done for window %d\n",iwin); } } } } } } else { mol_current=0; p_atom=p_molecule; p_this_fix= p_fix_flags; for (this_atom=0; this_atom < num_atoms; this_atom++) { if (*(p_mol_number+this_atom) != mol_current) { mol_current++; fprintf(fp, "end\n"); } write_atom_data(fp, p_atom, scale_factor, p_this_fix ); p_this_fix++; p_atom++; } } fprintf(fp, "end\nend\n"); return; }
int main (int argc, char *argv[]) { int cable_type; int quit = 0; float rot1 = 0.0, rot2 = 0.0, rot3 = 0.0; kos_img_t cubetxr; GLuint texture[2]; pvr_ptr_t texaddr; pvr_ptr_t bumpmap; /* Consider this as the vector from the object to the light, for now. */ GLfloat light_position[3] = { 0.7, 0.7, 2.0 }; vec_normalize (&light_position[0], &light_position[0]); cable_type = vid_check_cable (); printf ("KOS says M_PI is: %f\n", M_PI); if (cable_type == CT_VGA) vid_init (DM_640x480_VGA, PM_RGB565); else vid_init (DM_640x480_PAL_IL, PM_RGB565); init_pvr (); auto_orient (); png_to_img ("/rd/cube.png", PNG_NO_ALPHA, &cubetxr); texaddr = pvr_mem_malloc (cubetxr.w * cubetxr.h * 2); pvr_txr_load_kimg (&cubetxr, texaddr, PVR_TXRLOAD_INVERT_Y); kos_img_free (&cubetxr, 0); bumpmap = load_bumpmap ("/rd/bump.raw"); vid_border_color (0, 0, 0); pvr_set_bg_color (0.0, 0.0, 0.0); glKosInit (); glEnable (GL_DEPTH_TEST); glEnable (GL_CULL_FACE); glEnable (GL_TEXTURE_2D); glShadeModel (GL_SMOOTH); glClearDepth (1.0f); glDepthFunc (GL_LEQUAL); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (45.0, /* Field of view in degrees. */ 640.0 / 480.0, /* Aspect ratio. */ 1.0, /* Z near. */ 50.0); /* Z far. */ glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gluLookAt (0.0, 0.0, -4.5, /* Eye position. */ 0.0, 0.0, 0.0, /* Centre. */ 0.0, 1.0, 0.0); /* Up. */ glGenTextures (2, &texture[0]); /* Ordinary texture. */ glBindTexture (GL_TEXTURE_2D, texture[0]); glKosTex2D (GL_RGB565_TWID, cubetxr.w, cubetxr.h, texaddr); /* Bump texture. */ glBindTexture (GL_TEXTURE_2D, texture[1]); /*pvr_poly_cxt_txr (cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_BUMP | PVR_TXRFMT_TWIDDLED, 128, 128, bumpmap, PVR_FILTER_BILINEAR);*/ glKosTex2D (GL_BUMP_TWID, 128, 128, bumpmap); glTexEnvi (GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE); /* Break the nice abstraction. Tweak for bump mapping. */ /*cxt = (pvr_poly_cxt_t *) texture[1]; cxt->gen.specular = PVR_SPECULAR_ENABLE;*/ /*pvr_poly_compile (&bumphdr, cxt);*/ printf ("objmatrix at %p\n", objmatrix); while (!quit) { int faces; GLfloat transformed_normals [sizeof (face_normals) / (3 * sizeof (GLfloat))][3]; GLfloat transformed_orient [sizeof (face_orient) / (3 * sizeof (GLfloat))][3]; MAPLE_FOREACH_BEGIN (MAPLE_FUNC_CONTROLLER, cont_state_t, st) if (st->buttons & CONT_START) quit = 1; MAPLE_FOREACH_END () glKosBeginFrame (); glPushMatrix (); glRotatef (rot1, 1.0, 0.0, 0.0); glRotatef (rot2, 0.0, 1.0, 0.0); glRotatef (rot3, 0.0, 0.0, 1.0); rot1 += 0.1; rot2 += 0.2; rot3 += 0.3; /* Get the object's transformation matrix. */ glGetFloatv (GL_MODELVIEW_MATRIX, &objmatrix[0][0]); /* We care only about rotation for now. */ objmatrix[0][3] = objmatrix[1][3] = objmatrix[2][3] = 0.0; objmatrix[3][0] = objmatrix[3][1] = objmatrix[3][2] = 0.0; objmatrix[3][3] = 1.0; /*printf ("Got matrix:\n"); printf ("[ %f %f %f %f ]\n", objmatrix[0][0], objmatrix[0][1], objmatrix[0][2], objmatrix[0][3]); printf ("[ %f %f %f %f ]\n", objmatrix[1][0], objmatrix[1][1], objmatrix[1][2], objmatrix[1][3]); printf ("[ %f %f %f %f ]\n", objmatrix[2][0], objmatrix[2][1], objmatrix[2][2], objmatrix[2][3]); printf ("[ %f %f %f %f ]\n", objmatrix[3][0], objmatrix[3][1], objmatrix[3][2], objmatrix[3][3]);*/ /* Do these all in one go. */ mat_load ((matrix_t *) &objmatrix[0][0]); /* Note: mat_transform is only for 3D->2D (perspective) transformations! This won't be quite as quick, most likely. */ for (faces = 0; faces < 6; faces++) { GLfloat x = face_normals[faces][0]; GLfloat y = face_normals[faces][1]; GLfloat z = face_normals[faces][2]; GLfloat w = 1.0; mat_trans_nodiv (x, y, z, w); transformed_normals[faces][0] = x; transformed_normals[faces][1] = y; transformed_normals[faces][2] = z; x = face_orient[faces][0]; y = face_orient[faces][1]; z = face_orient[faces][2]; w = 1.0; mat_trans_nodiv (x, y, z, w); transformed_orient[faces][0] = x; transformed_orient[faces][1] = y; transformed_orient[faces][2] = z; } glKosMatrixDirty (); glDisable (GL_KOS_OFFSET_COLOR); glBindTexture (GL_TEXTURE_2D, texture[0]); glDisable (GL_TEXTURE_2D); //glBlendFunc (GL_DST_COLOR, GL_ZERO); glBlendFunc (GL_ONE, GL_ZERO); for (faces = 0; faces < 6; faces++) { int strip; glBegin (GL_TRIANGLE_STRIP); glColor4ub (colour[faces][0], colour[faces][1], colour[faces][2], colour[faces][3]); for (strip = 0; strip < 4; strip++) { glTexCoord2fv (texcoords[strip]); glVertex3fv (points[tristrips[faces][strip]]); } glEnd (); } /* Finish opaque list, start transparent list. */ glKosFinishList (); glBindTexture (GL_TEXTURE_2D, texture[1]); glEnable (GL_TEXTURE_2D); glEnable (GL_KOS_OFFSET_COLOR); glBlendFunc (GL_ZERO, GL_SRC_ALPHA); for (faces = 0; faces < 6; faces++) { int strip, over_pi, over_2pi; GLfloat s_dot_n, f[3], d[3], t, q; GLfloat d_cross_r[3], dxr_len, d_len; s_dot_n = vec_dot (&transformed_normals[faces][0], &light_position[0]); /* Elevation (T) angle: s.n = |s| |n| cos T T = acos (s.n / (|s| * |n|)) |s| and |n| are both 1. */ t = M_PI / 2 - acosf (s_dot_n); if (t < 0) t = 0; /* Rotation (Q) angle: d x r = (|d| |r| sin Q) n |d x r| / (|d| |r|) = sin Q. */ vec_scale (&f[0], &transformed_normals[faces][0], s_dot_n); vec_sub (&d[0], &light_position[0], &f[0]); vec_cross (&d_cross_r[0], &d[0], &transformed_orient[faces][0]); dxr_len = vec_length (&d_cross_r[0]); d_len = vec_length (&d[0]); q = asinf (dxr_len / d_len); over_pi = vec_dot (&d[0], &transformed_orient[faces][0]) < 0; if (over_pi) q = M_PI - q; over_2pi = vec_dot (&d_cross_r[0], &transformed_normals[faces][0]) < 0; if (over_2pi) q = 2 * M_PI - q; /*printf ("length of n: %f\n", length (&transformed_normals[faces][0])); printf ("%d: [ %f %f %f ]\n", faces, transformed_normals[faces][0], transformed_normals[faces][1], transformed_normals[faces][2]); printf ("length of r: %f\n", length (&transformed_orient[faces][0])); printf ("%d: [ %f %f %f ]\n", faces, transformed_orient[faces][0], transformed_orient[faces][1], transformed_orient[faces][2]);*/ glBegin (GL_TRIANGLE_STRIP); set_bump_direction (t, 2 * M_PI - q, 1.0); glColor4ub (255, 255, 255, 255); for (strip = 0; strip < 4; strip++) { glTexCoord2fv (texcoords[strip]); glVertex3fv (points[tristrips[faces][strip]]); } glEnd (); } /* Finish opaque polygon list, start translucent polygon list. */ /* glKosFinishList ();*/ glPopMatrix (); glKosFinishFrame (); } glKosShutdown (); pvr_shutdown (); vid_shutdown (); return 0; }
void create_9ball_scene( BallsType * balls ) { int i; myvec dball1, dball2, vdummy; VMfloat ang, ampl; myvec verr; balls->gametype=GAME_9BALL; /* balls */ balls->nr=10; if( balls->ball != NULL ) billard_free( balls->ball ); balls->ball = billard_malloc(sizeof(BallType)*balls->nr); place9ballnrs(balls); for(i=0;i<balls->nr;i++){ balls->ball[i].m=BALL_M; /* I_kugel = (m.r^2)2/5 = (m.d^2)/10 */ balls->ball[i].I=BALL_M*BALL_D*BALL_D/10.0/**0.01*/; balls->ball[i].d=BALL_D; balls->ball[i].v=vec_xyz(0.0,0.0,0.0); balls->ball[i].w=vec_xyz(0.0,0.0,0.0); balls->ball[i].b[0]=vec_unit(vec_xyz(rand(),rand(),rand())); vdummy=vec_xyz(rand(),rand(),rand()); balls->ball[i].b[1]=vec_unit(vec_diff(vdummy,vec_proj(vdummy,balls->ball[i].b[0]))); balls->ball[i].b[2]=vec_cross(balls->ball[i].b[0],balls->ball[i].b[1]); balls->ball[i].in_game=1; balls->ball[i].in_hole=0; balls->ball[i].soundplayed=0; } dball1=vec_scale(vec_xyz(-0.5*1.01, 0.5*sqrt(3.0)*1.01,0.0),BALL_D); dball2=vec_scale(vec_xyz(+0.5*1.01, 0.5*sqrt(3.0)*1.01,0.0),BALL_D); /* white ball */ balls->ball[0].r = vec_xyz(0.0,-TABLE_L/4.0,0.0); balls->ball[0].w = vec_xyz(0.0,0.0,0.0); /* other balls */ balls->ball[ 1].r = vec_xyz(0.0,TABLE_L/4.0,0.0); balls->ball[ 2].r = vec_add( balls->ball[1].r, vec_scale(dball2,2.0) ); balls->ball[ 3].r = vec_add( balls->ball[2].r, vec_scale(dball1,2.0) ); balls->ball[ 4].r = vec_add( balls->ball[1].r, vec_scale(dball1,2.0) ); balls->ball[ 5].r = vec_add( balls->ball[1].r, dball1 ); balls->ball[ 6].r = vec_add( balls->ball[1].r, dball2 ); balls->ball[ 7].r = vec_add( balls->ball[2].r, dball1 ); balls->ball[ 8].r = vec_add( balls->ball[4].r, dball2 ); balls->ball[ 9].r = vec_add( balls->ball[1].r, vec_add(dball1,dball2) ); /* add randomness to init positions */ for( i=1 ; i<balls->nr ; i++ ){ ang = rand(); ang = (VMfloat)rand()/(VMfloat)RAND_MAX*2.0*M_PI; ampl = (VMfloat)rand()/(VMfloat)RAND_MAX*0.0049*BALL_D; verr = vec_scale( vec_xyz(cos(ang),sin(ang),0.0), ampl ); balls->ball[i].r = vec_add( balls->ball[i].r, verr ); } for( i=0 ; i<balls->nr ; i++ ){ balls->ball[i].path=0; balls->ball[i].pathcnt=0; balls->ball[i].pathsize=0; } balls->ball[0].v=vec_xyz(0.0,0.0,0.0); }
void create_snooker_scene( BallsType * balls ) { int i; myvec dball1, dball2, vdummy; VMfloat ang, ampl; myvec verr; balls->gametype=GAME_SNOOKER; /* balls */ balls->nr=22; if( balls->ball != NULL ) billard_free( balls->ball ); balls->ball = billard_malloc(sizeof(BallType)*balls->nr); placesnookerballnrs(balls); for(i=0;i<balls->nr;i++){ balls->ball[i].m=BALL_M; /* I_kugel = (m.r^2)2/5 = (m.d^2)/10 */ balls->ball[i].I=BALL_M*BALL_D*BALL_D/10.0/**0.01*/; balls->ball[i].d=BALL_D; balls->ball[i].r = vec_xyz(TABLE_L*3,TABLE_L*3,0.0); /* get balls out of the way */ balls->ball[i].v=vec_xyz(0.0,0.0,0.0); balls->ball[i].w=vec_xyz(0.0,0.0,0.0); balls->ball[i].b[0]=vec_unit(vec_xyz(rand(),rand(),rand())); vdummy=vec_xyz(rand(),rand(),rand()); balls->ball[i].b[1]=vec_unit(vec_diff(vdummy,vec_proj(vdummy,balls->ball[i].b[0]))); balls->ball[i].b[2]=vec_cross(balls->ball[i].b[0],balls->ball[i].b[1]); balls->ball[i].in_game=1; balls->ball[i].in_hole=0; balls->ball[i].soundplayed=0; } dball1=vec_scale(vec_xyz(-0.5*1.01, 0.5*sqrt(3.0)*1.01,0.0),BALL_D); dball2=vec_scale(vec_xyz( 1.01, 0.0, 0.0),BALL_D); /* red balls */ balls->ball[ 1].r = vec_xyz(0.0,TABLE_L/4.0+1.1*BALL_D,0.0); balls->ball[ 8].r = vec_add( balls->ball[ 1].r, dball1 ); balls->ball[ 9].r = vec_add( balls->ball[ 8].r, dball2 ); balls->ball[10].r = vec_add( balls->ball[ 8].r, dball1 ); balls->ball[11].r = vec_add( balls->ball[10].r, dball2 ); balls->ball[12].r = vec_add( balls->ball[11].r, dball2 ); balls->ball[13].r = vec_add( balls->ball[10].r, dball1 ); balls->ball[14].r = vec_add( balls->ball[13].r, dball2 ); balls->ball[15].r = vec_add( balls->ball[14].r, dball2 ); balls->ball[16].r = vec_add( balls->ball[15].r, dball2 ); balls->ball[17].r = vec_add( balls->ball[13].r, dball1 ); balls->ball[18].r = vec_add( balls->ball[17].r, dball2 ); balls->ball[19].r = vec_add( balls->ball[18].r, dball2 ); balls->ball[20].r = vec_add( balls->ball[19].r, dball2 ); balls->ball[21].r = vec_add( balls->ball[20].r, dball2 ); /* color balls */ for(i=7;i>=2;i--) { spot_snooker_ball(balls,i); } /* white ball */ spot_snooker_ball(balls,0); /* add randomness to init positions */ for( i=1 ; i<balls->nr ; i++ ){ ang = (VMfloat)rand()/(VMfloat)RAND_MAX*2.0*M_PI; ampl = (VMfloat)rand()/(VMfloat)RAND_MAX*0.0049*BALL_D; verr = vec_scale( vec_xyz(cos(ang),sin(ang),0.0), ampl ); balls->ball[i].r = vec_add( balls->ball[i].r, verr ); } for( i=0 ; i<balls->nr ; i++ ){ balls->ball[i].path=0; balls->ball[i].pathcnt=0; balls->ball[i].pathsize=0; } balls->ball[0].v=vec_xyz(0.0,0.0,0.0); }
void tracer_build(raytracer *tracer){ int ne,i,j; const int pairs[6][2]={{0,1},{0,2},{0,3},{1,2},{1,3},{2,3}}; float3 *nodes; int *elems,ebase; int e1,e0; float Rn2; if(tracer->d || tracer->m || tracer->n || tracer->mesh==NULL) return; if(tracer->mesh->node==NULL||tracer->mesh->elem==NULL|| tracer->mesh->facenb==NULL||tracer->mesh->med==NULL) MESH_ERROR("mesh is missing"); ne=tracer->mesh->ne; nodes=tracer->mesh->node; elems=(int *)(tracer->mesh->elem); // convert int4* to int* if(tracer->method==rtPlucker){ int ea,eb,ec; float3 vecAB={0.f},vecAC={0.f}; tracer->d=(float3*)calloc(sizeof(float3),ne*6); // 6 edges/elem tracer->m=(float3*)calloc(sizeof(float3),ne*6); // 6 edges/elem tracer->n=(float3*)calloc(sizeof(float3),ne*4); // 4 face norms for(i=0;i<ne;i++){ ebase=i<<2; for(j=0;j<6;j++){ e1=elems[ebase+pairs[j][1]]-1; e0=elems[ebase+pairs[j][0]]-1; vec_diff(&nodes[e0],&nodes[e1],tracer->d+i*6+j); vec_cross(&nodes[e0],&nodes[e1],tracer->m+i*6+j); } for(j=0;j<4;j++){ ea=elems[ebase+out[j][0]]-1; eb=elems[ebase+out[j][1]]-1; ec=elems[ebase+out[j][2]]-1; vec_diff(&nodes[ea],&nodes[eb],&vecAB); vec_diff(&nodes[ea],&nodes[ec],&vecAC); vec_cross(&vecAB,&vecAC,tracer->n+ebase+j); Rn2=1.f/sqrt(vec_dot(tracer->n+ebase+j,tracer->n+ebase+j)); vec_mult(tracer->n+ebase+j,Rn2,tracer->n+ebase+j); } } }else if(tracer->method==rtHavel || tracer->method==rtBadouel){ int ea,eb,ec; float3 vecAB={0.f},vecAC={0.f}; tracer->d=NULL; tracer->m=(float3*)calloc(sizeof(float3),ne*12); for(i=0;i<ne;i++){ ebase=i<<2; for(j=0;j<4;j++){ float3 *vecN=tracer->m+3*(ebase+j); ea=elems[ebase+out[j][0]]-1; eb=elems[ebase+out[j][1]]-1; ec=elems[ebase+out[j][2]]-1; vec_diff(&nodes[ea],&nodes[eb],&vecAB); vec_diff(&nodes[ea],&nodes[ec],&vecAC); vec_cross(&vecAB,&vecAC,vecN); /*N is defined as ACxAB in Jiri's code, but not the paper*/ vec_cross(&vecAC,vecN,vecN+1); vec_cross(vecN,&vecAB,vecN+2); Rn2=1.f/sqrt(vec_dot(vecN,vecN)); vec_mult(vecN,Rn2,vecN); Rn2*=Rn2; vec_mult(vecN+1,Rn2,vecN+1); vec_mult(vecN+2,Rn2,vecN+2); #ifdef MMC_USE_SSE vecN->w = vec_dot(vecN, &nodes[ea]); (vecN+1)->w=-vec_dot(vecN+1,&nodes[ea]); (vecN+2)->w=-vec_dot(vecN+2,&nodes[ea]); #endif } } }else if(tracer->method==rtBLBadouel){ int ea,eb,ec; float3 vecAB={0.f},vecAC={0.f},vN={0.f}; tracer->d=NULL; tracer->n=(float3*)calloc(sizeof(float3),ne*4); for(i=0;i<ne;i++){ ebase=i<<2; float *vecN=&(tracer->n[ebase].x); for(j=0;j<4;j++){ ea=elems[ebase+out[j][0]]-1; eb=elems[ebase+out[j][1]]-1; ec=elems[ebase+out[j][2]]-1; vec_diff(&nodes[ea],&nodes[eb],&vecAB); vec_diff(&nodes[ea],&nodes[ec],&vecAC); vec_cross(&vecAB,&vecAC,&vN); /*N is defined as ACxAB in Jiri's code, but not the paper*/ Rn2=1.f/sqrt(vec_dot(&vN,&vN)); vec_mult(&vN,Rn2,&vN); vecN[j]=vN.x; vecN[j+4]=vN.y; vecN[j+8]=vN.z; #ifdef MMC_USE_SSE vecN[j+12] = vec_dot(&vN, &nodes[ea]); #endif } } } }