Пример #1
0
/*
 * Compute the new  linear and angular velocities of  a bouncing ball.
 * Q  gives the  position  of the  point  of impact  and  W gives  the
 * velocity of the object being impacted.
 */
static float sol_bounce(struct v_ball *up,
                        const float q[3],
                        const float w[3], float dt)
{
    float n[3], r[3], d[3], vn, wn;
    float *p = up->p;
    float *v = up->v;

    /* Find the normal of the impact. */

    v_sub(r, p, q);
    v_sub(d, v, w);
    v_nrm(n, r);

    /* Find the new angular velocity. */

    v_crs(up->w, d, r);
    v_scl(up->w, up->w, -1.0f / (up->r * up->r));

    /* Find the new linear velocity. */

    vn = v_dot(v, n);
    wn = v_dot(w, n);

    v_mad(v, v, n, 1.7 * (wn - vn));

    v_mad(p, q, n, up->r);

    /* Return the "energy" of the impact, to determine the sound amplitude. */

    return fabsf(v_dot(n, d));
}
Пример #2
0
void pl_project_to_plane(Polygon * pl, 
                         const Plane * const pn, 
                         const vec direction)
{
    assert(pl);
    assert(pn);
    
    double d= v_dot(pn->normal, direction);
    
    // otherwise projection is impossible
    assert(fabs(d) > E);
    
    vec tmp;
    double * pt;
    uint i;
    double N;
    for (i=0; i < pl->last; i++){
		pt= pl->points[i].co;
        v_sub(tmp, pt, pn->point);
        N= -v_dot(pn->normal, tmp);
        v_scale(tmp, direction, N/d);
        v_add(pt, pt, tmp);
    }
    v_sub(tmp, pl->bb.min, pn->point);
    N= -v_dot(pn->normal, tmp);
    v_scale(tmp, direction, N/d);
    v_add(pl->bb.min, pl->bb.min, tmp);
    
    v_sub(tmp, pl->bb.max, pn->point);
    N= -v_dot(pn->normal, tmp);
    v_scale(tmp, direction, N/d);
    v_add(pl->bb.max, pl->bb.max, tmp);
}
Пример #3
0
static int sol_test_back(float dt,
                         const struct v_ball *up,
                         const struct b_side *sp,
                         const float o[3],
                         const float w[3])
{
    float q[3], d;

    /* If the ball is not in front of the plane, the test passes. */

    v_sub(q, up->p, o);
    d = sp->d;

    if (v_dot(q, sp->n) - d - up->r <= 0)
        return 1;

    /* If it's not in front of the plane after DT seconds, the test passes. */

    v_mad(q, q, up->v, dt);
    d += v_dot(w, sp->n) * dt;

    if (v_dot(q, sp->n) - d - up->r <= 0)
        return 1;

    /* Else, test fails. */

    return 0;
}
Пример #4
0
void RigidBody::operator()(const RigidBody::InternalState &x, RigidBody::InternalState &dxdt, const double /* t */)
{
  	Eigen::Vector3d x_dot, v_dot, omega_dot;
  	Eigen::Vector4d q_dot;
  	Eigen::Vector4d q(attitude.x(), attitude.y(), attitude.z(), attitude.w());

	Eigen::Vector3d omega = angularVelocity;
	Eigen::Matrix4d omegaMat = Omega(omega);

  	x_dot = velocity;
  	v_dot = force/mass;
  	q_dot = 0.5*omegaMat*q;
  	omega_dot = inertia.inverse() *
      (torque - omega.cross(inertia*omega));

	dxdt[0]  = x_dot(0); 
	dxdt[1]  = x_dot(1); 
	dxdt[2]  = x_dot(2); 

	dxdt[3]  = v_dot(0); 
	dxdt[4]  = v_dot(1); 
	dxdt[5]  = v_dot(2); 

	dxdt[6]  = q_dot(0); 
	dxdt[7]  = q_dot(1); 
	dxdt[8]  = q_dot(2); 
	dxdt[9]  = q_dot(3); 

	dxdt[10] = omega_dot(0); 
	dxdt[11] = omega_dot(1); 
	dxdt[12] = omega_dot(2); 
}
Пример #5
0
// works for homogeneous weights only. not clean
float Reaching::GetCosts(joint_vec_t& des_angle,cart_vec_t& des_pos){
  joint_vec_t& v1,v2;
  cart_vec_t& w1,w2;
  float s1,s2;
  v4_sub(des_angle,pos_angle,v1);
  //m4_diag_v_multiply(weight_angle,v1,v2);
  if (weight_angle[0] == 0){
    s1 = v4_dot(v1,v1);
    return s1;
  }
  else{
    v4_scale(v1,1/weight_angle[0],v2);
    s1 = v4_dot(v1,v2);
  }
  v_sub(des_cart,pos_cart,w1);
  
  if (weight_cart[0] == 0){
    s2 = v_dot(w1,w1);
    return s2;
  }
  else{
     v4_scale(w1,1/weight_cart[0],w2);
     s2 = v_dot(w1,w2);
  }

  //  m3_diag_v_multiply(weight_cart,w1,w2);
 
  return (s1+s2)/(1/weight_cart[0]+1/weight_angle[0]);
}
Пример #6
0
static float sol_test_side(float dt,
                           float T[3],
                           const struct v_ball *up,
                           const struct s_base *base,
                           const struct b_lump *lp,
                           const struct b_side *sp,
                           const float o[3],
                           const float w[3])
{
    float t = v_side(T, o, w, sp->n, sp->d, up->p, up->v, up->r);
    int i;

    if (t < dt)
        for (i = 0; i < lp->sc; i++)
        {
            const struct b_side *sq = base->sv + base->iv[lp->s0 + i];

            if (sp != sq &&
                v_dot(T, sq->n) -
                v_dot(o, sq->n) -
                v_dot(w, sq->n) * t > sq->d)
                return LARGE;
        }
    return t;
}
Пример #7
0
/* Determine whether the given vector created by the point and direction intersects at any point on the given object.
 *
 * to_check: The sphere to check for intersection.
 * origin: The origin of the ray.
 * direction: unit vector representing the direction of the ray.
 *
 * Return: The shortest distance to intersection if it happens, or INFINITY if it does not.
 */
float object_intersect(object *to_check, float *origin, float *direction) {
    if (to_check->type == SPHERE_TYPE) {
        float a = v_dot(direction, direction);
        
        float *temp = (float*)malloc(sizeof(float)*3);
        v_sub(origin, to_check->definition.sphere.center, temp);
        v_scale(temp, 2, temp);
        float b = v_dot(temp, direction);
        
        v_sub(origin, to_check->definition.sphere.center, temp);
        float c = v_dot(temp, temp);
        c -= to_check->definition.sphere.radius * to_check->definition.sphere.radius;
        
        
        float discriminant = b*b - 4*a*c;
        
        if (discriminant < 0) {
            
            return INFINITY;
        }
        
        float t1 = (-b + sqrtf(b*b - 4*a*c))/2*a;
        float t2 = (-b - sqrtf(b*b - 4*a*c))/2*a;
        
        
        if (t1 > 0 && t2 > 0) {
            return t1 < t2 ? t1 : t2;
        }
        if (t1 > 0) return t1;
        if (t2 > 0) return t2;
        else {
            
            return INFINITY;
        }
    }
    else if(to_check->type == PLANE_TYPE) {
        // Compute incident angle
        float vD = v_dot(to_check->definition.plane.normal, direction);
        if (vD == 0) return INFINITY;
        
        float distance = 0;
        for (int i = 0; i < 3; i++) {
            distance -= to_check->definition.plane.point[i] * to_check->definition.plane.normal[i];
        }
        
        float v0 = -(v_dot(to_check->definition.plane.normal, origin) + distance);
        float t = v0/vD;
        if (t < 0) return INFINITY;
        
        return t;
    }
    
    return NAN;
}
Пример #8
0
/*
 * Compute appropriate tilt axes from the view basis.
 */
void game_tilt_axes(struct game_tilt *tilt, float view_e[3][3])
{
    const float Y[3] = { 0.0f, 1.0f, 0.0f };

    v_cpy(tilt->x, view_e[0]);
    v_cpy(tilt->z, view_e[2]);

    /* Handle possible top-down view. */

    if (fabsf(v_dot(view_e[1], Y)) < fabsf(v_dot(view_e[2], Y)))
        v_inv(tilt->z, view_e[1]);
}
Пример #9
0
/*
 * Compute the new angular velocity and orientation of a ball pendulum.
 * A gives the accelleration of the ball.  G gives the gravity vector.
 */
void sol_pendulum(struct v_ball *up,
                  const float a[3],
                  const float g[3], float dt)
{
    float v[3], A[3], F[3], r[3], Y[3], T[3] = { 0.0f, 0.0f, 0.0f };

    const float m  = 5.000f;
    const float ka = 0.500f;
    const float kd = 0.995f;

    /* Find the total force over DT. */

    v_scl(A, a,     ka);
    v_mad(A, A, g, -dt);

    /* Find the force. */

    v_scl(F, A, m / dt);

    /* Find the position of the pendulum. */

    v_scl(r, up->E[1], -up->r);

    /* Find the torque on the pendulum. */

    if (fabsf(v_dot(r, F)) > 0.0f)
        v_crs(T, F, r);

    /* Apply the torque and dampen the angular velocity. */

    v_mad(up->W, up->W, T, dt);
    v_scl(up->W, up->W,    kd);

    /* Apply the angular velocity to the pendulum basis. */

    sol_rotate(up->E, up->W, dt);

    /* Apply a torque turning the pendulum toward the ball velocity. */

    v_mad(v, up->v, up->E[1], v_dot(up->v, up->E[1]));
    v_crs(Y, v, up->E[2]);
    v_scl(Y, up->E[1], 2 * v_dot(Y, up->E[1]));

    sol_rotate(up->E, Y, dt);
}
Пример #10
0
/* Compute the reflection of a vector on an object.
 *
 * the_object: The object to reflect off of.
 * position: The position hit.
 * direction: The direction of the vector to be reflected.
 *
 * Returns: the reflection of direction on the object at position.
 */
float* reflection_vector(object *the_object, float *position, float *direction) {
    float *reflection = (float*)malloc(sizeof(float)*3);
    float *normal = get_normal(the_object, position);
    v_scale(normal, -2*v_dot(direction, normal), reflection);
    v_add(reflection, direction, reflection);
    v_unit(reflection, reflection);
    
    return reflection;
}
Пример #11
0
static float v_sol(const float p[3], const float v[3], float r)
{
    float a = v_dot(v, v);
    float b = v_dot(v, p) * 2.0f;
    float c = v_dot(p, p) - r * r;
    float d = b * b - 4.0f * a * c;

    /* Testing for equality against zero is acceptable. */

    if (a == 0.0f) return LARGE;

    if      (d < 0.0f) return LARGE;
    else if (d > 0.0f)
    {
        float t0 = 0.5f * (-b - fsqrtf(d)) / a;
        float t1 = 0.5f * (-b + fsqrtf(d)) / a;
        float t  = (t0 < t1) ? t0 : t1;

        return (t < 0.0f) ? LARGE : t;
    }
    else return -b * 0.5f / a;
}
Пример #12
0
/*
 * Compute  the earliest  time and  position of  the intersection  of a
 * sphere and a plane.
 *
 * The sphere has radius R and moves along vector V from point P.  The
 * plane  moves  along  vector  W.   The  plane has  normal  N  and  is
 * positioned at distance D from the origin O along that normal.
 */
static float v_side(float Q[3],
                    const float o[3],
                    const float w[3],
                    const float n[3], float d,
                    const float p[3],
                    const float v[3], float r)
{
    float vn = v_dot(v, n);
    float wn = v_dot(w, n);
    float t  = LARGE;
    
    if (vn - wn < 0.0f)
    {
        float on = v_dot(o, n);
        float pn = v_dot(p, n);

        float u = (r + d + on - pn) / (vn - wn);
        float a = (    d + on - pn) / (vn - wn);

        if (0.0f <= u)
        {
            t = u;

            v_mad(Q, p, v, +t);
            v_mad(Q, Q, n, -r);
        }
        else if (0.0f <= a)
        {
            t = 0;

            v_mad(Q, p, v, +t);
            v_mad(Q, Q, n, -r);
        }
    }
    return t;
}
Пример #13
0
/*
double  vec1, vec2;      // the two vectors
int     degf;            // degreee/radian flag( 0=rad, 1= deg )
int     dim;               // vector dimension
*/
double v_angle(double vec1[], double vec2[], int degf, int dim, double zeroTol) {
    // Cleaned up by Hamid 11/2006
    double   mag1, mag2, dprod, cosang, angle;
    
    mag1 = v_magn(vec1, dim);
    mag2 = v_magn(vec2, dim);
    if (fabs(mag1-0.)<zeroTol || fabs(mag2-0.)<zeroTol) {
        angle =0.;
    }
    else {
        dprod = v_dot(vec1, vec2, dim);
        cosang = dprod / (mag1 * mag2);
        cosang = cosang < -1. ? -1. : cosang;
        cosang = cosang > +1. ? +1. : cosang;
        angle = acos(cosang);
        if (degf == 1)
            angle *= RAD_TO_DEG;
    }
    return angle;
}
Пример #14
0
/*
 * Compute the  earliest time  and position of  the intersection  of a
 * sphere and a vertex.
 *
 * The sphere has radius R and moves along vector V from point P.  The
 * vertex moves  along vector  W from point  Q in a  coordinate system
 * based at O.
 */
static float v_vert(float Q[3],
                    const float o[3],
                    const float q[3],
                    const float w[3],
                    const float p[3],
                    const float v[3], float r)
{
    float O[3], P[3], V[3];
    float t = LARGE;

    v_add(O, o, q);
    v_sub(P, p, O);
    v_sub(V, v, w);

    if (v_dot(P, V) < 0.0f)
    {
        t = v_sol(P, V, r);

        if (t < LARGE)
            v_mad(Q, O, w, t);
    }
    return t;
}
Пример #15
0
int main(int argc, char **argv)
{
	COORD cord[3];
	float a,b;
	
	scanf("%f %f %f %f %f %f %f", &cord[0].x, &cord[0].y, &cord[0].z, &cord[1].x, &cord[1].y, &cord[1].z, &a);
	
	printf("\nv1 = ( %f , %f , %f)", cord[0].x, cord[0].y, cord[0].z);
	printf("\nv2 = ( %f , %f , %f)", cord[1].x, cord[1].y, cord[1].z);
	printf("\na =  %f ", a);

	cord[2] = v_sum(&cord[0],&cord[1]);
	printf("\nv1+v2 = ( %f , %f , %f )", cord[2].x, cord[2].y, cord[2].z);

	cord[2] = v_dif(&cord[0],&cord[1]);
	printf("\nv1-v2 = ( %f , %f , %f )", cord[2].x, cord[2].y, cord[2].z);

	b = v_dot(&cord[0],&cord[1]);
	printf("\nv1.v2 =  %f ", b);

	cord[2] = v_prod(&a,&cord[0]);
	printf("\na v1 = ( %f , %f , %f )", cord[2].x, cord[2].y, cord[2].z);

	cord[2] = v_cross(&cord[0],&cord[1]);
	printf("\nv1 x v2 = ( %f , %f , %f )", cord[2].x, cord[2].y, cord[2].z);

	b = v_mod_2(&cord[0]);
	printf("\nv1^2 =  %f ", b);

	b = v_mod(&cord[0]);
	printf("\n|v1| =  %f ", b);

	printf("\n\n");

	return(0);

}
Пример #16
0
/* init
 */
int init(void) {
	int i,num_vertex,width,height;
	float *vertex;
	unsigned char *data;
	float rmax;
	vec3 min,max;
    vec4 plane_s = { 1.0, 0.0, 0.0, 0.0 };
    vec4 plane_t = { 0.0, 1.0, 0.0, 0.0 };
    vec4 plane_r = { 0.0, 0.0, 1.0, 0.0 };
    vec4 plane_q = { 0.0, 0.0, 0.0, 1.0 };
	GLenum err;

	err = glewInit();
	if (GLEW_OK != err)
	{
		fprintf(stderr, "glewInit() error: %s\n", glewGetErrorString(err));
	}

	glClearDepth(1);
    glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
    glEnable(GL_LIGHT0);
	glPointSize(4);
	glTexGenfv(GL_S,GL_EYE_PLANE,plane_s);
	glTexGenfv(GL_T,GL_EYE_PLANE,plane_t);
	glTexGenfv(GL_R,GL_EYE_PLANE,plane_r);
	glTexGenfv(GL_Q,GL_EYE_PLANE,plane_q);
	glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
	glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
	glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
	glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);

	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
	glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,SIZE,SIZE,0,GL_RGB,
		GL_UNSIGNED_BYTE,NULL);
	
	glGenTextures(1,&texture_id);
	glBindTexture(GL_TEXTURE_2D,texture_id);
	if((data = load_jpeg("data/ground.jpg",&width,&height))) {
		glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,
			GL_LINEAR_MIPMAP_LINEAR);
		glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,
			GL_LINEAR_MIPMAP_LINEAR);
		gluBuild2DMipmaps(GL_TEXTURE_2D,4,width,height,GL_RGBA,
			GL_UNSIGNED_BYTE,data);
		free(data);
	}
	
	vertex = load_3ds("data/mesh.3ds",&num_vertex);
	if(!vertex) return -1;
	
	v_set(999999,999999,999999,min);
	v_set(-999999,-999999,-999999,max);
    for(i = 0; i < num_vertex; i++) {
		int j;
		float *v = &vertex[i << 3];
		for(j = 0; j < 3; j++) {
			if(min[j] > v[j]) min[j] = v[j];
			if(max[j] < v[j]) max[j] = v[j];
		}
    }
	v_add(min,max,min);
	v_scale(min,0.5,min);
    for(i = 0; i < num_vertex; i++) {
        v_sub(&vertex[i << 3],min,&vertex[i << 3]);
    }
    for(i = 0, rmax = 0; i < num_vertex; i++) {
        float r = sqrt(v_dot(&vertex[i << 3],&vertex[i << 3]));
		if(r > rmax) rmax = r;
    }
	rmax = 0.8 / rmax;
    for(i = 0; i < num_vertex; i++) {
        v_scale(&vertex[i << 3],rmax,&vertex[i << 3]);
    }
	
    mesh_id = glGenLists(1);
	glNewList(mesh_id,GL_COMPILE);
    glBegin(GL_TRIANGLES);
    for(i = 0; i < num_vertex; i++) {
        glNormal3fv((float*)&vertex[i << 3] + 3);
        glVertex3fv((float*)&vertex[i << 3]);
    }
    glEnd();
    glEndList();
	
	vertex = load_3ds("data/ground.3ds",&num_vertex);
	if(!vertex) return -1;
	
    ground_id = glGenLists(1);
	glNewList(ground_id,GL_COMPILE);
    glBegin(GL_TRIANGLES);
    for(i = 0; i < num_vertex; i++) {
		glTexCoord2fv((float*)&vertex[i << 3] + 6);
		glNormal3fv((float*)&vertex[i << 3] + 3);
        glVertex3fv((float*)&vertex[i << 3]);
    }
    glEnd();
    glEndList();
	
	image = malloc(SIZE * SIZE * 4);
	
	return 0;
}
Пример #17
0
/* Third version of draw triangle uses a z_buffer
	And we're using flat shading 
	clear_z_buffer needs to be run in the main loop before every frame. */
void draw_triangle3(int *a,int *b,int *c,vect_t pos,vect_t rot,rgb color){
	int x0,y0,x1,y1,x2,y2;
	// this is is the format that the triangles should be passed to us already 
	vect_t x={a[0],a[1],a[2]+Z};
	vect_t y={b[0],b[1],b[2]+Z};
	vect_t z={c[0],c[1],c[2]+Z};

// Lighting	
	vect_t n=v_norm(v_cross(x,y));
//	vect_t l=v_sub(cam.pos,x);
	vect_t l=cam.pos;
	double lum=1.0;

//	if( lum < 0 ) return 0; 
	rgb colors[3];



	point p[3];

	x=v_rot(x,rot);
	y=v_rot(y,rot);
	z=v_rot(z,rot);
// should we do the translation here as well does this make sense?  
	x=v_add(x,pos);
	y=v_add(y,pos);
	z=v_add(z,pos);

	double lums[3];
	lums[0]=v_dot(l,x)/(v_len(l)*v_len(x));
	lums[1]=v_dot(l,y)/(v_len(l)*v_len(y));
	lums[2]=v_dot(l,z)/(v_len(l)*v_len(z));

#if 1
	for(int i=0;i<3;i++){
	#if 0 
		lum=lums[i];
		if( lum < 0 ) lum=0;
	#else 
		lum=1.0;
	#endif 

		colors[i].r=clip(color.r*lum);
		colors[i].g=clip(color.g*lum);
		colors[i].b=clip(color.b*lum);
	}
#else 
	for(int i=0;i<3;i++){
		colors[i].r=color.r;
		colors[i].g=color.g;
		colors[i].b=color.b;
	}
#endif 


	int q,w,e;
	q=project_coord(x,&p[0].x,&p[0].y);
	w=project_coord(y,&p[1].x,&p[1].y);
	e=project_coord(z,&p[2].x,&p[2].y);

	if(outside_of_screen(p)){
		return;
	}

	rgb ca[3];
	ca[0]=ca[1]=ca[2]=color;	

	vect_t v3[3];
	v3[0]=x; v3[1]=y; v3[2]=z;

	double distances[3];
	
	// introduce max distance of 5000 
	distances[0]=clipfloat(v_len(v_sub(x,cam.pos)),0,MAX_DIST)/MAX_DIST;	
	distances[1]=clipfloat(v_len(v_sub(y,cam.pos)),0,MAX_DIST)/MAX_DIST;	
	distances[2]=clipfloat(v_len(v_sub(z,cam.pos)),0,MAX_DIST)/MAX_DIST;	

/*	
	distances[0]=v_len(v_sub(z,cam.pos));	
	distances[1]=v_len(v_sub(y,cam.pos));	
	distances[2]=v_len(v_sub(x,cam.pos));	
		*/


	draw_triangle_gradient_new(p,v3,distances,colors);	
#if 0
	draw_line_color(p[0].x,p[0].y,p[1].x,p[1].y,black);
	draw_line_color(p[1].x,p[1].y,p[2].x,p[2].y,black);
	draw_line_color(p[1].x,p[1].y,p[0].x,p[0].y,black);
#endif 
}
Пример #18
0
static void game_update_view(float dt)
{
    float dc = view_dc * (jump_b ? 2.0f * fabsf(jump_dt - 0.5f) : 1.0f);
    float dx = view_ry * dt * 5.0f;
    float k;

    view_a += view_ry * dt * 90.f;

    /* Center the view about the ball. */

    v_cpy(view_c, file.uv->p);
    v_inv(view_v, file.uv->v);

    switch (config_get_d(CONFIG_CAMERA))
    {
    case 1: /* Camera 1:  Viewpoint chases the ball position. */

        v_sub(view_e[2], view_p, view_c);
        break;

    case 2: /* Camera 2: View vector is given by view angle. */

        view_e[2][0] = fsinf(V_RAD(view_a));
        view_e[2][1] = 0.f;
        view_e[2][2] = fcosf(V_RAD(view_a));

        dx = 0.0f;

        break;

    default: /* Default: View vector approaches the ball velocity vector. */

        k = v_dot(view_v, view_v);

        v_sub(view_e[2], view_p, view_c);
        v_mad(view_e[2], view_e[2], view_v, k * dt / 4);

        break;
    }

    /* Orthonormalize the basis of the view in its new position. */

    v_crs(view_e[0], view_e[1], view_e[2]);
    v_crs(view_e[2], view_e[0], view_e[1]);
    v_nrm(view_e[0], view_e[0]);
    v_nrm(view_e[2], view_e[2]);

    /* Compute the new view position. */

    k = 1.0f + v_dot(view_e[2], view_v) / 10.0f;

    view_k = view_k + (k - view_k) * dt;

    if (view_k < 0.5) view_k = 0.5;

    v_cpy(view_p, file.uv->p);
    v_mad(view_p, view_p, view_e[0], dx      * view_k);
    v_mad(view_p, view_p, view_e[1], view_dp * view_k);
    v_mad(view_p, view_p, view_e[2], view_dz * view_k);

    /* Compute the new view center. */

    v_cpy(view_c, file.uv->p);
    v_mad(view_c, view_c, view_e[1], dc);

    /* Note the current view angle. */

    view_a = V_DEG(fatan2f(view_e[2][0], view_e[2][2]));
}
Пример #19
0
void MoveR::IK4(const point& P)
{
  //ROS_INFO("IK\n");
  double th0=0,th1=0,th2=0,th3=0;
  double x=P.x.data;
  double y=P.y.data;
  double z=P.z.data;
  double p[3]={x,y,z};
  double temp1=pow(x,2)+pow(y,2)+pow(z,2);
  double norm_p=pow(temp1,0.5);
  double b=acos((pow(lup,2)+pow(ldn,2)-pow(norm_p,2))/(2*lup*ldn));
  th3=PI-b;  
  double a=asin((ldn/norm_p)*sin(b));
  double s[3]={0,0,0};
  double u_z[3]={0,0,1};
  double p_s[3];
  v_sub(p,s,p_s,3);
  //ROS_INFO("p\n");
  //v_print(p,3);	
  //ROS_INFO("s\n");
  //v_print(s,3);	
  //ROS_INFO("p-s\n");
  //v_print(p_s,3);	

  double norm_p_s=pow(pow(p_s[0],2)+pow(p_s[1],2)+pow(p_s[2],2),0.5);
  double u_n[3]={p_s[0]/norm_p_s,p_s[1]/norm_p_s,p_s[2]/norm_p_s};
  
  //ROS_INFO("u_n\n");
  //v_print(u_n,3);	
  double tmp[3];
  v_scalar_multip(v_dot(u_z,u_n,3),u_n,tmp,3);
  double u[3],u_u[3];
  //v_add(u_z,tmp,u,3);
  
  //u correct on 2/17
  v_cross(u_n,u_z,u);

  double norm_u=pow(pow(u[0],2)+pow(u[1],2)+pow(u[2],2),0.5);
  v_scalar_multip(1/norm_u,u,u_u,3);

  //ROS_INFO("u_u \n");
  //v_print(u_u,3);	
  double v[3],u_v[3];
  v_cross(u_n,u_u,v);
  double norm_v=pow(pow(v[0],2)+pow(v[1],2)+pow(v[2],2),0.5);
  v_scalar_multip(1/norm_v,v,u_v,3);

  //ROS_INFO("u_v \n");
  //v_print(u_v,3);	

  double c[3];
  v_scalar_multip(cos(a)*lup,u_n,tmp,3);
  v_add(s,tmp,c,3);
  double r=lup*sin(a);
  //double fi=PI/2;
  ROS_INFO("b %f\n",b);

  ROS_INFO("a %f\n",a);
  double tmp1[3],tmp2[3];
  v_scalar_multip(cos(fi),u_u,tmp1,3);
  v_scalar_multip(sin(fi),u_v,tmp2,3);
  v_add(tmp1,tmp2,tmp,3);
  v_scalar_multip(r,tmp,tmp,3);
  double e[3];
  v_add(c,tmp,e,3);
  ROS_INFO("u_u \n");
  v_print(u_u,3);	

  double ex=e[0],ey=e[1],ez=e[2];
  ROS_INFO("ex %f\n",ex);
  ROS_INFO("ey %f\n",ey);
  ROS_INFO("ez %f\n",ez);

  if(ex>=0&&ey<0)
    th0=atan((double)abs(ex)/abs(ey));
  else if(ex>=0&&ey>=0)
      th0=PI-atan((double)abs(ex)/abs(ey));
    else if(ex<0&&ey>=0)
        th0=PI+atan((double)abs(ex)/abs(ey));
      else if(ex<0&&ey<0)
          th0=-atan((double)abs(ex)/abs(ey));
  double temp2=pow(pow(ex,2)+pow(ey,2),0.5);
  if(ez>=0)
    th1=-atan((double)abs(ez)/temp2);
  else if(ez<0)
    th1=atan((double)abs(ez)/temp2);

   //ROS_INFO("IK:th0 %f\n",th0);
   //ROS_INFO("IK:th1 %f\n",th1);
   //ROS_INFO("th3 %f\n",th3);


  th2=atan2(-x*sin(th0)*sin(th1)+y*cos(th0)*sin(th1)-z*cos(th1),x*cos(th0)+y*sin(th0));
  ROS_INFO("x %f  y %f  z %f\n",x,y,z);

  ROS_INFO("th0 %f  th1 %f  th2 %f  th3 %f  fi% f\n",th0,th1,th2,th3,fi);

  if(isnan(th0)||isnan(th1)||isnan(th2)||isnan(th3)||th0>TH0_MAX||th0<TH0_MIN||th1>TH1_MAX||th1<TH1_MIN||th3>TH3_MAX||th3<TH3_MIN){
    ROS_INFO("Fail and dont move\n");
   }
  else{
    ROS_INFO("go move move time=%f\n",move_time);

    arm_angle.joint0.angle = th0;
    arm_angle.joint0.duration = move_time;
    arm_angle.joint1.angle = th1;
    arm_angle.joint1.duration = move_time;
    arm_angle.joint2.angle = th2;
    arm_angle.joint2.duration = move_time;
    arm_angle.joint3.angle = th3;
    arm_angle.joint3.duration = move_time;
  }
}
Пример #20
0
/*
 * Compute the  earliest time  and position of  the intersection  of a
 * sphere and an edge.
 *
 * The sphere has radius R and moves along vector V from point P.  The
 * edge moves along vector W from point Q in a coordinate system based
 * at O.  The edge extends along the length of vector U.
 */
static float v_edge(float Q[3],
                    const float o[3],
                    const float q[3],
                    const float u[3],
                    const float w[3],
                    const float p[3],
                    const float v[3], float r)
{
    float d[3], e[3];
    float P[3], V[3];
    float du, eu, uu, s, t;

    v_sub(d, p, o);
    v_sub(d, d, q);
    v_sub(e, v, w);

    /*
     * Think projections.  Vectors D, extending from the edge vertex Q
     * to the sphere,  and E, the relative velocity  of sphere wrt the
     * edge, are  made orthogonal to  the edge vector U.   Division of
     * the  dot products  is required  to obtain  the  true projection
     * ratios since U does not have unit length.
     */

    du = v_dot(d, u);
    eu = v_dot(e, u);
    uu = v_dot(u, u);

    v_mad(P, d, u, -du / uu);

    /* First, test for intersection. */

    if (v_dot(P, P) < r * r)
    {
        /* The sphere already intersects the line of the edge. */

        if (du < 0 || du > uu)
        {
            /*
             * The sphere is behind the endpoints of the edge, and
             * can't hit the edge without hitting the vertices first.
             */
            return LARGE;
        }

        /* The sphere already intersects the edge. */

        if (v_dot(P, e) >= 0)
        {
            /* Moving apart. */
            return LARGE;
        }

        v_nrm(P, P);
        v_mad(Q, p, P, -r);

        return 0;
    }

    v_mad(V, e, u, -eu / uu);

    t = v_sol(P, V, r);
    s = (du + eu * t) / uu; /* Projection of D + E * t on U. */

    if (0.0f <= t && t < LARGE && 0.0f < s && s < 1.0f)
    {
        v_mad(d, o, w, t);
        v_mad(e, q, u, s);
        v_add(Q, e, d);
    }
    else
        t = LARGE;

    return t;
}
Пример #21
0
int Reaching::LinkDistanceToObject(int link, EnvironmentObject *obj, float *dist, 
			 float *point, cart_vec_t& contact_vector){
  cart_vec_t& objPos;
  cart_vec_t& lowerLinkExtr;
  cart_vec_t& upperLinkExtr;
  cart_vec_t& v1,v2,linkv,u,vertexPos,v_tmp,tmp3;
  CMatrix4_t ref,tmpmat,tmpmat2;
  cart_vec_t& s1,s2;
  int i,j,k,dir1,dir2,pindex,min_i;
  float alldists[12]; //closest distance to each edge
  float allpoints[24]; // closest pair of points on each edge
  float min_dist;
  int s3[3];

  for (i=0;i<12;i++){
    alldists[i]=FLT_MAX;
  }

  switch(link){
  case 1:
    v_clear(upperLinkExtr);
    ElbowPosition(pos_angle,lowerLinkExtr);
    break;
  case 2:
    ElbowPosition(pos_angle,upperLinkExtr);
    v_copy(pos_cart,lowerLinkExtr);
    break;
  default:
    cout<<"unvalid link number"<< endl;
  }
  if(!obj){
    return 0;
  }
  //  v_sub(obj->solid->m_position, shoulder_abs_pos,objPos);
    Abs2LocalRef(obj->GetPosition(), objPos);
  //  cout<<"ule: ";coutvec(upperLinkExtr);
  //  cout<<"lle: ";coutvec(lowerLinkExtr);
    //  coutvec(objPos);
  v_sub(lowerLinkExtr,objPos,v1);
  v_sub(upperLinkExtr,objPos,v2);
  //m_transpose(obj->solid->m_ref.m_orient,ref); //stupid to do it each time
  m_copy(obj->solid->m_ref.m_orient,ref); //stupid to do it each time
  v_clear(s3);
  
  //checking when two parallel sides must me checked
  for(i=0;i<3;i++){
    s1[i] = v_dot(v1, &ref[i*4]);
    s2[i] = v_dot(v2, &ref[i*4]);
    if (s1[i]*s2[i]>=0){
      s3[i] = sign(s1[i]+s2[i]);
    }
  }
  //    cout << "s3: ";coutvec(s3);
  m_copy(ref,tmpmat);
  for(i=0;i<3;i++){
    if(s3[i]){
      v_sub(lowerLinkExtr,upperLinkExtr,linkv);
      v_scale(obj->solid->m_size,-0.5,u);
      u[i] *=-s3[i];
      v_add(objPos,u,vertexPos);
      //      cout<<"vPos "<<i<<": ";coutvec(vertexPos);
      v_scale(&(ref[i*4]),s3[i],&(tmpmat[i*4]));
      // cout<<"norm "<<i<<": ";coutvec((tmpmat+i*4));
      m_inverse(tmpmat,tmpmat2);
      if(v_dot(&(tmpmat[i*4]),linkv)<0){
	v_sub(lowerLinkExtr,vertexPos,v_tmp);
	*point = 1;
      }
      else{
	v_sub(upperLinkExtr,vertexPos,v_tmp);
	*point = 0;
      }
      //      cout<<"linkv ";coutvec(linkv);
      // cout <<"pt "<<*point<<endl;
	
      
// #ifdef OLD_AV
//       v_copy(linkv,(cart_vec_t&)&tmpmat[i*4]);
//       m_inverse(tmpmat,tmpmat2);
//       v_sub(upperLinkExtr,vertexPos,tmp2);
      // tmp3 should contain the intersection coordinates in
      // the referential defined by the edges of the surface 
      v_transform_normal(v_tmp,tmpmat2,tmp3); 
      // cout<<"tmp3 ";coutvec(tmp3);
      if(tmp3[(i+1)%3]>=0 && tmp3[(i+2)%3]>=0 // the link points to the rectangle
	 && tmp3[(i+1)%3]<=obj->solid->m_size[(i+1)%3] && 
	 tmp3[(i+2)%3]<=obj->solid->m_size[(i+2)%3]){
	if(tmp3[i]<0){
	  return 0; // there is a collision
	}
	else{
	  *dist = tmp3[i];
	  v_copy(&(tmpmat[i*4]),contact_vector);
	  v_scale(contact_vector,*dist,contact_vector);
	  return 1;
	}
      }
    }
  }
  // the link does not point to a rectangle -> look for the edges
  v_scale(obj->solid->m_size,-0.5,u);
  for(i=0;i<3;i++){// each kind of edge
      dir1 = s3[(i+1)%3]; 
      dir2 = s3[(i+2)%3];
    for(j=0;j<2;j++){ 
      if(dir1 == 0 || dir1==2*j-1){ //edges of this face must be computed
	for(k=0;k<2;k++){
	  if(dir2 == 0 || dir2==2*k-1){ //edges of this face must be computed
	    v_copy(u,v_tmp);
	    v_tmp[(i+1)%3]*=-(2*j-1);
	    v_tmp[(i+2)%3]*=-(2*k-1);
	    v_add(objPos,v_tmp,vertexPos);
	    v_scale(&(ref[4*i]),obj->solid->m_size[i],v1); // edge with the right length
	    pindex = 4*i+2*j+k;
	    FindSegmentsNearestPoints(vertexPos,v1,upperLinkExtr,linkv,&(allpoints[2*pindex]),&(allpoints[2*pindex+1]),&(alldists[pindex]));
	//     cout<<"i:"<<i<<" j:"<<j<<" k:"<<k<<"dist "<<alldists[pindex]<<endl;
// 	    cout<<"v1:";coutvec(v1);
// 	    cout<<"ref:";coutvec((&(ref[4*i])));
// 	    cout<<"vP:";coutvec(vertexPos);
	  }
	}
      }
    }
  }
  //looking for the min
  min_dist = alldists[0];
  min_i = 0;
  for(i=1;i<12;i++){
    if(alldists[i] < min_dist){
      min_dist = alldists[i];
      min_i = i;
    }
  }
  // returning the min distance
  *dist = min_dist;
  *point = allpoints[2*min_i+1];
  v_scale(linkv,*point,v1);
  v_add(upperLinkExtr,v1,v2); // nearest point on link
  k = min_i%2; //retrieving the right edge
  j = ((min_i-k)%4)/2;
  i = min_i/4; 
  //  cout<<"ijk: "<<i<<" "<<j<<" "<<k<<endl;
  v_copy(u,v_tmp);
  v_tmp[(i+1)%3]*=-(2*j-1);
  v_tmp[(i+2)%3]*=-(2*k-1); 
  v_add(objPos,v_tmp,vertexPos); // starting vertex of the edge
  v_scale(&(ref[3*1]),allpoints[2*min_i]*(obj->solid->m_size[min_i]),v1);
  v_add(vertexPos,v1,v1); // nearest point on solid
  v_sub(v2,v1,contact_vector);
  return 1;
}
Пример #22
0
float sol_step(struct s_vary *vary, const float *g, float dt, int ui, int *m)
{
    float P[3], V[3], v[3], r[3], a[3], d, e, nt, b = 0.0f, tt = dt, t;
    int c;

    union cmd cmd;

    if (ui < vary->uc)
    {
        struct v_ball *up = vary->uv + ui;

        /* If the ball is in contact with a surface, apply friction. */

        v_cpy(a, up->v);
        v_cpy(v, up->v);
        v_cpy(up->v, g);

        if (m && sol_test_file(tt, P, V, up, vary) < 0.0005f)
        {
            v_cpy(up->v, v);
            v_sub(r, P, up->p);

            t = v_len(r) * v_len(g);
            if (t == 0.f)
            {
              t = SMALL;
            }
            
            if ((d = v_dot(r, g) / t) > 0.999f)
            {
                if ((e = (v_len(up->v) - dt)) > 0.0f)
                {
                    /* Scale the linear velocity. */

                    v_nrm(up->v, up->v);
                    v_scl(up->v, up->v, e);

                    /* Scale the angular velocity. */

                    v_sub(v, V, up->v);
                    v_crs(up->w, v, r);
                    v_scl(up->w, up->w, -1.0f / (up->r * up->r));
                }
                else
                {
                    /* Friction has brought the ball to a stop. */

                    up->v[0] = 0.0f;
                    up->v[1] = 0.0f;
                    up->v[2] = 0.0f;

                    (*m)++;
                }
            }
            else v_mad(up->v, v, g, tt);
        }
        else v_mad(up->v, v, g, tt);

        /* Test for collision. */

        for (c = 16; c > 0 && tt > 0; c--)
        {
            float st;
            int mi, ms;

            /* HACK: avoid stepping across path changes. */

            st = tt;

            for (mi = 0; mi < vary->mc; mi++)
            {
                struct v_move *mp = vary->mv + mi;
                struct v_path *pp = vary->pv + mp->pi;

                if (!pp->f)
                    continue;

                if (mp->tm + ms_peek(st) > pp->base->tm)
                    st = MS_TO_TIME(pp->base->tm - mp->tm);
            }

            /* Miss collisions if we reach the iteration limit. */

            if (c > 1)
                nt = sol_test_file(st, P, V, up, vary);
            else
                nt = tt;

            cmd.type       = CMD_STEP_SIMULATION;
            cmd.stepsim.dt = nt;
            sol_cmd_enq(&cmd);

            ms = ms_step(nt);

            sol_move_step(vary, nt, ms);
            sol_swch_step(vary, nt, ms);
            sol_ball_step(vary, nt);

            if (nt < st)
                if (b < (d = sol_bounce(up, P, V, nt)))
                    b = d;

            tt -= nt;
        }

        v_sub(a, up->v, a);

        sol_pendulum(up, a, g, dt);
    }

    return b;
}
Пример #23
0
void game_set_fly(float k)
{
    struct s_vary *fp = &file.vary;

    float  x[3] = { 1.f, 0.f, 0.f };
    float  y[3] = { 0.f, 1.f, 0.f };
    float  z[3] = { 0.f, 0.f, 1.f };
    float c0[3] = { 0.f, 0.f, 0.f };
    float p0[3] = { 0.f, 0.f, 0.f };
    float c1[3] = { 0.f, 0.f, 0.f };
    float p1[3] = { 0.f, 0.f, 0.f };
    float  v[3];

    if (!state)
        return;

    v_cpy(view_e[0], x);
    v_cpy(view_e[1], y);

    if (fp->base->zc > 0)
        v_sub(view_e[2], fp->uv[ball].p, fp->base->zv[0].p);
    else
        v_cpy(view_e[2], z);

    if (fabs(v_dot(view_e[1], view_e[2])) > 0.999)
        v_cpy(view_e[2], z);

    v_crs(view_e[0], view_e[1], view_e[2]);
    v_crs(view_e[2], view_e[0], view_e[1]);

    v_nrm(view_e[0], view_e[0]);
    v_nrm(view_e[2], view_e[2]);

    /* k = 0.0 view is at the ball. */

    if (fp->uc > 0)
    {
        v_cpy(c0, fp->uv[ball].p);
        v_cpy(p0, fp->uv[ball].p);
    }

    v_mad(p0, p0, view_e[1], view_dy);
    v_mad(p0, p0, view_e[2], view_dz);

    /* k = +1.0 view is s_view 0 */

    if (k >= 0 && fp->base->wc > 0)
    {
        v_cpy(p1, fp->base->wv[0].p);
        v_cpy(c1, fp->base->wv[0].q);
    }

    /* k = -1.0 view is s_view 1 */

    if (k <= 0 && fp->base->wc > 1)
    {
        v_cpy(p1, fp->base->wv[1].p);
        v_cpy(c1, fp->base->wv[1].q);
    }

    /* Interpolate the views. */

    v_sub(v, p1, p0);
    v_mad(view_p, p0, v, k * k);

    v_sub(v, c1, c0);
    v_mad(view_c, c0, v, k * k);

    /* Orthonormalize the view basis. */

    v_sub(view_e[2], view_p, view_c);
    v_crs(view_e[0], view_e[1], view_e[2]);
    v_crs(view_e[2], view_e[0], view_e[1]);
    v_nrm(view_e[0], view_e[0]);
    v_nrm(view_e[2], view_e[2]);

    view_a = V_DEG(fatan2f(view_e[2][0], view_e[2][2]));
}
Пример #24
0
void game_update_view(float dt)
{
    const float y[3] = { 0.f, 1.f, 0.f };

    float dy;
    float dz;
    float k;
    float e[3];
    float d[3];
    float s = 2.f * dt;

    if (!state)
        return;

    /* Center the view about the ball. */

    v_cpy(view_c, file.vary.uv[ball].p);
    v_inv(view_v, file.vary.uv[ball].v);

    switch (config_get_d(CONFIG_CAMERA))
    {
    case 2:
        /* Camera 2: View vector is given by view angle. */

        view_e[2][0] = fsinf(V_RAD(view_a));
        view_e[2][1] = 0.f;
        view_e[2][2] = fcosf(V_RAD(view_a));

        s = 1.f;
        break;

    default:
        /* View vector approaches the ball velocity vector. */

        v_mad(e, view_v, y, v_dot(view_v, y));
        v_inv(e, e);

        k = v_dot(view_v, view_v);

        v_sub(view_e[2], view_p, view_c);
        v_mad(view_e[2], view_e[2], view_v, k * dt * 0.1f);
    }

    /* Orthonormalize the basis of the view in its new position. */

    v_crs(view_e[0], view_e[1], view_e[2]);
    v_crs(view_e[2], view_e[0], view_e[1]);
    v_nrm(view_e[0], view_e[0]);
    v_nrm(view_e[2], view_e[2]);

    /* The current view (dy, dz) approaches the ideal (view_dy, view_dz). */

    v_sub(d, view_p, view_c);

    dy = v_dot(view_e[1], d);
    dz = v_dot(view_e[2], d);

    dy += (view_dy - dy) * s;
    dz += (view_dz - dz) * s;

    /* Compute the new view position. */

    view_p[0] = view_p[1] = view_p[2] = 0.f;

    v_mad(view_p, view_c, view_e[1], dy);
    v_mad(view_p, view_p, view_e[2], dz);

    view_a = V_DEG(fatan2f(view_e[2][0], view_e[2][2]));
}
Пример #25
0
//TODO: don't pass scene....
void illuminate(vector point, Object* s, vector normal, Scene scene, float initColor[], vector color){
//    printf("ic: %f %f %f\n", initColor[0],initColor[1],initColor[2]);
    //construct ray from the point in space
    //where this collision occured
    float diffuse=0; 
    float specular=0;
    for(int i=0; i<scene.numLights; i++){
        //TODO: divide by type of light
        switch(scene.lights[i]->type){
            case DIRECTIONAL:
                {
                    DirLight* dl = static_cast<DirLight*>(scene.lights[i]->li);
                    vector dir;
                    v_copy(dir, dl->dir);
                    v_normalize(dir);
                    v_scale(dir, dir, -1);
                    
                    vector re, e;
                    v_subtract(e, scene.cam.pos, point);
                    v_normalize(e);
                    v_scale(re, normal, v_dot(e, normal)*2);
                    v_subtract(re, re, e);
                    v_normalize(re);
                    float dotprod = v_dot(dir, normal);
                    if(dotprod>0){
                        Ray rayToLight;
                        v_copy(rayToLight.o, point);
                        v_copy(rayToLight.d, dir);
                        
                        float scale = shadowRay(rayToLight);
                        diffuse+=dotprod*dl->i;
                        float x=-1;
                        if(s->n!=0){
                            float dotprodSpec = v_dot(re,dir);
                            if(dotprodSpec<0)
                                dotprodSpec=0;
                            x = pow(dotprodSpec, s->n)*dl->i;
                        }
                        if(x>0)
                            specular+=x;
                        diffuse*=scale;
                        specular*=scale;
                    }

                }
                break;
            case SPOT:
                {
                    SpotLight* sl = static_cast<SpotLight*>(scene.lights[i]->li);
                    vector lightPoint;
                    v_copy(lightPoint, sl->pos);
                    vector lightVector;
                    vector lightToPoint;
                    v_subtract(lightVector,lightPoint,point);
                    v_normalize(lightVector);
                    
                    vector re, e;
                    v_subtract(e, scene.cam.pos, point);
                    v_normalize(e);
                    v_scale(re, normal, v_dot(e, normal)*2);
                    v_subtract(re, re, e);
                    v_normalize(re);
                    float dotprod = v_dot(lightVector,normal);
                    //if positive, we are facing the light
                    if(dotprod>0){
                        Ray rayToLight;
                        v_copy(rayToLight.o, point);
                        v_copy(rayToLight.d, lightVector);
                        
                        float scale = shadowRay(rayToLight);
                        vector D;
                        vector dist;
                        v_subtract(dist,lightPoint,point);
                        v_copy(D,sl->dir);
                        v_scale(D,D,-1);
                        float intensity = pow(v_dot(D,lightVector), sl->falloff);
                        if(intensity<0)
                            intensity=0;
                        diffuse+=dotprod*intensity*sl->i;
                        float x=-1;
                        if(s->n!=0){
                            float dotprodSpec = v_dot(re,lightVector);
                            if(dotprodSpec<0)
                                dotprodSpec=0;
                            x = pow(dotprodSpec, s->n)*intensity*sl->i;
                        }
                        if(x>0){
                            specular+=x;
                        }
                        diffuse*=scale;
                        specular*=scale;
                    }
                }
                break;
            case POINT:
                {
                    PointLight* pl = static_cast<PointLight*>(scene.lights[i]->li);
                    vector lightPoint;
                    v_copy(lightPoint, pl->pos);
                    vector lightVector;
                    
                    v_subtract(lightVector,lightPoint,point);
                    v_normalize(lightVector);
                    lightVector[3]=0;
                    point[3]=1;
                    
                    vector re, e;
                    v_subtract(e, scene.cam.pos, point);
                    v_normalize(e);
                    v_scale(re, normal, v_dot(e, normal)*2);
                    v_subtract(re, re, e);
                    v_normalize(re);
                    float dotprod = v_dot(lightVector,normal);
                    //if positive, we are facing the light
                    if(dotprod>0){
                        Ray rayToLight;
                        v_copy(rayToLight.o, point);
                        if(pl->size==0){
                            v_copy(rayToLight.d, lightVector);
                        } else {
                            vector lightTemp;
                            v_subtract(lightTemp,lightPoint,point);
//                            printf("Pre Jitter:\n");
//                            v_print(lightTemp);
//                            printf("size: %f\n",pl->size);
                            float sx=randFloat(-pl->size,pl->size);
                            float sy=randFloat(-pl->size,pl->size);
                            float sz=randFloat(-pl->size,pl->size);
                            vector jitter;
                            jitter[0]=sx;
                            jitter[1]=sy;
                            jitter[2]=sz;
//                            v_print(jitter);
                            v_add(lightTemp, lightTemp, jitter);
//                            printf("Post Jitter:\n");
//                            v_print(lightTemp);
                            v_normalize(lightTemp);
                            lightTemp[3]=0;
                            v_copy(rayToLight.d, lightTemp);
                        }
                        float scale = shadowRay(rayToLight);
                        diffuse+=dotprod*pl->i;
                        float x=-1;
                        if(s->n!=0){
                            float dotprodSpec = v_dot(re,lightVector);
                            if(dotprodSpec<0)
                                dotprodSpec=0;
                            x = pow(dotprodSpec, s->n)*pl->i;
                        }
                        if(x>0){
                            specular+=x;
                        }
                        diffuse*=scale;
                        specular*=scale;
                    }
                }
                break;
        }
    }
        
    color[0]=s->kd*(scene.amb + diffuse)*initColor[0];
    color[0]+=s->ks*specular;
    color[1]=s->kd*(scene.amb + diffuse)*initColor[1];
    color[1]+=s->ks*specular;
    color[2]=s->kd*(scene.amb + diffuse)*initColor[2];
    color[2]+=s->ks*specular;
    //printf("c %f\n",color[0]);
    
} 
Пример #26
-1
static void game_update_view(float dt)
{
    float dc = view.dc * (jump_b > 0 ? 2.0f * fabsf(jump_dt - 0.5f) : 1.0f);
    float da = input_get_r() * dt * 90.0f;
    float k;

    float M[16], v[3], Y[3] = { 0.0f, 1.0f, 0.0f };
    float view_v[3];

    float spd = (float) cam_speed(input_get_c()) / 1000.0f;

    /* Track manual rotation time. */

    if (da == 0.0f)
    {
        if (view_time < 0.0f)
        {
            /* Transition time is influenced by activity time. */

            view_fade = CLAMP(VIEW_FADE_MIN, -view_time, VIEW_FADE_MAX);
            view_time = 0.0f;
        }

        /* Inactivity. */

        view_time += dt;
    }
    else
    {
        if (view_time > 0.0f)
        {
            view_fade = 0.0f;
            view_time = 0.0f;
        }

        /* Activity (yes, this is negative). */

        view_time -= dt;
    }

    /* Center the view about the ball. */

    v_cpy(view.c, vary.uv->p);

    view_v[0] = -vary.uv->v[0];
    view_v[1] =  0.0f;
    view_v[2] = -vary.uv->v[2];

    /* Compute view vector. */

    if (spd >= 0.0f)
    {
        /* Viewpoint chases ball position. */

        if (da == 0.0f)
        {
            float s;

            v_sub(view.e[2], view.p, view.c);
            v_nrm(view.e[2], view.e[2]);

            /* Gradually restore view vector convergence rate. */

            s = fpowf(view_time, 3.0f) / fpowf(view_fade, 3.0f);
            s = CLAMP(0.0f, s, 1.0f);

            v_mad(view.e[2], view.e[2], view_v, v_len(view_v) * spd * s * dt);
        }
    }
    else
    {
        /* View vector is given by view angle. */

        view.e[2][0] = fsinf(V_RAD(view.a));
        view.e[2][1] = 0.0;
        view.e[2][2] = fcosf(V_RAD(view.a));
    }

    /* Apply manual rotation. */

    if (da != 0.0f)
    {
        m_rot(M, Y, V_RAD(da));
        m_vxfm(v, M, view.e[2]);
        v_cpy(view.e[2], v);
    }

    /* Orthonormalize the new view reference frame. */

    v_crs(view.e[0], view.e[1], view.e[2]);
    v_crs(view.e[2], view.e[0], view.e[1]);
    v_nrm(view.e[0], view.e[0]);
    v_nrm(view.e[2], view.e[2]);

    /* Compute the new view position. */

    k = 1.0f + v_dot(view.e[2], view_v) / 10.0f;

    view_k = view_k + (k - view_k) * dt;

    if (view_k < 0.5) view_k = 0.5;

    v_scl(v,    view.e[1], view.dp * view_k);
    v_mad(v, v, view.e[2], view.dz * view_k);
    v_add(view.p, v, vary.uv->p);

    /* Compute the new view center. */

    v_cpy(view.c, vary.uv->p);
    v_mad(view.c, view.c, view.e[1], dc);

    /* Note the current view angle. */

    view.a = V_DEG(fatan2f(view.e[2][0], view.e[2][2]));

    game_cmd_updview();
}