Beispiel #1
0
static int _llfunc_vec4_add(lua_State *L) {
	vec4 *a = (vec4*)userdata_get_or_die(L, 1);
	vec4 *b = (vec4*)userdata_get_or_die(L, 2);
	vec4 *r = (vec4*)userdata_get_or_new(L, 3, sizeof(vec4));
	vec4_add(a, b, r);
	return 1;
}
Beispiel #2
0
void	make_inv(t_vec4 inv[4], t_vec4 vec[4], t_vec4 faces[6], t_vec4 sign[2])
{
	inv[0] = vec4_add(vec4_sub(vec4_mul(vec[1], faces[0]),
							vec4_mul(vec[2], faces[1])),
					vec4_mul(vec[3], faces[2]));
	inv[1] = vec4_add(vec4_sub(vec4_mul(vec[0], faces[0]),
							vec4_mul(vec[2], faces[3])),
					vec4_mul(vec[3], faces[4]));
	inv[2] = vec4_add(vec4_sub(vec4_mul(vec[0], faces[1]),
							vec4_mul(vec[1], faces[3])),
					vec4_mul(vec[3], faces[5]));
	inv[3] = vec4_add(vec4_sub(vec4_mul(vec[0], faces[2]),
							vec4_mul(vec[1], faces[4])),
					vec4_mul(vec[2], faces[5]));
	sign[0].s = (t_4dvec){+1, -1, +1, -1};
	sign[1].s = (t_4dvec){-1, +1, -1, +1};
}
Beispiel #3
0
void point_calc_normal(Point *point, distance_func sdf)
{
  float eps = 0.1e-4;
  vec4 pos = {point->pos[0], point->pos[1], point->pos[2], 1.0};
  vec4 epsX = {eps, 0.f, 0.f, 0.0f};
  vec4 epsY = {0.f, eps, 0.f, 0.0f};
  vec4 epsZ = {0.f, 0.f, eps, 0.0f};

  vec4 ppx, psx, ppy, psy, ppz, psz;
  vec4_add(ppx, pos, epsX);
  vec4_add(ppy, pos, epsY);
  vec4_add(ppz, pos, epsZ);
  vec4_sub(psx, pos, epsX);
  vec4_sub(psy, pos, epsY);
  vec4_sub(psz, pos, epsZ);

  point->norm[0] = sdf(ppx) - sdf(psx);
  point->norm[1] = sdf(ppy) - sdf(psy);
  point->norm[2] = sdf(ppz) - sdf(psz);
  vec3_norm(point->norm, point->norm);
}
Beispiel #4
0
/* this function is needed for a serious hack that I really
 * hate doing.  R.I.P. clean code R.I.P. */
ray_t* ray_tinypush(ray_t *rayout, const ray_t *ray)
{
	vector4_t v;
	vec4_set(&v, (float *)&ray->direction);
	/* make sure direction was normalized */
	vec4_normalize(&v);
	/* create a tiny displacement vector along direction */
	vec4_scale(&v, &v, 0.001f);
	/* copy the ray */
	ray_copy(rayout, ray);
	/* display the new rays origin */
	vec4_add(&rayout->origin, &rayout->origin, &v);

	return rayout;
}
Beispiel #5
0
/* reverse the direction and origin of a ray */
ray_t* ray_reverse(ray_t *rayout, const ray_t *ray)
{
	ray_t tmpray;
	ray_copy(&tmpray, ray);
	/* scale original direction by magnitude of ray */
	vec4_scale(&tmpray.direction, &ray->direction, ray->magnitude);
	/* origin of new ray is destination of original ray */
	vec4_add(&rayout->origin, &tmpray.direction, &ray->origin);	
	/* copy magnitude straight over */
	rayout->magnitude = ray->magnitude;
	/* direction of new ray is reverse that of old ray */
	vec4_scale(&rayout->direction, &tmpray.direction, -1.0f);

	return rayout;
}
Beispiel #6
0
int main(int argc, char **argv) 
{
	SDL_Surface *screen;
	SDL_Event event;
	struct vec4 cubeCenter, cube[8];
	scalar rota;
	struct mat4 rot;
	int i;

	SDL_Init( SDL_INIT_EVERYTHING ); 

	screen = SDL_SetVideoMode(width, height, 32, 0);

	proj = proj_perspective(45, (scalar) width / (scalar) height, 1, 10);

	cubeCenter = vec4_zero();

	while(1) 
	{
		rota = (scalar) SDL_GetTicks() / 1000.0;
		cubeCenter.z = 5 + sin(rota);
		rot = mat4_aangle(_vec4(0, 1, 0, 1), rota);

		cube[0] = vec4_add(mat4_mulv(rot, _vec4( 1, -1, 1, 0)), cubeCenter);
		cube[1] = vec4_add(mat4_mulv(rot, _vec4(-1, -1, 1, 0)), cubeCenter);
		cube[2] = vec4_add(mat4_mulv(rot, _vec4(-1,  1, 1, 0)), cubeCenter);
		cube[3] = vec4_add(mat4_mulv(rot, _vec4( 1,  1, 1, 0)), cubeCenter);

		cube[4] = vec4_add(mat4_mulv(rot, _vec4( 1, -1, -1, 0)), cubeCenter);
		cube[5] = vec4_add(mat4_mulv(rot, _vec4(-1, -1, -1, 0)), cubeCenter);
		cube[6] = vec4_add(mat4_mulv(rot, _vec4(-1,  1, -1, 0)), cubeCenter);
		cube[7] = vec4_add(mat4_mulv(rot, _vec4( 1,  1, -1, 0)), cubeCenter);

		SDL_FillRect(screen, 0, 0);

		drawLine3d(screen, cube[0], cube[1]);
		drawLine3d(screen, cube[0], cube[3]);
		drawLine3d(screen, cube[1], cube[2]);
		drawLine3d(screen, cube[2], cube[3]);

		drawLine3d(screen, cube[4], cube[5]);
		drawLine3d(screen, cube[4], cube[7]);
		drawLine3d(screen, cube[5], cube[6]);
		drawLine3d(screen, cube[6], cube[7]);

		drawLine3d(screen, cube[0], cube[4]);
		drawLine3d(screen, cube[1], cube[5]);
		drawLine3d(screen, cube[2], cube[6]);
		drawLine3d(screen, cube[3], cube[7]);

		SDL_Flip(screen);

		while(SDL_PollEvent(&event) != 0)
		{
			switch(event.type)
			{
				case (SDL_QUIT):
					SDL_Quit();
					return 0;
				default:
					break;
			}
		}
	}

	SDL_Quit(); 
	return 0;
}
Beispiel #7
0
/* tests if ray intersects a given polygon */
int ray_intersect_polygon(const ray_t *ray, const polygon_t* poly,
							point_t *pt, float *distance)
{
	float num = -1.0f * (
		vec4_dot((vector4_t *)&poly->plane, &ray->origin) +
		poly->plane.F);
	float den = vec4_dot((vector4_t *)&poly->plane, &ray->direction);
	float w;
	unsigned int i = 0;		/* counter variable for loop */
	double angleTotal = 0.0;	/* running total of angle */
	double angleTmp = 0.0;		/* angle between current two vectors */	
	vector4_t tmp;
	vector4_t tmp2;
#ifdef __SPU__
	vector float vTmp;
#endif

	/* if denomenator = 0, ray is parallel to plane */
	if(den == 0.0f)
	{	/* return no intersection */
		return 0;
	}

	w = num / den;		/* distance to intersection */
	/* if w < 0, intersection point is behind ray */
	if(w < 0.0f)
	{	/* return no intersection */
		return 0;
	}

	/* now w is least positive root */
	/* use it to calculate where intersection point is */
	vec4_add(pt, &ray->origin,
		vec4_scale(&tmp, &ray->direction, w));
	*distance = w;		/* pass back distance to intersection */

	/* at this point we at least know the ray intersects the plane.
	 * let's figure out if the point is actually inside the confined
	 * polygonal area */
	for(i = 0; i < poly->nVerticies; ++i)
	{
		if(i == (poly->nVerticies - 1))
		{	/* last vertex, compare with first */
			/* calculate two vectors */
			vec4_sub(&tmp, &poly->vertex[i], pt);
			vec4_sub(&tmp2, &poly->vertex[0], pt);
			/* find angle between them - between normal vectors, dot
			 * product is cos of angle between them */
#ifdef __SPU__
			vTmp[0] = vec4_costheta(&tmp, &tmp2);
			vTmp = _acosf4(vTmp);
			angleTotal += vTmp[0];
#else
			angleTmp = vec4_costheta(&tmp, &tmp2);
			/* arccos to get theta */
			angleTmp = acos(angleTmp);
			angleTotal += angleTmp;
#endif
		}
		else
		{
			/* calculate two vectors */
			vec4_sub(&tmp, &poly->vertex[i], pt);
			vec4_sub(&tmp2, &poly->vertex[i+1], pt);
			/* find angle between them - between normal vectors, dot
			 * product is cos of angle between them */
#ifdef __SPU__
			vTmp[0] = vec4_costheta(&tmp, &tmp2);
			vTmp = _acosf4(vTmp);
			angleTotal += vTmp[0];
#else
			angleTmp = vec4_costheta(&tmp, &tmp2);
			/* arccos to get theta */
			angleTmp = acos(angleTmp);
			angleTotal += angleTmp;
#endif
		}
	}

	/* TODO: this comparison is weak, should be refined */
	if((angleTotal + .001) > (2.0 * M_PI))
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
Beispiel #8
0
/* tests if ray intersects a given sphere */
int ray_intersect_sphere(const ray_t *ray, const sphere_t* sphere,
							point_t *pt, float *distance)
{
	vector4_t	tmp;	/* used to hold scale of ray direction */
	float A = 1;	/* since we know ray direction is normalized */
	float dx = ray->origin.x - sphere->center.x;
	float dy = ray->origin.y - sphere->center.y;
	float dz = ray->origin.z - sphere->center.z;
	float B = 2 * (
		ray->direction.x * (dx) +
		ray->direction.y * (dy) +
		ray->direction.z * (dz));
	float C = (dx * dx + dy * dy + dz * dz) 
		- (sphere->radius * sphere->radius);
	float det = (B*B) - (4 * A * C);
	float wOne;	/* distance to first intersection */
	float wTwo;	/* distance to second intersection */
	float w = 0.0f;	/* least positive w */
#ifdef __SPU__
	vector float vTmp;
	float	scalarTmp;
#endif

	if(det < 0.0f)
	{	/* intersection is behind ray so none at all*/
		return 0;
	}
	else
	{	/* no need to use A since it's 1 */
#ifdef __SPU__
		vTmp = spu_promote(det, 0);
		scalarTmp = spu_extract(
				_sqrtf4(vTmp), 0);
		wOne = (-B - scalarTmp) / (2.0f * A);
		wTwo = (-B + scalarTmp) / (2.0f * A);
#else
		wOne = (-B - sqrt(det)) / (2.0f * A);
		wTwo = (-B + sqrt(det)) / (2.0f * A);
#endif

		if(det == 0.0f)
		{	/* one root, wOne and wTwo should be equal */
			vec4_add(pt, &ray->origin, 
				vec4_scale(&tmp, &ray->direction, wOne));
			*distance = wOne;	/* pass back distance to intersection */
			return 1;
		}
		else
		{
			if(wOne > 0.0f)
				w = wOne;
			if(wTwo > 0.0f && wTwo < w)
				w = wTwo;
			/* now w is least positive root */
			/* use it to calculate where intersection point is */
			vec4_add(pt, &ray->origin, 
				vec4_scale(&tmp, &ray->direction, w));
			*distance = w;		/* pass back distance to intersection */
			return 1;
		}
	}

	/* all code paths above this point should have returned something
	 * but if we've gotten here anyways, assume no intersection occured */
#if defined(_DEBUG)
	printf("Ray-Sphere intersection test failed!!!\n");
#endif
	return 0;
}