Пример #1
0
int		hit_cone(t_ray *r, t_cone co, double *hit)
{
	t_lanormemecasselescouilles	q;
	double						tmp;
	t_vector					new_o;
	double						norm_sucks[3];

	co.dir = vector_normalize(co.dir);
	new_o = vector_sub(r->o, co.o);
	norm_sucks[2] = 1 + tan(co.angle) * tan(co.angle);
	norm_sucks[0] = vector_dot_product(r->dir, co.dir);
	norm_sucks[1] = vector_dot_product(new_o, co.dir);
	get_eqcone(r, norm_sucks, new_o, &q);
	if (q.eqc[3] < 0)
		return (0);
	else if ((tmp = (-q.eqc[1] - sqrt(q.eqc[3])) / (2 * q.eqc[0])) || 1)
	{
		if (tmp < 0 &&
				((tmp = (-q.eqc[1] + sqrt(q.eqc[3]) / (2 * q.eqc[0]))) || 1))
			if (tmp < 0)
				return (0);
		if (*hit > 0 && tmp > *hit)
			return (0);
		*hit = tmp;
		return (1);
	}
}
Пример #2
0
void vector_difference_to_euler_angles(fixedpointnum *v1, fixedpointnum *v2, fixedpointnum *euler) {
    // take the difference between the two attitudes and return the euler angles between them
    // find the axis of rotation and angle between the two downVectors
   // the cross products of the two vectors will give us the axis of rotation from one to the other
   fixedpointnum axisofrotation[3];
   vector_cross_product(v1, v2, axisofrotation);

   fixedpointnum axislength=lib_fp_sqrt(normalize_vector(axisofrotation));
   
   // get the angle of rotation between the two vectors
   fixedpointnum angle=lib_fp_atan2(axislength, vector_dot_product(v1, v2));

   fixedpointnum unitvector[3];
   unitvector[0]=0;
   unitvector[1]=FIXEDPOINTONE;
   unitvector[2]=0;
   
   euler[0]=lib_fp_multiply(vector_dot_product(axisofrotation, unitvector), angle);

   unitvector[0]=FIXEDPOINTONE;
   unitvector[1]=0;
   unitvector[2]=0;
   
   euler[1]=lib_fp_multiply(vector_dot_product(axisofrotation, unitvector), angle);
}
Пример #3
0
int		hit_cylinder(t_ray *r, t_cylinder cy, double *hit)
{
	t_lanormemecasselescouilles	q;
	double						tmp;
	t_vector					new_o;
	double						sucemanorme[3];

	if (cy.dir.x == 0 && cy.dir.y == 0 && cy.dir.z == 0)
		return (0);
	cy.dir = vector_normalize(cy.dir);
	new_o = vector_sub(r->o, cy.o);
	sucemanorme[0] = vector_dot_product(r->dir, cy.dir);
	sucemanorme[1] = vector_dot_product(new_o, cy.dir);
	sucemanorme[2] = cy.rayon;
	if (get_eqcyl(r, sucemanorme, new_o, &q) && q.eqc[3] < 0)
		return (0);
	else if ((tmp = (-q.eqc[1] - sqrt(q.eqc[3])) / (2 * q.eqc[0])) || 1)
	{
		if (tmp < 0 &&
				((tmp = (-q.eqc[1] + sqrt(q.eqc[3])) / (2 * q.eqc[0])) || 1))
			if (tmp < 0)
				return (0);
		if (*hit > 0 && tmp > *hit)
			return (0);
		*hit = tmp;
		return (1);
	}
}
Пример #4
0
int		get_eqcone(t_ray *r, double n[3], t_vector new_o,
		t_lanormemecasselescouilles *q)
{
	q->eqc[0] = vector_dot_product(r->dir, r->dir) - n[2] * n[0] * n[0];
	q->eqc[1] = 2 * (vector_dot_product(r->dir, new_o) - n[2] * n[0] * n[1]);
	q->eqc[2] = vector_dot_product(new_o, new_o) - n[2] * n[1] * n[1];
	q->eqc[3] = q->eqc[1] * q->eqc[1] - 4 * q->eqc[0] * q->eqc[2];
	return (1);
}
Пример #5
0
void			cylinder_inter(t_inter *inter, void *obj, t_ray ray,
								t_light *light)
{
	t_cylinder	cylinder;
	double		dist;
	t_ray		temp;

	cylinder = *((t_cylinder *)obj);
	temp = ray;
	change_frame(&ray, cylinder.inv, vector_inverse(cylinder.trans));
	dist = cylinder_distance(ray, cylinder);
	if (dist > EPS && (inter->dist == NULL || dist < *(inter->dist) - EPS))
	{
		if (inter->dist == NULL)
			inter->dist = malloc(sizeof(double));
		free_light_ray_list(inter);
		*(inter->dist) = dist;
		inter->pos = calculate_position(ray, dist);
		inter->normal = cylinder_normal(inter->pos, cylinder);
		if (vector_dot_product(inter->normal, ray.dir) > 0)
			inter->normal = vector_inverse(inter->normal);
		op_inv(cylinder.trans, cylinder.rot, &(inter->normal), &(inter->pos));
		inter->refl = calculate_reflection(temp, inter->normal);
		inter->color = cylinder.color;
		create_light_ray_list(inter, light, inter->pos);
		inter->refl_val = cylinder.refl;
	}
}
Пример #6
0
int		hit_sphere(t_ray *r, t_sphere s, double *hit)
{
	double	eqc[4];
	double	tmp;

	eqc[0] = vector_dot_product(r->dir, r->dir);
	eqc[1] = 2 * (r->dir.x * (r->o.x - s.o.x) + r->dir.y * (r->o.y - s.o.y) +
			r->dir.z * (r->o.z - s.o.z));
	eqc[2] = (r->o.x - s.o.x) * (r->o.x - s.o.x) + (r->o.y - s.o.y) *
		(r->o.y - s.o.y) + (r->o.z - s.o.z) * (r->o.z - s.o.z) -
		s.rayon * s.rayon;
	eqc[3] = eqc[1] * eqc[1] - 4 * eqc[0] * eqc[2];
	if (eqc[3] < 0)
		return (0);
	else
	{
		tmp = (-eqc[1] - sqrt(eqc[3])) / (2 * eqc[0]);
		if (tmp < 0 && ((tmp += sqrt(eqc[3]) / eqc[0]) || 1))
			if (tmp < 0)
				return (0);
		if (*hit > 0 && tmp > *hit)
			return (0);
		*hit = tmp;
		return (1);
	}
}
/*
% project v in direction of u
function p=project_vec(v,u)
p = (dot(v,u)/norm(u)^2)*u;
*/
void project_vector(vec *v, vec *u, vec *p){
    double dot_product_val, vec_norm, scalar_val; 
    dot_product_val = vector_dot_product(v, u);
    vec_norm = vector_get2norm(u);
    scalar_val = dot_product_val/(vec_norm*vec_norm);
    vector_copy(p, u);
    vector_scale(p, scalar_val); 
}
Пример #8
0
void object_render_flatshading(surface_t* s, object_t* obj, vector_t* pbuffer, char* stencil, vector_t* light) {
	int c, diff;
	//int l, top, bottom;
	vector_t *i, *j, *k;
	vector_t q1, q2, N;
	mesh_t* mesh = obj->mesh;
	vector_t* m = mesh->points;
	triangle_t* t = mesh->triangles;
	int li;

	object_apply_transformations(obj, pbuffer, 128, 96); // FIXME: must use surface center

	m = mesh->points;
	diff = (char*)pbuffer - (char*)m;
	for (c = 0; c < mesh->tcount; c++) {
		i = (vector_t*)((char*)t->vertexes[0] + diff);
		j = (vector_t*)((char*)t->vertexes[1] + diff);
		k = (vector_t*)((char*)t->vertexes[2] + diff);

		vector_subtract(j, i, &q1);
		vector_subtract(k, i, &q2);
		vector_cross_product(&q1, &q2, &N);

		if (N.z > 0) {
			vector_normalize(&N, &N);
			//li = vector_dot_product(&N, light)*5;
			//li = f2i(li);
			//li = (li < 0) ? 0 : ((li > 4) ? 4 : li);

			// FIXME: can optimize memset's by covering only "top" to "bottom" lines
			// in this case we should require clean buffers to start with.
			// and we should clean them after rendering.
			//memset(low, MODE2_HEIGHT << 1, 64);	// FIXME: must use surface height
			//memset(high, MODE2_HEIGHT << 1, 0);	// FIXME: must use surface height
			stencil_init(stencil);

			// calculate polygon
			stencil_add_side(i->x, i->y, j->x, j->y, stencil);
			stencil_add_side(j->x, j->y, k->x, k->y, stencil);
			stencil_add_side(k->x, k->y, i->x, i->y, stencil);


/*
			top = (i->y < j->y) ? ((i->y < k->y) ? i->y : k->y) : ((j->y < k->y) ? j->y : k->y);
			bottom = (i->y > j->y) ? ((i->y > k->y) ? i->y : k->y) : ((j->y > k->y) ? j->y : k->y);

			for (l = top; l <= bottom; l++) {
				surface_hline(s, low[l], l, high[l], DITHER(li, l));
			}
*/
			surface_stencil_render(s, stencil, vector_dot_product(&N, light)/6);
			//surface_stencil_render(s, stencil, li);
		}
		t++;
	}	
}
Пример #9
0
/*******************************************************************************
* vector_t vector_projection(vector_t v, vector_t e)
*
* Projects vector v onto e
*******************************************************************************/
vector_t vector_projection(vector_t v, vector_t e){
	int i;
	float factor;
	vector_t out = create_empty_vector();
	
	if(!v.initialized || !e.initialized){
		printf("ERROR: vectors not initialized yet\n");
		return out;
	}
	if(v.len != e.len){
		printf("ERROR: vectors not of same dimension\n");
		return out;
	}
	out = create_vector(v.len);
	factor = vector_dot_product(v,e)/vector_dot_product(e,e);
	for(i=0;i<v.len;i++){
		out.data[i] = factor * e.data[i];
	}
	return out;
}
Пример #10
0
int		hit_plane(t_ray *r, t_plane p, double *hit)
{
	double	a;
	double	b;

	p.n = vector_normalize(p.n);
	a = vector_dot_product(r->dir, p.n);
	b = vector_dot_product(p.n, vector_sub(r->o, p.pt));
	if (a == 0)
		return (0);
	if (*hit > 0 && -b / a > *hit)
		return (0);
	else if (-b / a > 0)
	{
		*hit = -b / a;
		return (1);
	}
	else
		return (0);
}
Пример #11
0
void rotate_vector_by_axis_angle(fixedpointnum *v1, fixedpointnum *axisvector, fixedpointnum angle, fixedpointnum *v2) {
   fixedpointnum cosineofangle=lib_fp_cosine(angle);
   fixedpointnum sineofangle=lib_fp_sine(angle);
   
   fixedpointnum crossproductvector[3];
   vector_cross_product(axisvector,v1, crossproductvector);
   
   fixedpointnum dotproducttimesoneminuscosineofangle=lib_fp_multiply(vector_dot_product(axisvector,v1),FIXEDPOINTONE-cosineofangle);
   
   v2[0]=lib_fp_multiply(v1[0], cosineofangle)+lib_fp_multiply(crossproductvector[0],sineofangle)+lib_fp_multiply(axisvector[0],dotproducttimesoneminuscosineofangle);
   v2[1]=lib_fp_multiply(v1[1], cosineofangle)+lib_fp_multiply(crossproductvector[1],sineofangle)+lib_fp_multiply(axisvector[1],dotproducttimesoneminuscosineofangle);
   v2[2]=lib_fp_multiply(v1[2], cosineofangle)+lib_fp_multiply(crossproductvector[2],sineofangle)+lib_fp_multiply(axisvector[2],dotproducttimesoneminuscosineofangle);
}
Пример #12
0
static void matrix_mult_vector(matrix_t * A, vector_t * x, vector_t * b)
{
    /* Ax = b */
    int i;
    vector_t * tmp_v = vector_create_with_data(x->size, NULL);
    
    for (i = 0; i < A->rows; i++)
    {
        /* treat A's row as a vector */
        tmp_v->data = A->data[i];
        
        /* run a dot product and store in b */
        b->data[i] = vector_dot_product(tmp_v, x);
    }
    
    tmp_v->data = NULL;
    vector_destroy(tmp_v);
}
Пример #13
0
/*******************************************************************************
* matrix_t householder_matrix(vector_t v)
*
* returns the householder reflection matrix for a given vector
*******************************************************************************/
matrix_t householder_matrix(vector_t v){
	int i, j;
	float tau;
	matrix_t out = create_empty_matrix();
	if(!v.initialized){
		printf("ERROR: vector not initialized yet\n");
		return out;
	}
	out = create_square_matrix(v.len);
	for(i=0;i<v.len;i++){
		out.data[i][i] = 1;
	}
	tau = 2.0/vector_dot_product(v,v);
	for(i=0;i<v.len;i++){
		for(j=0;j<v.len;j++){
			out.data[i][j] -= tau * v.data[i]*v.data[j];
		}
	}
	return out;
}
Пример #14
0
void map_prepare_mesh_poly(map_type *map,map_mesh_type *mesh,map_mesh_poly_type *poly)
{
	int				n,ptsz,y,lx,rx,lz,rz,dist;
	float			ang;
	bool			flat;
	d3pnt			min,max,mid;
	d3pnt			*pt;
	d3vct			map_up;

		// find enclosing square
		// and middle and if polygon is flat
		
	pt=&mesh->vertexes[poly->v[0]];

	min.x=max.x=mid.x=pt->x;
	min.y=max.y=mid.y=y=pt->y;
	min.z=max.z=mid.z=pt->z;

	flat=TRUE;
    
    ptsz=poly->ptsz;
    
	for (n=1;n<ptsz;n++) {
		pt=&mesh->vertexes[poly->v[n]];

			// get min and max

		if (pt->x<min.x) min.x=pt->x;
		if (pt->x>max.x) max.x=pt->x;
		if (pt->y<min.y) min.y=pt->y;
		if (pt->y>max.y) max.y=pt->y;
		if (pt->z<min.z) min.z=pt->z;
		if (pt->z>max.z) max.z=pt->z;

			// add for middle

		mid.x+=pt->x;
		mid.y+=pt->y;
		mid.z+=pt->z;

			// check for flat y

		if (pt->y!=y) flat=FALSE;
	}
    
	memmove(&poly->box.min,&min,sizeof(d3pnt));
	memmove(&poly->box.max,&max,sizeof(d3pnt));
	
	poly->box.mid.x=mid.x/ptsz;
	poly->box.mid.y=mid.y/ptsz;
	poly->box.mid.z=mid.z/ptsz;
	
	poly->box.flat=flat;

		// get dot product of normal and up
		// vector to determine the slope of surface
		// and if it's wall like

	if (flat) {
		poly->slope.y=0.0f;
		poly->slope.ang_y=0.0f;
		poly->slope.move_x=0.0f;
		poly->slope.move_z=0.0f;

		poly->box.wall_like=FALSE;
	}
	else {
		map_up.x=0.0f;
		map_up.y=-1.0f;
		map_up.z=0.0f;

		ang=fabsf(vector_dot_product(&map_up,&poly->tangent_space.normal));

			// use dot product to tell if wall like
			// and the y slope

		poly->box.wall_like=(ang<=0.4f);
		poly->slope.y=1.0f-ang;

			// find the slope angle

		map_prepare_mesh_poly_slope_ang(mesh,poly);
		angle_get_movement_float(poly->slope.ang_y,(map->physics.slope_max_speed*poly->slope.y),&poly->slope.move_x,&poly->slope.move_z);
	}

		// create wall "line" for wall like polygons

	if (poly->box.wall_like) {
			
			// get the lx,lz to rx,rz
			
		lx=poly->box.min.x;
		rx=poly->box.max.x;
		lz=poly->box.min.z;
		rz=poly->box.max.z;
		
		for (n=0;n!=poly->ptsz;n++) {
			pt=&mesh->vertexes[poly->v[n]];
			
			if ((rx-lx)>(rz-lz)) {
				if (pt->x==lx) lz=pt->z;
				if (pt->x==rx) rz=pt->z;
			}
			else {
				if (pt->z==lz) lx=pt->x;
				if (pt->z==rz) rx=pt->x;
			}
		}

		poly->line.lx=lx;
		poly->line.rx=rx;
		poly->line.lz=lz;
		poly->line.rz=rz;
		
			// find ty,by for each point
			// we need to catch polygons that have higher or lower
			// points slightly offset from lx,lz or rx,rz, so we use
			// a distance calculation here (within 20% of end point)
			
		dist=distance_2D_get(lx,lz,rx,rz);
		dist=(dist*20)/100;
			
		poly->line.l_ty=poly->line.r_ty=poly->line.l_by=poly->line.r_by=-1;
		
		for (n=0;n!=poly->ptsz;n++) {
			pt=&mesh->vertexes[poly->v[n]];
			
			if (distance_2D_get(pt->x,pt->z,lx,lz)<dist) {
				if ((pt->y<poly->line.l_ty) || (poly->line.l_ty==-1)) poly->line.l_ty=pt->y;
				if ((pt->y>poly->line.l_by) || (poly->line.l_by==-1)) poly->line.l_by=pt->y;
			}
			
			if (distance_2D_get(pt->x,pt->z,rx,rz)<dist) {
				if ((pt->y<poly->line.r_ty) || (poly->line.r_ty==-1)) poly->line.r_ty=pt->y;
				if ((pt->y>poly->line.r_by) || (poly->line.r_by==-1)) poly->line.r_by=pt->y;
			}
		}
		
		if (poly->line.l_ty==-1) poly->line.l_ty=poly->box.min.y;
		if (poly->line.r_ty==-1) poly->line.r_ty=poly->box.min.y;
		if (poly->line.l_by==-1) poly->line.l_by=poly->box.max.y;
		if (poly->line.r_by==-1) poly->line.r_by=poly->box.max.y;
	}
	
		// get the plane equation for ray-plane intersections
		
	map_prepare_mesh_poly_plane(mesh,poly);

		// determine if shadows can project on this polygon

	map_prepare_mesh_poly_shadow(map,mesh,poly);
}
Пример #15
0
bool model_recalc_normals_determine_vector_in_out(model_type *model,int mesh_idx,int vertex_idx)
{
    int					x,y,z,k,pos_dist,neg_dist;
    float				f_dist;
    bool				is_out;
    d3pnt				*pnt,min,max,center,pos_pt,neg_pt;
    d3vct				face_vct;
    model_mesh_type		*mesh;
    model_vertex_type	*vertex;

    // get box for vertex.  This will be the combination
    // of vertexes with the same material

    map_recalc_normals_get_vertex_box(model,mesh_idx,vertex_idx,&min,&max);

    // get the box center

    mesh=&model->meshes[mesh_idx];
    vertex=&mesh->vertexes[vertex_idx];
    pnt=&vertex->pnt;

    center.x=(min.x+max.x)>>1;
    center.y=(min.y+max.y)>>1;
    center.z=(min.z+max.z)>>1;

    // the dot product is the fall back position
    // if these specialized checks fail

    vector_create(&face_vct,pnt->x,pnt->y,pnt->z,center.x,center.y,center.z);
    is_out=(vector_dot_product(&vertex->tangent_space.normal,&face_vct)>0.0f);

    // get a point from the current normal vector
    // and inverse of the current normal vector, using 10%
    // of the distance to center

    f_dist=(float)distance_get(pnt->x,pnt->y,pnt->z,center.x,center.y,center.z);
    f_dist*=0.1f;

    pos_pt.x=pnt->x+(int)(vertex->tangent_space.normal.x*f_dist);
    pos_pt.y=pnt->y+(int)(vertex->tangent_space.normal.y*f_dist);
    pos_pt.z=pnt->z+(int)(vertex->tangent_space.normal.z*f_dist);

    neg_pt.x=pnt->x-(int)(vertex->tangent_space.normal.x*f_dist);
    neg_pt.y=pnt->y-(int)(vertex->tangent_space.normal.y*f_dist);
    neg_pt.z=pnt->z-(int)(vertex->tangent_space.normal.z*f_dist);

    // first we determine if we can think of the
    // poly's box (which is determined by all connected
    // polys) as a closed object in one direction

    // if one direction is at least 25% greater than the others
    // then consider it a tube like structure

    // if any distance calcs fail, fall back to dot product

    x=max.x-min.x;
    y=max.y-min.y;
    z=max.z-min.z;

    k=x-((x*25)/100);
    if ((x>y) && (x>z)) {
        pos_dist=distance_2D_get(pos_pt.y,pos_pt.z,center.y,center.z);
        neg_dist=distance_2D_get(neg_pt.y,neg_pt.z,center.y,center.z);
        if (pos_dist==neg_dist) return(is_out);

        return(pos_dist>neg_dist);
    }

    k=y-((y*25)/100);
    if ((y>x) && (y>z)) {
        pos_dist=distance_2D_get(pos_pt.x,pos_pt.z,center.x,center.z);
        neg_dist=distance_2D_get(neg_pt.x,neg_pt.z,center.x,center.z);
        if (pos_dist==neg_dist) return(is_out);

        return(pos_dist>neg_dist);
    }

    k=z-((z*25)/100);
    if ((z>x) && (z>y)) {
        pos_dist=distance_2D_get(pos_pt.x,pos_pt.y,center.x,center.y);
        neg_dist=distance_2D_get(neg_pt.x,neg_pt.y,center.x,center.y);
        if (pos_dist==neg_dist) return(is_out);

        return(pos_dist>neg_dist);
    }

    // finally fall back to dot product

    return(is_out);
}
Пример #16
0
bool object_move_xz_slide_line(obj_type *obj,int *xadd,int *yadd,int *zadd,int lx,int rx,int lz,int rz)
{
	int					n,xadd2,yadd2,zadd2,mx,mz;
	float				f,ang,rang;
	bool				hit,cwise;
	d3vct				line_vct,obj_vct;
	
		// special check for horizontal/vertical walls

	if (lx==rx) {
		xadd2=0;
		yadd2=0;
		zadd2=*zadd;

		if (collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) return(FALSE);

		obj->pnt.z+=zadd2;

		xadd2=*xadd;
		yadd2=0;
		zadd2=0;

		if (collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) return(FALSE);

		obj->pnt.x+=xadd2;

		return(FALSE);
	}
	
	if (lz==rz) {
		xadd2=*xadd;
		yadd2=0;
		zadd2=0;

		if (collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) return(FALSE);

		obj->pnt.x+=xadd2;

		xadd2=0;
		yadd2=0;
		zadd2=*zadd;

		if (collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) return(FALSE);

		obj->pnt.z+=zadd2;

		return(FALSE);
	}
	
		// get angle between the line and the object movement
			
	obj_vct.x=(float)*xadd;
	obj_vct.y=0.0f;
	obj_vct.z=(float)*zadd;
	vector_normalize(&obj_vct);
	
	vector_create(&line_vct,lx,0,lz,rx,0,rz);		// perpendicular vector (swap x/z)
	
		// get the angle between them

	f=vector_dot_product(&obj_vct,&line_vct);
	f=((float)acos(f))*RAD_to_ANG;

		// get angle of wall.  If the angle between the
		// collision lines is less than 90, then head down
		// the line the opposite way

	ang=angle_find(lx,lz,rx,rz);
	if (f<90.0f) ang=angle_add(ang,180.0f);

		// change the motion to reflect the angle of the wall
		// uses facing instead of motion to check so we
		// don't get motion build up from sliding against a wall
		
	rang=obj->ang.y;
	if (obj->forward_move.reverse) rang=angle_add(rang,180.0f);

	if (angle_dif(rang,ang,&cwise)<90.0f) {
		if (!obj->forward_move.reverse) {
			obj->motion.ang.y=ang;
		}
		else {
			obj->motion.ang.y=angle_add(ang,180.0f);
		}
	}

		// reduce movement to slide against the walls

	mz=*zadd/ws_step_factor;
	mx=*xadd/ws_step_factor;

	for (n=0;n!=ws_step_factor;n++) {

			// try z then x movement first

		xadd2=0;
		yadd2=0;
		zadd2=mz;

		hit=collide_object_to_map(obj,&xadd2,&yadd2,&zadd2);
		
		if (!hit) {
			obj->pnt.z+=zadd2;

			xadd2=mx;
			yadd2=0;
			zadd2=0;

			if (!collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) {
				obj->pnt.x+=xadd2;
			}

			continue;
		}

			// try x then z movement next

		xadd2=mx;
		yadd2=0;
		zadd2=0;

		hit=collide_object_to_map(obj,&xadd2,&yadd2,&zadd2);

		if (!hit) {
			obj->pnt.x+=xadd2;

			xadd2=0;
			yadd2=0;
			zadd2=mz;

			if (!collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) {
				obj->pnt.z+=zadd2;
			}
		}
	}
	
	return(FALSE);
}
Пример #17
0
double vector_norm(struct vector* v) {
    double norm_squared = vector_dot_product(v, v);
    return sqrt(norm_squared);
}
Пример #18
0
uint8_t quest(vector v_B_c, vector v_sun_c, vector v_B_m, float sun_adc[], quaternion q_triad, uint8_t * p_w_ctrl)
{
  uint8_t w_ctrl = *p_w_ctrl;
  static uint16_t time_since_light;
  static uint8_t light_prev = 1;
  
  uint8_t light = 1, num_dark_sensors = 0, i, j;
  vector v_sun_m, v_cross_m, v_cross_c, v_mc_cross, v_mc_add;
  vector v_temp1, v_temp2;
  vector v_triad;
  float mu, nu, rho, k, triad;
  
  for(i = 0; i < N_SS; i++)
  {
    if(sun_adc[i] < (0.5 * SS_GAIN))
      num_dark_sensors++;
  }
  if(num_dark_sensors == N_SS)
    light = 0;
  
  if(light)
  {
    if(!w_ctrl)
    {
      time_since_light += FRAME_TIME;
      if(time_since_light == 300)
        w_ctrl = 0;
    }
    
    if(light_prev == 0)
    {
      w_ctrl = 0;
      time_since_light = 0;
    }
    
    for(i = 0; i < (N_SS / 2); i++)
    {
      j = i * 2;
      if(sun_adc[j] > sun_adc[j + 1])
        v_sun_m[i] = (float)sun_adc[j];
      else
        v_sun_m[i] = -1 * (float)sun_adc[j + 1];
    }
    convert_unit_vector(v_sun_m);
    
    /*v_B_m[0] = Current_state.mm.B_x;
    v_B_m[1] = Current_state.mm.B_y;
    v_B_m[2] = Current_state.mm.B_z;*/
    
    vector_cross_product(v_B_m, v_sun_m, v_cross_m);
    convert_unit_vector(v_cross_m);
    
    vector_cross_product(v_B_c, v_sun_c, v_cross_c);
    convert_unit_vector(v_cross_c);
    
    mu = (1 + vector_dot_product(v_cross_m, v_cross_c)) * (MAG_WEIGHT * vector_dot_product(v_B_m, v_B_c) + (1 - MAG_WEIGHT) * vector_dot_product(v_sun_m, v_sun_c));
    
    vector_cross_product(v_B_m, v_B_c, v_temp1);
    vector_cross_product(v_sun_m, v_sun_c, v_temp2);
    for(i = 0; i < 3; i++)
      v_temp2[i] = v_temp1[i] * MAG_WEIGHT + (1 - MAG_WEIGHT) * v_temp2[i];
    vector_cross_product(v_cross_m, v_cross_c, v_mc_cross);
    
    mu += vector_dot_product(v_mc_cross, v_temp2);
    
    add_vectors(v_cross_m, v_cross_c, v_mc_add);
    
    nu = vector_dot_product(v_mc_add, v_temp2);
    
    rho = sqrt(mu * mu + nu * nu);
    
    if(mu > 0)
    {
      k = 1 / (2 * sqrt(rho * (rho + mu) * (1 + vector_dot_product(v_cross_m, v_cross_c))));
      
      for(i = 0; i < 3; i++)
        v_triad[i] = v_mc_cross[i] * (rho + mu) + v_mc_add[i] * nu;
      
      triad = (rho + mu) * (1 + vector_dot_product(v_cross_m, v_cross_c));
      
    }
    else
    {
      k = 1 / (2 * sqrt(rho * (rho - mu) * (1 + vector_dot_product(v_cross_m, v_cross_c))));
      
      for(i = 0; i < 3; i++)
        v_triad[i] = v_mc_cross[i] * nu + v_mc_add[i] * (rho - mu);
      
      triad = nu * (1 + vector_dot_product(v_cross_m, v_cross_c));
      
    }
    for(i = 0; i < 3; i++)
      q_triad[i] = v_triad[i];
    q_triad[3] = triad;
      
    scalar_into_quaternion(q_triad, k);
  }
  else
  {
    for(i = 0; i < 3; i++)
      q_triad[i] = 0;
    q_triad[3] = 1;
  }
  light_prev = light;
  return light;
}