Example #1
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);
}
Example #2
0
//nearest points between two segments given by pi+veci, results given in ratio of vec [0 1]
int Reaching::FindSegmentsNearestPoints(cart_vec_t& p1,cart_vec_t& vec1,cart_vec_t& p2,cart_vec_t& vec2, float *nearest_point1, float *nearest_point2, float *dist){
  CMatrix3_t mat;
  CMatrix3_t invmat;
  cart_vec_t& vec3,tmp,tmp1,tmp2,k,v2;
  int i; 
  m_identity(mat);
  v_cross(vec1,vec2,vec3);// check if vec1 and vec2 are not //
  if(v_squ_length(vec3)<0.00001){
    return 0;
  }

  v_scale(vec2,-1,v2);
  m_set_v3_column(vec1,0,mat);
  m_set_v3_column(v2,1,mat);
  m_set_v3_column(vec3,2,mat);
  m_inverse(mat,invmat);
  v_sub(p2,p1,tmp);
  v_transform_normal(tmp,invmat,k);
  for(i=0;i<2;i++){
    k[i] = max(min(1,k[i]),0);
  }
  v_scale(vec1,k[0],tmp);
  v_add(p1,tmp,tmp1);
  v_scale(vec2,k[1],tmp);
  v_add(p2,tmp,tmp2);
  v_sub(tmp2,tmp1,tmp);
  *dist=v_length(tmp);
  *nearest_point1 = k[0];
  *nearest_point2 = k[1];
  return 1;
}
Example #3
0
void Reaching::IncrementCartWeights(float factor){
  if (factor<0) return;
#ifdef DYN_WEIGHTS
  v_scale(base_weight_cart,factor,base_weight_cart);
#else
  v_scale(weight_cart,factor,weight_cart);
#endif
}
Example #4
0
void make_first_shell_centers(cVector *centers, int num_layers, float layer_thickness)
{
	// host vars
	cVector *ptr_centers;
	int x, x_zero, y, j, k, index=0;

	// init host vars
	x_zero = 15, y = 0;	
	
	// allocate memory
	
	// init pointers
	ptr_centers = centers;
	
	// do stuff
	for(k = 0; k < num_layers; k++)
	{
		x = (x_zero + 9*k) % num_layers;
		y = 0;
		for(j = 0; j < num_layers; j++, ptr_centers++, y++)
		{
			ptr_centers->x = x;
			ptr_centers->y = y;
			ptr_centers->z = k;
			//v_print_t(ptr_centers);
			v_scale(ptr_centers, layer_thickness, ptr_centers);
			x = (x + 3) % num_layers;
			index++;
		}
	}		
	// free memory
	
	// return value
}
Example #5
0
static void orthonormalize(float dcm[3][3])
{
	/* Orthogonalize the i and j unit vectors (DCMDraft2 Eqn. 19). */
	dcm_err = v_dotp(dcm[0], dcm[1]);
	v_scale(dcm[1], -dcm_err/2, dcm_d[0]);   /* i vector correction */
	v_scale(dcm[0], -dcm_err/2, dcm_d[1]);   /* i vector correction */
	v_add(dcm[0], dcm_d[0], dcm[0]);
	v_add(dcm[1], dcm_d[1], dcm[1]);

	/* k = i x j */
	v_crossp(dcm[0], dcm[1], dcm[2]);

	/* Normalize all three vectors. */
	v_norm(dcm[0]);
	v_norm(dcm[1]);
	v_norm(dcm[2]);
}
Example #6
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;
}
Example #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;
}
Example #8
0
void sm_frame(sm_t *sm,int from,int to,float frame) {
	int i,frame0,frame1;
	if(from == -1) from = 0;
	if(to == -1) to = sm->num_frame;
	frame0 = (int)frame;
	frame -= frame0;
	frame0 += from;
	if(frame0 >= to) frame0 = ((frame0 - from) % (to - from)) + from;
	frame1 = frame0 + 1;
	if(frame1 >= to) frame1 = from;
	for(i = 0; i < sm->num_bone; i++) {
		float m0[16],m1[16];
		float xyz0[3],xyz1[3],xyz[3],rot[4];
		v_scale(sm->frame[frame0][i].xyz,1.0 - frame,xyz0);
		v_scale(sm->frame[frame1][i].xyz,frame,xyz1);
		v_add(xyz0,xyz1,xyz);
		q_slerp(sm->frame[frame0][i].rot,sm->frame[frame1][i].rot,frame,rot);
		m_translate(xyz,m0);
		q_to_matrix(rot,m1);
		m_multiply(m0,m1,sm->bone[i].matrix);
	}
	for(i = 0; i < sm->num_surface; i++) {
		int j;
		sm_surface_t *s = sm->surface[i];
		for(j = 0; j < s->num_vertex; j++) {
			int k;
			v_set(0,0,0,s->vertex[j].xyz);
			v_set(0,0,0,s->vertex[j].normal);
			for(k = 0; k < s->vertex[j].num_weight; k++) {
				float v[3];
				sm_weight_t *w = &s->vertex[j].weight[k];
				v_transform(w->xyz,sm->bone[w->bone].matrix,v);
				v_scale(v,w->weight,v);
				v_add(s->vertex[j].xyz,v,s->vertex[j].xyz);
				v_transform_normal(w->normal,sm->bone[w->bone].matrix,v);
				v_scale(v,w->weight,v);
				v_add(s->vertex[j].normal,v,s->vertex[j].normal);
			}
		}
	}
}
Example #9
0
static int intersect(float fDst1, float fDst2,
			   const vec3_t a, const vec3_t b, vec3_t hit)
{
	if ((fDst1 * fDst2) >= 0.0f)
		return 0;
	if (fDst1 == fDst2)
		return 0;

	v_sub(hit, b, a);
	v_add(hit, a);
	v_scale(hit, (-fDst1 / (fDst2 - fDst1)));
	return 1;
}
Example #10
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;
}
Example #11
0
void update_ahrs(float dt, float dcm_out[3][3], float gyr_out[3])
{
	static uint8_t i;

	read_mpu(v_gyr, v_acc);
	for (i=0; i<3; i++) {
		gyr_out[i] = v_gyr[i];
	}

	/**
	 * Accelerometer
	 *     Frame of reference: body
	 *     Units: G (gravitational acceleration)
	 *     Purpose: Measure the acceleration vector v_acc with components
	 *              codirectional with the i, j, and k vectors. Note that the
	 *              gravitational vector is the negative of the K vector.
	 */
	#ifdef ACC_WEIGHT
	// Take weighted average.
	#ifdef ACC_SELF_WEIGHT
	for (i=0; i<3; i++) {
		v_acc[i] = ACC_SELF_WEIGHT * v_acc[i] + (1-ACC_SELF_WEIGHT) * v_acc_last[i];
		v_acc_last[i] = v_acc[i];

		// Kalman filtering?
		//v_acc_last[i] = acc.get(i);
		//kalmanUpdate(v_acc[i], accVar, v_acc_last[i], ACC_UPDATE_SIG);
		//kalmanPredict(v_acc[i], accVar, 0.0, ACC_PREDICT_SIG);
	}
	#endif // ACC_SELF_WEIGHT
	acc_scale = v_norm(v_acc);

	/**
	 * Reduce accelerometer weight if the magnitude of the measured
	 * acceleration is significantly greater than or less than 1 g.
	 *
	 * TODO: Magnitude of acceleration should be reported over telemetry so
	 * ACC_SCALE_WEIGHT can be more accurately determined.
	 */
	#ifdef ACC_SCALE_WEIGHT
	acc_scale = (1.0 - MIN(1.0, ACC_SCALE_WEIGHT * ABS(acc_scale - 1.0)));
	acc_weight = ACC_WEIGHT * acc_scale;
	#else
	acc_weight = ACC_WEIGHT;

	// Ignore accelerometer if it measures anything 0.5g past gravity.
	if (acc_scale > 1.5 || acc_scale < 0.5) {
		acc_weight = 0;
	}
	#endif // ACC_SCALE_WEIGHT

	/**
	 * Express K global unit vector in body frame as k_gb for use in drift
	 * correction (we need K to be described in the body frame because gravity
	 * is measured by the accelerometer in the body frame). Technically we
	 * could just create a transpose of dcm_gyro, but since we don't (yet) have
	 * a magnetometer, we don't need the first two rows of the transpose. This
	 * saves a few clock cycles.
	 */
	for (i=0; i<3; i++) {
		k_gb[i] = dcm_gyro[i][2];
	}

	/**
	 * Calculate gyro drift correction rotation vector w_a, which will be used
	 * later to bring KB closer to the gravity vector (i.e., the negative of
	 * the K vector). Although we do not explicitly negate the gravity vector,
	 * the cross product below produces a rotation vector that we can later add
	 * to the angular displacement vector to correct for gyro drift in the
	 * X and Y axes. Note we negate w_a because our acceleration vector is
	 * actually the negative of our gravity vector.
	 */
	v_crossp(k_gb, v_acc, w_a);
	v_scale(w_a, -1, w_a);
	#endif // ACC_WEIGHT

	/**
	 * Magnetometer
	 *     Frame of reference: body
	 *     Units: N/A
	 *     Purpose: Measure the magnetic north vector v_mag with components
	 *              codirectional with the body's i, j, and k vectors.
	 */
	#ifdef MAG_WEIGHT
	// Express J global unit vectory in body frame as j_gb.
	for (i=0; i<3; i++) {
		j_gb[i] = dcm_gyro[i][1];
	}

	// Calculate yaw drift correction vector w_m.
	v_crossp(j_gb, v_mag, w_m);
	#endif // MAG_WEIGHT

	/**
	 * Gyroscope
	 *     Frame of reference: body
	 *     Units: rad/s
	 *     Purpose: Measure the rotation rate of the body about the body's i,
	 *              j, and k axes.
	 * ========================================================================
	 * Scale v_gyr by elapsed time (in seconds) to get angle w*dt in radians,
	 * then compute weighted average with the accelerometer and magnetometer
	 * correction vectors to obtain final w*dt.
	 * TODO: This is still not exactly correct.
	 */
	for (i=0; i<3; i++) {
		w_dt[i] = v_gyr[i] * dt;

		#ifdef ACC_WEIGHT
		w_dt[i] += acc_weight * w_a[i];
		#endif // ACC_WEIGHT

		#ifdef MAG_WEIGHT
		w_dt[i] += MAG_WEIGHT * w_m[i];
		#endif // MAG_WEIGHT
	}

	/**
	 * Direction Cosine Matrix
	 *     Frame of reference: global
	 *     Units: None (unit vectors)
	 *     Purpose: Calculate the components of the body's i, j, and k unit
	 *              vectors in the global frame of reference.
	 * ========================================================================
	 * Skew the rotation vector and sum appropriate components by combining the
	 * skew symmetric matrix with the identity matrix. The math can be
	 * summarized as follows:
	 *
	 * All of this is calculated in the body frame. If w is the angular
	 * velocity vector, let w_dt (w*dt) be the angular displacement vector of
	 * the DCM over a time interval dt. Let w_dt_i, w_dt_j, and w_dt_k be the
	 * components of w_dt codirectional with the i, j, and k unit vectors,
	 * respectively. Also, let dr be the linear displacement vector of the DCM
	 * and dr_i, dr_j, and dr_k once again be the i, j, and k components,
	 * respectively.
	 *
	 * In very small dt, certain vectors approach orthogonality, so we can
	 * assume that (draw this out for yourself!):
	 *
	 *     dr_x = <    0,  dw_k, -dw_j>,
	 *     dr_y = <-dw_k,     0,  dw_i>, and
	 *     dr_z = < dw_j, -dw_i,     0>,
	 *
	 * which can be expressed as the rotation matrix:
	 *
	 *          [     0  dw_k -dw_j ]
	 *     dr = [ -dw_k     0  dw_i ]
	 *          [  dw_j -dw_i     0 ].
	 *
	 * This can then be multiplied by the current DCM and added to the current
	 * DCM to update the DCM. To minimize the number of calculations performed
	 * by the processor, however, we can combine the last two steps by
	 * combining dr with the identity matrix to produce:
	 *
	 *              [     1  dw_k -dw_j ]
	 *     dr + I = [ -dw_k     1  dw_i ]
	 *              [  dw_j -dw_i     1 ],
	 *
	 * which we multiply with the current DCM to produce the updated DCM
	 * directly.
	 *
	 * It may be helpful to read the Wikipedia pages on cross products and
	 * rotation representation.
	 */
	dcm_d[0][0] =        1;
	dcm_d[0][1] =  w_dt[2];
	dcm_d[0][2] = -w_dt[1];
	dcm_d[1][0] = -w_dt[2];
	dcm_d[1][1] =        1;
	dcm_d[1][2] =  w_dt[0];
	dcm_d[2][0] =  w_dt[1];
	dcm_d[2][1] = -w_dt[0];
	dcm_d[2][2] =        1;

	// Multiply the current DCM with the change in DCM and update.
	m_product(dcm_d, dcm_gyro, dcm_gyro);

	// Remove any distortions introduced by the small-angle approximations.
	orthonormalize(dcm_gyro);

	// Apply rotational offset (in case IMU is not installed orthogonally to
	// the airframe).
	dcm_offset[0][0] =              1;
	dcm_offset[0][1] =              0;
	dcm_offset[0][2] = -trim_angle[1];
	dcm_offset[1][0] =              0;
	dcm_offset[1][1] =              1;
	dcm_offset[1][2] =  trim_angle[0];
	dcm_offset[2][0] =  trim_angle[1];
	dcm_offset[2][1] = -trim_angle[0];
	dcm_offset[2][2] =              1;
	m_product(dcm_offset, dcm_gyro, dcm_out);
}
Example #12
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;
}
Example #13
0
void lsf_vq(struct melp_param *par)
{
    register int16_t i, j, k;
    static BOOLEAN firstTime = TRUE;
    static int16_t qplsp[LPC_ORD];	/* Q15 */
    const int16_t melp_cb_size[4] = { 256, 64, 32, 32 };	/* !!! (12/15/99) */
    const int16_t res_cb_size[4] = { 256, 64, 64, 64 };
    const int16_t melp_uv_cb_size[1] = { 512 };
    int16_t uv_config;	/* Bits of uv_config replace uv1, uv2 and cuv. */
    int16_t *lsp[NF];
    int32_t err, minErr, acc, bcc;	/* !!! (12/15/99), Q11 */
    int16_t temp1, temp2;
    int16_t lpc[LPC_ORD];	/* Q12 */
    int16_t wgt[NF][LPC_ORD];	/* Q11 */
    int16_t mwgt[2 * LPC_ORD];	/* Q11 */
    int16_t bestlsp0[LPC_ORD], bestlsp1[LPC_ORD];	/* Q15 */
    int16_t res[2 * LPC_ORD];	/* Q17 */

    /* The original program declares lsp_cand[LSP_VQ_CAND][] and              */
    /* lsp_index_cand[LSP_VQ_CAND*LSP_VQ_STAGES] with LSP_VQ_CAND == 8.  The  */
    /* program only uses up to LSP_INP_CAND == 5 and the declaration is       */
    /* modified.                                                              */

    int16_t lsp_cand[LSP_INP_CAND][LPC_ORD];	/* Q15 */
    int16_t lsp_index_cand[LSP_INP_CAND * LSP_VQ_STAGES];
    int16_t ilsp0[LPC_ORD], ilsp1[LPC_ORD];	/* Q15 */
    int16_t cand, inp_index_cand, tos, intfact;

    if (firstTime) {
        temp2 = melpe_shl(LPC_ORD, 10);	/* Q10 */
        temp1 = X08_Q10;	/* Q10 */
        for (i = 0; i < LPC_ORD; i++) {
            /*      qplsp[i] = (i+1)*0.8/LPC_ORD; */
            qplsp[i] = melpe_divide_s(temp1, temp2);
            temp1 = melpe_add(temp1, X08_Q10);
        }
        firstTime = FALSE;
    }

    /* ==== Compute weights ==== */
    for (i = 0; i < NF; i++) {
        lsp[i] = par[i].lsf;
        lpc_lsp2pred(lsp[i], lpc, LPC_ORD);
        vq_lspw(wgt[i], lsp[i], lpc, LPC_ORD);
    }

    uv_config = 0;
    for (i = 0; i < NF; i++) {
        uv_config = melpe_shl(uv_config, 1);
        if (par[i].uv_flag) {
            uv_config |= 0x0001;

            /* ==== Adjust weights ==== */
            if (i == 0)	/* Testing for par[0].uv_flag == 1 */
                v_scale(wgt[0], X02_Q15, LPC_ORD);
            else if (i == 1)
                v_scale(wgt[1], X02_Q15, LPC_ORD);
        }
    }

    /* ==== Quantize the lsp according to the UV decisions ==== */
    switch (uv_config) {
    case 7:		/* 111, all frames are NOT voiced ---- */
        lspVQ(lsp[0], wgt[0], lsp[0], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[0], LPC_ORD, FALSE);
        lspVQ(lsp[1], wgt[1], lsp[1], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[1], LPC_ORD, FALSE);
        lspVQ(lsp[2], wgt[2], lsp[2], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[2], LPC_ORD, FALSE);
        break;
    case 6:		/* 110 */
        lspVQ(lsp[0], wgt[0], lsp[0], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[0], LPC_ORD, FALSE);
        lspVQ(lsp[1], wgt[1], lsp[1], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[1], LPC_ORD, FALSE);
        lspVQ(lsp[2], wgt[2], lsp[2], lsp_v_256x64x32x32, 4, melp_cb_size,	/* !!! (12/15/99) */
              quant_par.lsf_index[2], LPC_ORD, FALSE);
        break;
    case 5:		/* 101 */
        lspVQ(lsp[0], wgt[0], lsp[0], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[0], LPC_ORD, FALSE);
        lspVQ(lsp[1], wgt[1], lsp[1], lsp_v_256x64x32x32, 4, melp_cb_size,	/* !!! (12/15/99) */
              quant_par.lsf_index[1], LPC_ORD, FALSE);
        lspVQ(lsp[2], wgt[2], lsp[2], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[2], LPC_ORD, FALSE);
        break;
    case 3:		/* 011 */
        lspVQ(lsp[0], wgt[0], lsp[0], lsp_v_256x64x32x32, 4, melp_cb_size,	/* !!! (12/15/99) */
              quant_par.lsf_index[0], LPC_ORD, FALSE);
        lspVQ(lsp[1], wgt[1], lsp[1], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[1], LPC_ORD, FALSE);
        lspVQ(lsp[2], wgt[2], lsp[2], lsp_uv_9, 1, melp_uv_cb_size,
              quant_par.lsf_index[2], LPC_ORD, FALSE);
        break;
    default:
        if (uv_config == 1) {	/* 001 case, if (!uv1 && !uv2 && uv3). */
            /* ---- Interpolation [4 inp + (8+6+6+6) res + 9 uv] ---- */
            tos = 1;
            lspVQ(lsp[2], wgt[2], lsp_cand[0], lsp_uv_9, tos,
                  melp_uv_cb_size, lsp_index_cand, LPC_ORD, TRUE);
        } else {
            tos = 4;
            lspVQ(lsp[2], wgt[2], lsp_cand[0], lsp_v_256x64x32x32, tos,	/* !!! (12/15/99) */
                  melp_cb_size, lsp_index_cand, LPC_ORD, TRUE);
        }

        minErr = LW_MAX;
        cand = 0;
        inp_index_cand = 0;
        for (k = 0; k < LSP_INP_CAND; k++) {
            for (i = 0; i < 16; i++) {

                err = 0;

                /* Originally we have two for loops here.  One computes       */
                /* ilsp0[] and ilsp1[] and the other one computes "err".  If  */
                /* "err" already exceeds minErr, we can stop the loop and     */
                /* there is no need to compute the remaining ilsp0[] and      */
                /* ilsp1[] entries.  Hence the two for loops are joined.      */

                for (j = 0; j < LPC_ORD; j++) {

                    /*      ilsp0[j] = (inpCoef[i][j] * qplsp[j] +
                       (1.0 - inpCoef[i][j]) * lsp_cand[k][j]); */
                    intfact = inpCoef[i][j];	/* Q14 */
                    acc = melpe_L_mult(intfact, qplsp[j]);	/* Q30 */
                    intfact = melpe_sub(ONE_Q14, intfact);	/* Q14 */
                    acc = melpe_L_mac(acc, intfact, lsp_cand[k][j]);	/* Q30 */
                    ilsp0[j] = melpe_extract_h(melpe_L_shl(acc, 1));
                    acc =
                        melpe_L_sub(acc,
                                    melpe_L_shl(melpe_L_deposit_l(lsp[0][j]),
                                                15));

                    /*      ilsp1[j] = inpCoef[i][j + LPC_ORD] * qplsp[j] +
                       (1.0 - inpCoef[i][j + LPC_ORD]) * lsp_cand[k][j]; */
                    intfact = inpCoef[i][j + LPC_ORD];	/* Q14 */
                    bcc = melpe_L_mult(intfact, qplsp[j]);
                    intfact = melpe_sub(ONE_Q14, intfact);
                    bcc = melpe_L_mac(bcc, intfact, lsp_cand[k][j]);	/* Q30 */
                    ilsp1[j] = melpe_extract_h(melpe_L_shl(bcc, 1));
                    bcc =
                        melpe_L_sub(bcc,
                                    melpe_L_shl(melpe_L_deposit_l(lsp[1][j]),
                                                15));

                    /*      err += wgt0[j]*(lsp0[j] - ilsp0[j])*
                       (lsp0[j] - ilsp0[j]); */
                    temp1 = melpe_norm_l(acc);
                    temp2 = melpe_extract_h(melpe_L_shl(acc, temp1));
                    if (temp2 == MONE_Q15)
                        temp2 = -32767;
                    temp2 = melpe_mult(temp2, temp2);
                    acc = melpe_L_mult(temp2, wgt[0][j]);
                    temp1 = melpe_shl(melpe_sub(1, temp1), 1);
                    acc = melpe_L_shl(acc, melpe_sub(temp1, 3));	/* Q24 */
                    err = melpe_L_add(err, acc);

                    /*      err += wgt1[j]*(lsp1[j] - ilsp1[j])*
                       (lsp1[j] - ilsp1[j]); */
                    temp1 = melpe_norm_l(bcc);
                    temp2 = melpe_extract_h(melpe_L_shl(bcc, temp1));
                    if (temp2 == MONE_Q15)
                        temp2 = -32767;
                    temp2 = melpe_mult(temp2, temp2);
                    bcc = melpe_L_mult(temp2, wgt[1][j]);
                    temp1 = melpe_shl(melpe_sub(1, temp1), 1);
                    bcc = melpe_L_shl(bcc, melpe_sub(temp1, 3));	/* Q24 */
                    err = melpe_L_add(err, bcc);

                    /* computer the err for the last frame */
                    acc = melpe_L_shl(melpe_L_deposit_l(lsp[2][j]), 15);
                    acc =
                        melpe_L_sub(acc,
                                    melpe_L_shl(melpe_L_deposit_l
                                                (lsp_cand[k][j]), 15));
                    temp1 = melpe_norm_l(acc);
                    temp2 = melpe_extract_h(melpe_L_shl(acc, temp1));
                    if (temp2 == MONE_Q15)
                        temp2 = -32767;
                    temp2 = melpe_mult(temp2, temp2);
                    acc = melpe_L_mult(temp2, wgt[2][j]);
                    temp1 = melpe_shl(melpe_sub(1, temp1), 1);
                    acc = melpe_L_shl(acc, melpe_sub(temp1, 3));	/* Q24 */
                    err = melpe_L_add(err, acc);
                }

                if (err < minErr) {
                    minErr = err;
                    cand = k;
                    inp_index_cand = i;
                    v_equ(bestlsp0, ilsp0, LPC_ORD);
                    v_equ(bestlsp1, ilsp1, LPC_ORD);
                }
            }
        }

        v_equ(lsp[2], lsp_cand[cand], LPC_ORD);
        v_equ(quant_par.lsf_index[0], &(lsp_index_cand[cand * tos]),
              tos);
        quant_par.lsf_index[1][0] = inp_index_cand;

        for (i = 0; i < LPC_ORD; i++) {
            temp1 = melpe_sub(lsp[0][i], bestlsp0[i]);	/* Q15 */
            temp2 = melpe_sub(lsp[1][i], bestlsp1[i]);	/* Q15 */
            res[i] = melpe_shl(temp1, 2);	/* Q17 */
            res[i + LPC_ORD] = melpe_shl(temp2, 2);	/* Q17 */
        }
        v_equ(mwgt, wgt[0], LPC_ORD);
        v_equ(mwgt + LPC_ORD, wgt[1], LPC_ORD);

        /* Note that in the following IF block, the lspVQ() is quantizing on  */
        /* res[] and res256x64x64x64[], and both of them are Q17 instead of   */
        /* Q15, unlike the other calling instances in this function.          */

        if (uv_config == 1)	/* if (!uv1 && !uv2 && uv3) */
            lspVQ(res, mwgt, res, res256x64x64x64, 4, res_cb_size,
                  quant_par.lsf_index[2], 2 * LPC_ORD, FALSE);
        else
            lspVQ(res, mwgt, res, res256x64x64x64, 2, res_cb_size,
                  quant_par.lsf_index[2], 2 * LPC_ORD, FALSE);

        /* ---- reconstruct lsp for later stability check ---- */
        for (i = 0; i < LPC_ORD; i++) {
            temp1 = melpe_shr(res[i], 2);
            lsp[0][i] = melpe_add(temp1, bestlsp0[i]);
            temp2 = melpe_shr(res[i + LPC_ORD], 2);
            lsp[1][i] = melpe_add(temp2, bestlsp1[i]);
        }
        break;
    }

    /* ---- Stability checking ---- */
    /* The sortings on lsp[0] and lsp[1] are not necessary because they are   */
    /* variables local to this function and they are discarded upon exit.     */
    /* We only check whether they fit the stability test and issue a warning. */

    (void)lspStable(lsp[0], LPC_ORD);
    (void)lspStable(lsp[1], LPC_ORD);
    if (!lspStable(lsp[2], LPC_ORD))
        lspSort(lsp[2], LPC_ORD);

    v_equ(qplsp, lsp[2], LPC_ORD);
}
Example #14
0
/**
 * Prepare a mesh for drawing.  Compute mesh's final vertex positions
 * given a skeleton.  Put the vertices in vertex arrays.
 */
static void
PrepareMesh(const struct md5_mesh_part *mesh, const struct md5_joint_t *skeleton)
{
	unsigned int i, j, k;

	/* Setup vertex indices */
	for (k = 0, i = 0; i < mesh->num_tris; ++i) {
		for (j = 0; j < 3; ++j, ++k)
			vertexIndices[k] = mesh->triangles[i].index[j];
	}

	/* Setup vertices */
	for (i = 0; i < mesh->num_verts; ++i) {
		vec3_t vert = { 0.0f, 0.0f, 0.0f };
		vec3_t norm = { 0.0f, 0.0f, 0.0f };
//		vec3_t tan = { 0.0f, 0.0f, 0.0f };

		/* Calculate final vertex to draw with weights */
		for (j = 0; j < mesh->vertices[i].count; ++j) {
			const struct md5_weight_t *weight
			    = &mesh->weights[mesh->vertices[i].start + j];
			const struct md5_joint_t *joint
			    = &skeleton[weight->joint];
			vec3_t wv;

			/* Calculate transformed vertex for this weight */
			Quat_rotatePoint(joint->orient, weight->pos, wv);

			/* The sum of all weight->bias should be 1.0 */
			vert[0] +=
			    (joint->pos[0] + wv[0]) * weight->bias;
			vert[1] +=
			    (joint->pos[1] + wv[1]) * weight->bias;
			vert[2] +=
			    (joint->pos[2] + wv[2]) * weight->bias;

			Quat_rotatePoint(joint->orient, weight->normal, wv);
			v_scale(wv, weight->bias);
			v_add(norm, norm, wv);

//			Quat_rotatePoint(joint->orient, weight->tangent, wv);
//			v_scale(wv, weight->bias);
//			v_add(tan, tan, wv);
		}

		v_normalize(norm);
//		v_normalize(tan);

		vertexArray[i][0] = vert[0];
		vertexArray[i][1] = vert[1];
		vertexArray[i][2] = vert[2];

		normalArray[i][0] = norm[0];
		normalArray[i][1] = norm[1];
		normalArray[i][2] = norm[2];

#if 0
		tangentArray[i][0] = tan[0];
		tangentArray[i][1] = tan[1];
		tangentArray[i][2] = tan[2];
#endif
		texArray[i][0] = mesh->vertices[i].st[0];
		texArray[i][1] = 1.0f - mesh->vertices[i].st[1];
	}
}
Example #15
0
void melp_ana_init()
{

    int j;

    bpvc_ana_init(FRAME,PITCHMIN,PITCHMAX,NUM_BANDS,2,MINLENGTH);
    pitch_ana_init(PITCHMIN,PITCHMAX,FRAME,LPF_ORD,MINLENGTH);
    p_avg_init(PDECAY,DEFAULT_PITCH,3);

    v_zap(speech,IN_BEG+FRAME);
    pitch_avg=DEFAULT_PITCH;
    fill(fpitch,DEFAULT_PITCH,2);
    v_zap(lpfsp_del,LPF_ORD);
	
    /* Initialize multi-stage vector quantization (read codebook) */
	
    vq_par.num_best = MSVQ_M;
    vq_par.num_stages = 4;
    vq_par.dimension = 10;

    /* 
     * Allocate memory for number of levels per stage and indices
     * and for number of bits per stage 
     */
 
    MEM_ALLOC(MALLOC,vq_par.num_levels,vq_par.num_stages,int);
    MEM_ALLOC(MALLOC,vq_par.indices,vq_par.num_stages,int);
    MEM_ALLOC(MALLOC,vq_par.num_bits,vq_par.num_stages,int);
	
    vq_par.num_levels[0] = 128;
    vq_par.num_levels[1] = 64;
    vq_par.num_levels[2] = 64;
    vq_par.num_levels[3] = 64;
	
    vq_par.num_bits[0] = 7;
    vq_par.num_bits[1] = 6;
    vq_par.num_bits[2] = 6;
    vq_par.num_bits[3] = 6;
	
    vq_par.cb = msvq_cb;
	
    /* Scale codebook to 0 to 1 */
    v_scale(vq_par.cb,(2.0/FSAMP),3200);

    /* Initialize Fourier magnitude vector quantization (read codebook) */
	
    fs_vq_par.num_best = 1;
    fs_vq_par.num_stages = 1;
    fs_vq_par.dimension = NUM_HARM;

    /* 
     * Allocate memory for number of levels per stage and indices
     * and for number of bits per stage 
     */
 
    MEM_ALLOC(MALLOC,fs_vq_par.num_levels,fs_vq_par.num_stages,int);
    MEM_ALLOC(MALLOC,fs_vq_par.indices,fs_vq_par.num_stages,int);
    MEM_ALLOC(MALLOC,fs_vq_par.num_bits,fs_vq_par.num_stages,int);

    fs_vq_par.num_levels[0] = FS_LEVELS;
    fs_vq_par.num_bits[0] = FS_BITS;
    fs_vq_par.cb = fsvq_cb;
	
    /* Initialize fixed MSE weighting and inverse of weighting */
	
    vq_fsw(w_fs, NUM_HARM, 60.0);
	
    /* Pre-weight codebook (assume single stage only) */
	
    if (fsvq_weighted == 0)
      {
	  fsvq_weighted = 1;
	  for (j = 0; j < fs_vq_par.num_levels[0]; j++)
	    window(&fs_vq_par.cb[j*NUM_HARM],w_fs,&fs_vq_par.cb[j*NUM_HARM],
		   NUM_HARM);
      }

}
/**
 *  ahrs_step() takes the values from the IMU and produces the
 * new estimated attitude.
 */
void
ahrs_step(
	v_t			angles_out,
	f_t			dt,
	f_t			p,
	f_t			q,
	f_t			r,
	f_t			ax,
	f_t			ay,
	f_t			az,
	f_t			heading
)
{
	m_t			C;

	m_t			A;
	m_t			AT;
	v_t			X_dot;
	m_t			temp;

	v_t			Xm;
	v_t			Xe;

	/* Construct the quaternion omega matrix */
	rotate2omega( A, p, q, r );

	/* X_dot = AX */
	mv_mult( X_dot, A, X, 4, 4 );

	/* X += X_dot dt */
	v_scale( X_dot, X_dot, dt, 4 );

	v_add( X, X_dot, X, 4 );
	v_normq( X, X );

/*
	printf( "X =" );
	Vprint( X, 4 );
	printf( "\n" );
*/
	
	/* AT = transpose(A) */
	m_transpose( AT, A, 4, 4 );

	/* P = A * P * AT + Q */
	m_mult( temp, A, P, 4, 4, 4 );
	m_mult( P, temp, AT, 4, 4, 4 );
	m_add( P, Q, P, 4, 4 );
	
	
	compute_c( C, X );

	/* Compute the euler angles of the measured attitude */
	accel2euler(
		Xm,
		ax,
		ay,
		az,
		heading
	);

	/*
	 * Compute the euler angles of the estimated attitude
	 * Xe = quat2euler( X )
	 */
	quat2euler( Xe, X );

	/* Kalman filter update */
	kalman_update(
		P,
		R,
		C,
		X,
		Xe,
		Xm
	);

	/* Estimated attitude extraction */
	quat2euler( angles_out, X );
}
Example #17
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]);
    
}