Esempio n. 1
0
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));
}
Esempio n. 2
0
/*  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;
}
Esempio n. 3
0
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));
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/**
 * 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;
}
Esempio n. 6
0
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];
	}
}
Esempio n. 7
0
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();
}
Esempio n. 8
0
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();
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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;
    }
}
Esempio n. 15
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];
        }
    }
}
Esempio n. 16
0
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);
	}
}
Esempio n. 17
0
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");
}
Esempio n. 18
0
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;
	}
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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;
  }
Esempio n. 22
0
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;
}
Esempio n. 23
0
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);
}
Esempio n. 24
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;
}
Esempio n. 25
0
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, &current_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, &current_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, &current_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;
}
Esempio n. 26
0
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;
}
Esempio n. 27
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);
}
Esempio n. 28
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);
}
Esempio n. 29
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
			}
                }
	}
}