Beispiel #1
0
int main( int argc, char *argv[] )
{
    gdouble max_area = 0.0001;
    gdouble min_angle = RADIANS(15.0);
    guint niter = 10;

    Polygon *p = polygon_create_box( 0.0, 0.0, 1.0, 1.0 );
    /* Polygon *p = polygon_create_island(); */
    /* Polygon *p = polygon_create_A(); */

    /* ELEMENT QUALITY SMOOTHING */
    Mesh * mesh = mesh_triangulate_polygon( p );
    mesh_make_cdt_by_edge_flipping( mesh );
    polygon_free( p );
    
    mesh_refine( mesh, RUPPERT_REFINEMENT, max_area, min_angle );
    mesh_relax( mesh );
    mesh_smooth( mesh, ELEMENT_QUALITY_SMOOTHING, niter, max_area );
    mesh_relax( mesh );
    mesh_smooth( mesh, ELEMENT_QUALITY_SMOOTHING, niter, max_area );
    mesh_save_to_eps( "mesh.eps", mesh );
    mesh_save_to_obj( "mesh.obj", mesh );

    mesh_free( mesh );

    return EXIT_SUCCESS;
}
Beispiel #2
0
int test_refine( int argc, char *argv[] )
{
    /* Polygon *p = polygon_create_box( 0.0, 0.0, 1.0, 1.0 ); */
    Polygon *p = polygon_create_island();
    Mesh *mesh = mesh_triangulate_polygon( p );
    mesh_save_to_eps( "test_refine_1.eps", mesh );
    polygon_free( p );

    mesh_make_cdt_by_edge_flipping( mesh );
    mesh_save_to_eps( "test_refine_2.eps", mesh );
    mesh_refine( mesh, RUPPERT_REFINEMENT, 0.0007, RADIANS(30) );
    mesh_save_to_eps( "test_refine_3.eps", mesh );
    mesh_save_to_ply( "test_refine_3.ply", mesh );
    mesh_save_to_poly( "test_refine_3.poly", mesh );
    mesh_save_to_obj( "test_refine_3.obj", mesh );
    mesh_save_to_off( "test_refine_3.off", mesh );
    mesh_free( mesh );

    return EXIT_SUCCESS;
}
Beispiel #3
0
static OverlapInfo *
overlap(double t, stateVector *st, BeamModeInfo *bmi, double look_angle,
        int zone, double clat, double clon, Poly *aoi)
{
  Poly *viewable_region =
    get_viewable_region(st, bmi, look_angle, zone, clat, clon, NULL, NULL);

  if (!viewable_region)
    return NULL; // no overlap

  if (polygon_overlap(aoi, viewable_region)) {
    // need a good method to test for overlap amount!
    // for now we have this sort of kludgey method... which is
    // probably a bit slow:
    //   generate 1000 points in the aoi -- pct is how many are also
    //   in the viewable region
    srand(42);
    int i=0,pct=0,n=1000;
    double xmin, xmax, ymin, ymax;
    polygon_get_bbox(aoi, &xmin, &xmax, &ymin, &ymax);

    while (i<n) {
      double x = random_in_interval(xmin, xmax);
      double y = random_in_interval(ymin, ymax);
      if (point_in_polygon(aoi, x, y)) {
        ++i;
        if (point_in_polygon(viewable_region, x, y))
          ++pct;
      }
    }

    return overlap_new(pct, n, viewable_region, zone, clat, clon, st, t);
  }
  else {
    // no overlap
    polygon_free(viewable_region);
    return NULL;
  }
}
Beispiel #4
0
void overlap_free(OverlapInfo *oi)
{
    if (oi && oi->viewable_region)
      polygon_free(oi->viewable_region);
    FREE(oi);
}
Beispiel #5
0
/*
 * Draw the module into the image using the given view transformation matrix [VTM], 
 * Lighting and DrawState by traversing the list of Elements. 
 * (For now, Lighting can be an empty structure.)
 */
void module_draw(Module *md, Matrix *VTM, Matrix *GTM, DrawState *ds, 
				Lighting *lighting, Image *src){
				
	/* for antialiasing
	Module *thickLineMod = module_create();			
	Element *thickLineE;
	float dx, dy, dz, lineLength;
	Vector u, v, w;*/
	
	// all locally needed variables
	Matrix LTM, tempGTM;
	Line tempLine;
	DrawState *tempds = drawstate_create();
	Point tempPointLTM, tempPointGTM, tempPointVTM;
	Polyline *tempPolyline = polyline_create();
	Polygon *tempPolygon = polygon_create();
	Element *e = md->head;
	
	matrix_identity(&LTM);
	
	// loop until the end of the linked list is reached
	while(e){
		//printf("Handling type %d\n", e->type);
		// draw based on type
		switch(e->type){
			case ObjNone:
				break;
			case ObjPoint:
				//printf("drawing point ");
				// copy, xform, normalize, draw
				matrix_xformPoint(&LTM, &(e->obj.point), &tempPointLTM);
				matrix_xformPoint(GTM, &tempPointLTM, &tempPointGTM);
				matrix_xformPoint(VTM, &tempPointGTM, &tempPointVTM);
				point_normalize(&(tempPointVTM));
				//point_print(&tempPointVTM, stdout);
				point_draw(&tempPointVTM, src, ds->color);
				break;
			case ObjLine:
				line_copy(&tempLine, &(e->obj.line));
				//printf("drawing line ");
				// copy, xform, normalize, draw
				matrix_xformLine(&LTM, &tempLine);
				matrix_xformLine(GTM, &tempLine);
				matrix_xformLine(VTM, &tempLine);
				line_normalize(&tempLine);
				line_draw(&tempLine, src, ds->color);
				//line_print(&tempLine, stdout);
				/*if(antialias){
					dx = tempLine.b.val[0]-tempLine.a.val[0];
					dy = tempLine.b.val[1]-tempLine.a.val[1];
					dz = tempLine.b.val[2]-tempLine.a.val[2];
					lineLength = sqrt(dx*dx+dy*dy+dz*dz);
					module_scale( thickLineMod, 1, lineLength, 1 );
					vector_set(&v, dx, dy, dz);
					vector_normalize(&v);
					vector_set(&u, -dz, dx, dy);
					vector_cross(&u, &v, &w);
					vector_cross(&v, &w, &u);
					vector_normalize(&u);
					vector_normalize(&w);
					module_rotateXYZ( thickLineMod, &u, &v, &w );
					module_translate( thickLineMod,	tempLine.a.val[0], 
													tempLine.a.val[1], 
													tempLine.a.val[2] );
					module_cylinder( thickLineMod, 4, 1, 1, 0, 0, 0 );
					thickLineE = element_init(ObjModule, thickLineMod);
					thickLineE->next = e->next;
					e->next = thickLineE;
				}*/
				break;
			case ObjPolyline:
				//printf("drawing polyline ");
				// copy, xform, normalize, draw
				polyline_copy(tempPolyline, &(e->obj.polyline));
				matrix_xformPolyline(&LTM, tempPolyline);
				matrix_xformPolyline(GTM, tempPolyline);
				matrix_xformPolyline(VTM, tempPolyline);
				polyline_normalize(tempPolyline);
				//polyline_print(tempPolyline, stdout);
				polyline_draw(tempPolyline, src, ds->color);
				break;
			case ObjPolygon:
				//printf("drawing polygon ");
				// copy, xform, normalize, draw
				polygon_copy(tempPolygon, &(e->obj.polygon));
				matrix_xformPolygon(&LTM, tempPolygon);
				matrix_xformPolygon(GTM, tempPolygon);
				matrix_xformPolygon(VTM, tempPolygon);
				polygon_normalize(tempPolygon);
				//polygon_print(tempPolygon, stdout);
				polygon_draw(tempPolygon, src, ds);
				break;
			case ObjColor:
				drawstate_setColor(ds, e->obj.color);
				break;
			case ObjBodyColor:
				break;
			case ObjSurfaceColor:
				break;
			case ObjSurfaceCoeff:
				break;
			case ObjLight:
				break;
			case ObjIdentity:
				matrix_identity(&LTM);
				break;
			case ObjMatrix:
				matrix_multiply(&(e->obj.matrix), &LTM, &LTM);
				break;
			case ObjModule:
				matrix_multiply(GTM, &LTM, &tempGTM);
				drawstate_copy(tempds, ds);
				module_draw(e->obj.module, VTM, &tempGTM, tempds, lighting, src);
				break;
			default:
				printf("ObjectType %d is not handled in module_draw\n",e->type);
		}
		
		// advance traversal
		e = e->next;
	}
	
	// clean up
	polygon_free(tempPolygon);
	polyline_free(tempPolyline);
	free(tempds);
}
Beispiel #6
0
/*
 * use the de Casteljau algorithm to subdivide the Bezier surface divisions times,
 * then draw either the lines connecting the control points, if solid is 0, 
 * or draw triangles connecting the surface.
 */
void module_bezierSurface(Module *m, BezierSurface *b, int divisions, int solid){
	int i, j, k, l;
	Line tempLine;
	Point grid[7][7];
	Point controls[7];
	Point deCast[7];
	Point surfacePoints[16];
	BezierSurface tempBezSurf;
	Polygon *temptri = polygon_create();
	if(!m || !b){
		printf("Null passed to module_bezierSurface\n");
		return;
	}
	
	// base case
	if(divisions == 0){
		// lines
		if(solid == 0){
			for(i=0;i<4;i++){
				for(j=0;j<3;j++){
					line_set(&tempLine, b->c[i][j], b->c[i][j+1]);
					module_line(m, &tempLine);
					line_set(&tempLine, b->c[j][i], b->c[j+1][i]);
					module_line(m, &tempLine);
				}
			}
		} 
		// triangles
		else {
			controls[0] = b->c[0][0];
			controls[1] = b->c[0][3];
			controls[2] = b->c[3][3];
			controls[3] = b->c[3][0];
			controls[4] = b->c[0][0];
			polygon_set(temptri, 3, &(controls[0]));
			module_polygon(m, temptri);
			polygon_set(temptri, 3, &(controls[2]));
			module_polygon(m, temptri);
		}
	}
	
	// divide and recurse
	else {

		// compute all avg points for 3 orders, down to just one point 3rd order
		// do for each of the four bezier curves
		for(i=0;i<4;i++){
			deCasteljau(&(deCast[0]), &(b->c[i][0]));
			for(j=0;j<7;j++){
				grid[2*i][j] = deCast[j];
			}
		}

		// now traverse the other direction, populating grid
		for(i=0;i<7;i++){
			for(j=0;j<4;j++){
				controls[j] = grid[2*j][i];
			}
			deCasteljau(&(deCast[0]), &(controls[0]));
			for(j=0;j<7;j++){
				grid[j][i] = deCast[j];
			}
		}

		// now make the four new bezier surfaces by subdividing across
		for(i=0;i<2;i++){
			for(j=0;j<2;j++){
				for(k=0;k<4;k++){
					for(l=0;l<4;l++){
						surfacePoints[4*k+l] = grid[k+3*i][l+3*j];
					}
				}
				bezierSurface_set(&tempBezSurf, &(surfacePoints[0]));
				// recursive call
				module_bezierSurface(m, &tempBezSurf, divisions-1, solid);
			}
		}
	}
	
	// clean up
	polygon_free(temptri);
}
Beispiel #7
0
int main(int argc, char *argv[]){
	Image* src;
	int offset = 100;
	const int rows = 1000;
  	const int cols = 1000;
  	float r1, r2, r3, r4, r5, r6, r7, r8, r9;
  	int i;
	Color RED;
	Color GREEN;
	Color BLUE;
	Color WHITE;
	Color c1;
	Color c2;
	Color c3;
	Polygon* poly;
	Point points[3];
	char filename[100];
	
	Color_set(&RED, 1.0, 0.0, 0.0);
	Color_set(&GREEN, 0.0, 1.0, 0.0);
	Color_set(&BLUE, 0.0, 0.0, 1.0);
	Color_set(&WHITE, 1.0,1.0,1.0);

	for(i=0; i<offset+1; i++){
		src = image_create(rows, cols);

		//drawing the first triangle
		printf("Preparing and drawing triangle 0\n");
		point_set2D(&points[0], 300, (100 - offset + i));
		point_set2D(&points[1], 700, (100 - offset + i));
		point_set2D(&points[2], 500, (500 - offset + i));

		poly = polygon_createp(3, points);
		r1 = rand()/((double) RAND_MAX);
		r2 = rand()/((double) RAND_MAX);
		r3 = rand()/((double) RAND_MAX);
		r4 = rand()/((double) RAND_MAX);
		r5 = rand()/((double) RAND_MAX);
		r6 = rand()/((double) RAND_MAX);
		r7 = rand()/((double) RAND_MAX);
		r8 = rand()/((double) RAND_MAX);
		r9 = rand()/((double) RAND_MAX);

		Color_set(&c1, r1, r2, r3);
		Color_set(&c2, r4, r5, r6);
		Color_set(&c3, r7, r8, r9);

		polygon_drawFillB_Gradient(poly, src, c1, c2, c3);


		//drawing the second triangle
		printf("Preparing and drawing triangle 1\n");
		point_set2D(&points[0], 700+offset-i, 100-(offset-i)/2);
		point_set2D(&points[1], 900+offset-i, 500-(offset-i)/2);
		point_set2D(&points[2], 500+offset-i, 500-(offset-i)/2);
		

		poly = polygon_createp(3, points);
		r1 = rand()/((double) RAND_MAX);
		r2 = rand()/((double) RAND_MAX);
		r3 = rand()/((double) RAND_MAX);
		r4 = rand()/((double) RAND_MAX);
		r5 = rand()/((double) RAND_MAX);
		r6 = rand()/((double) RAND_MAX);
		r7 = rand()/((double) RAND_MAX);
		r8 = rand()/((double) RAND_MAX);
		r9 = rand()/((double) RAND_MAX);

		Color_set(&c1, r1, r2, r3);
		Color_set(&c2, r4, r5, r6);
		Color_set(&c3, r7, r8, r9);

		polygon_drawFillB_Gradient(poly, src, c1, c2, c3);


		//drawing the third triangle
		printf("Preparing and drawing triangle 2\n");
		point_set2D(&points[0], 900+offset-i, 500+(offset-i)/2);
		point_set2D(&points[1], 700+offset-i, 900+(offset-i)/2);
		point_set2D(&points[2], 500+offset-i, 500+(offset-i)/2);

		poly = polygon_createp(3, points);
		r1 = rand()/((double) RAND_MAX);
		r2 = rand()/((double) RAND_MAX);
		r3 = rand()/((double) RAND_MAX);
		r4 = rand()/((double) RAND_MAX);
		r5 = rand()/((double) RAND_MAX);
		r6 = rand()/((double) RAND_MAX);
		r7 = rand()/((double) RAND_MAX);
		r8 = rand()/((double) RAND_MAX);
		r9 = rand()/((double) RAND_MAX);

		Color_set(&c1, r1, r2, r3);
		Color_set(&c2, r4, r5, r6);
		Color_set(&c3, r7, r8, r9);

		polygon_drawFillB_Gradient(poly, src, c1, c2, c3);


		//drawing the forth triangle
		printf("Preparing and drawing triangle 3\n");
		point_set2D(&points[0], 300, 900 + offset - i);
		point_set2D(&points[1], 700, 900 + offset - i);
		point_set2D(&points[2], 500, 497 + offset - i);

		poly = polygon_createp(3, points);
		r1 = rand()/((double) RAND_MAX);
		r2 = rand()/((double) RAND_MAX);
		r3 = rand()/((double) RAND_MAX);
		r4 = rand()/((double) RAND_MAX);
		r5 = rand()/((double) RAND_MAX);
		r6 = rand()/((double) RAND_MAX);
		r7 = rand()/((double) RAND_MAX);
		r8 = rand()/((double) RAND_MAX);
		r9 = rand()/((double) RAND_MAX);

		Color_set(&c1, r1, r2, r3);
		Color_set(&c2, r4, r5, r6);
		Color_set(&c3, r7, r8, r9);

		polygon_drawFillB_Gradient(poly, src, c1, c2, c3);


		//drawing the fifth triangle
		printf("Preparing and drawing triangle 4\n");
		point_set2D(&points[0], 100-offset+i, 500+(offset-i)/2);
		point_set2D(&points[1], 300-offset+i, 900+(offset-i)/2);
		point_set2D(&points[2], 500-offset+i, 500+(offset-i)/2);

		poly = polygon_createp(3, points);
		r1 = rand()/((double) RAND_MAX);
		r2 = rand()/((double) RAND_MAX);
		r3 = rand()/((double) RAND_MAX);
		r4 = rand()/((double) RAND_MAX);
		r5 = rand()/((double) RAND_MAX);
		r6 = rand()/((double) RAND_MAX);
		r7 = rand()/((double) RAND_MAX);
		r8 = rand()/((double) RAND_MAX);
		r9 = rand()/((double) RAND_MAX);

		Color_set(&c1, r1, r2, r3);
		Color_set(&c2, r4, r5, r6);
		Color_set(&c3, r7, r8, r9);

		polygon_drawFillB_Gradient(poly, src, c1, c2, c3);



	//drawing the sixth triangle
		printf("Preparing and drawing triangle 5\n");
		point_set2D(&points[0], 100-offset+i, 500-(offset-i)/2);
		point_set2D(&points[1], 301-offset+i, 100-(offset-i)/2);
		point_set2D(&points[2], 503-offset+i, 500-(offset-i)/2);

		poly = polygon_createp(3, points);
		r1 = rand()/((double) RAND_MAX);
		r2 = rand()/((double) RAND_MAX);
		r3 = rand()/((double) RAND_MAX);
		r4 = rand()/((double) RAND_MAX);
		r5 = rand()/((double) RAND_MAX);
		r6 = rand()/((double) RAND_MAX);
		r7 = rand()/((double) RAND_MAX);
		r8 = rand()/((double) RAND_MAX);
		r9 = rand()/((double) RAND_MAX);

		Color_set(&c1, r1, r2, r3);
		Color_set(&c2, r4, r5, r6);
		Color_set(&c3, r7, r8, r9);

		polygon_drawFillB_Gradient(poly, src, c1, c2, c3);

		if(i%5==0){
			sprintf(filename, "../images/task6_2_%3.0d.ppm",i);
			image_write(src, filename);
		}
		image_dealloc(src);

	}	
	system("convert -delay 10 -loop 0   ../images/task6_2_*.ppm   ../images/animation.gif");
	system("rm -f ../images/task6_2*");

	//clean up

	polygon_free(poly);
  	image_free(src);


	return 0;
}
Beispiel #8
0
int main(int argc, char *argv[]){
  Image *src;
  Ellipse elip;
  Circle circ;
  Color color, red, pink, yellow;
  Color blue; 
  Line l;
  Point p;
  Point pt[5];
  Polygon *poly;
  int i;

  /*set the colors*/
  color_set(&color, 1.0, 1.0, 1.0);
  color_set(&red, 1.0, 0.0,0.0);
  color_set(&blue, 0.4,1.0,1.0);
  color_set(&pink, 1.0, 0.6, 0.8);
  color_set(&yellow, 1.0, 1.0, 0.4);

  /*build an image*/
  src = image_create( 700,700); 

  /*build the cupcake like I was using turtle graphics*/
  line_set2D(&l, 100,300,200,600);
  line_draw( &l, src, pink );

  line_set2D(&l, 600,300,500,600);
  line_draw( &l, src, pink );

  point_set2D( &p, 600, 350 );
  ellipse_set(&elip, p, 40, 150,0);
  ellipse_draw(&elip, src, pink);

  point_set2D( &p, 300,350 );
  ellipse_set(&elip, p, 80, 250,0);
  ellipse_draw(&elip, src, pink);

  point_set2D( &p, 275,350 );
  ellipse_set(&elip, p, 75, 225,0);
  ellipse_draw(&elip, src, blue);

  point_set2D( &p, 250,350 );
  ellipse_set(&elip, p, 50, 200,0);
  ellipse_draw(&elip, src, blue);

  point_set2D( &p, 225,350 );
  ellipse_set(&elip, p, 25, 175,0);
  ellipse_draw(&elip, src, blue);

  point_set2D( &p, 200,350 );
  ellipse_set(&elip, p, 20, 150,0);
  ellipse_draw(&elip, src, blue);

  point_set2D( &p, 175,350 );
  ellipse_set(&elip, p, 15, 125,0);
  ellipse_draw(&elip, src, blue);

  point_set2D( &p, 150,350 );
  ellipse_set(&elip, p, 5, 75,0);
  ellipse_draw(&elip, src, blue);

  point_set2D( &p, 350, 100 );
  circle_set( &circ, p, 25 );
  circle_draw( &circ, src, red);

  /*write image*/
  image_write( src, "3Dimage.ppm" );

  /*free image*/
  image_free( src );

  /*this time fill the cupcake*/

  src = image_create( 700,700); 

  color_set(&pink, 1.0, 0.6, 0.8);
  point_set2D( &p, 600, 350 );
  ellipse_set(&elip, p, 40, 150,0);
  ellipse_drawFill(&elip, src, pink);
  
  point_set2D(&(pt[0]),100 ,300);
  point_set2D(&(pt[1]),600 ,300);
  point_set2D(&(pt[2]),505 ,600);
  point_set2D(&(pt[3]),198, 600);
  
  poly = polygon_createp(4, pt);
  polygon_drawFill(poly,src, pink);

  color_set(&pink, 1.0, 0.4, 0.8);
  point_set2D( &p, 300,350 );
  ellipse_set(&elip, p, 80, 250,0);
  ellipse_drawFill(&elip, src, pink);

  color_set(&pink, 1.0, 0., 0.8);
  for(i=0; i<10; i++){
    line_set2D(&l, 100-i,300-i,200,600);
    line_draw( &l, src, pink );

    line_set2D(&l, 600-i,300-i,500,600);
    line_draw( &l, src, pink );

    line_set2D(&l, 175-i, 300-i, 225, 623);
    line_draw(&l, src, pink);

    line_set2D(&l, 275-i, 280-i, 305, 636);
    line_draw(&l, src, pink);

    line_set2D(&l, 385-i, 280-i, 385, 640);
    line_draw(&l, src, pink);

    line_set2D(&l, 510-i, 300-i, 450, 630);
    line_draw(&l, src, pink);

  }


  point_set2D( &p, 295,350 );
  ellipse_set(&elip, p, 70, 230,0);
  ellipse_drawFill(&elip, src, yellow);

  color_set(&blue, 0.0,0.8,0.8);

  point_set2D( &p, 275,350 );
  ellipse_set(&elip, p, 75, 220,0);
  ellipse_drawFill(&elip, src, blue);

  color_set(&blue, 0.0,1.0,1.0);

  point_set2D( &p, 250,350 );
  ellipse_set(&elip, p, 50, 200,0);
  ellipse_drawFill(&elip, src, blue);

  color_set(&blue, 0.4,1.0,1.0);

  point_set2D( &p, 225,350 );
  ellipse_set(&elip, p, 25, 175,0);
  ellipse_drawFill(&elip, src, blue);

  color_set(&blue, 0.6,1.0,1.0);

  point_set2D( &p, 200,350 );
  ellipse_set(&elip, p, 20, 150,0);
  ellipse_drawFill(&elip, src, blue);

  color_set(&blue, 0.7,1.0,1.0);

  point_set2D( &p, 175,350 );
  ellipse_set(&elip, p, 15, 125,0);
  ellipse_drawFill(&elip, src, blue);

  color_set(&blue, 0.8,1.0,1.0);

  point_set2D( &p, 150,350 );
  ellipse_set(&elip, p, 5, 75,0);
  ellipse_drawFill(&elip, src, blue);

  point_set2D( &p, 350, 100 );
  circle_set( &circ, p, 25 );
  circle_drawFill( &circ, src, red);

  image_write( src, "3DimageFill.ppm" );

  polygon_free(poly);
  image_free( src );

  return(0);

}
void bsp_split_polygon_with_plane(const polygon_t* poly, const vec3_t normal, vec_t dist, bool* split, polygon_t* front, polygon_t* back)
{
	side_t side, lside, rside;
	vertex_t* last;
	vertex_t r;
	vec_t t;

	memset(front, 0, sizeof(polygon_t));
	memset(back, 0, sizeof(polygon_t));

	last = &poly->verts[poly->vertc - 1];
	lside = tr_side_of_point(last->coords, normal, dist);
	rside = lside;

	*split = false;

	if(poly->vertc < 3 && poly->vertc != 0)
	{
		fputs("HOUSTON HOUSTON WE GOT A PROBLEM!", stderr);
		fprintf(stderr, "SPLIT RECEIVED POLYGON WITH %d VERTICES!\n", poly->vertc);
		abort();
	}

	unsigned int i;
	for(i = 0; i < poly->vertc; i++)
	{
		side = tr_side_of_point(poly->verts[i].coords, normal, dist);

		switch(side)
		{
			case SAME:
				addtofront(&poly->verts[i]);
				addtoback(&poly->verts[i]);
				lside = SAME;
				break;

			case FRONT:
				if(rside == BACK)
					*split = true;

				switch(lside)
				{
					case FRONT:
					case SAME:
						break;

					case BACK:
						bsp_split_polygon_edge_with_plane(last, &poly->verts[i], normal, dist, split, &r, &t);

						addtofront(&r);
						addtoback(&r);
						break;	
				}

				addtofront(&poly->verts[i]);
				rside = FRONT;
				lside = FRONT;
				break;

			case BACK:
				if(rside == FRONT)
					*split = true;

				switch(lside)
				{
					case BACK:
					case SAME:
						break;

					case FRONT:
						bsp_split_polygon_edge_with_plane(last, &poly->verts[i], normal, dist, split, &r, &t);

						addtofront(&r);
						addtoback(&r);
						break;	
				}

				addtoback(&poly->verts[i]);
				rside = BACK;
				lside = BACK;
				break;
		}

		last = &poly->verts[i];
	}

	if(rside == FRONT || (*split))
	{
		vec3_copy(front->normal, poly->normal);
		front->material = poly->material;
		vec3_copy(front->tex_shift, poly->tex_shift);
		vec3_copy(front->tex_rotation, poly->tex_rotation);
		vec3_copy(front->tex_scale, poly->tex_scale);
	}

	else
	{
		front->vertc = 0;
		polygon_free(front);
	}

	if(rside == BACK || (*split))
	{
		vec3_copy(back->normal, poly->normal);
		back->material = poly->material;
		vec3_copy(back->tex_shift, poly->tex_shift);
		vec3_copy(back->tex_rotation, poly->tex_rotation);
		vec3_copy(back->tex_scale, poly->tex_scale);
	}

	else
	{
		back->vertc = 0;
		polygon_free(back);
	}

#if 0
	if(rside == SAME)
	{
		puts("rside is same!");
		front->vertc = 0;
		polygon_free(front);

		back->vertc = 0;
		polygon_free(back);
	}
#endif

	if(front->vertc < 3 && front->vertc != 0)
	{
		fputs("HOUSTON HOUSTON WE GOT A PROBLEM!", stderr);
		fprintf(stderr, "SPLIT MADE FRONT POLYGON WITH %d VERTICES!\n", front->vertc);
		abort();
	}

	if(back->vertc < 3 && back->vertc != 0)
	{
		fputs("HOUSTON HOUSTON WE GOT A PROBLEM!", stderr);
		fprintf(stderr, "SPLIT MADE BACK POLYGON WITH %d VERTICES!\n", back->vertc);
		abort();
	}


}
void bsp_make_node_from_polygons(bsp_node_t* node, bsp_node_t* parent, const side_t side_of_parent, const polygon_t* polys, unsigned long int polyc)
{
	polygon_t* front_list = NULL;
	polygon_t* back_list = NULL;

	unsigned long int front_count = 0;
	unsigned long int back_count = 0;

	polygon_t front, back;
	bool split;

	memset(node, 0, sizeof(bsp_node_t));

	vec3_copy(node->normal, polys[0].normal);
	node->dist = vec3_dotproduct(polys[0].verts[0].coords, node->normal);

	node->parent = parent;
	node->side_of_parent = side_of_parent;

	unsigned long int i;
	for(i = 0; i < polyc; i++)
	{
		bsp_split_polygon_with_plane(&polys[i], node->normal, node->dist, &split, &front, &back);

		if(front.vertc == 0 && back.vertc == 0)
		{
			addtonode(&polys[i]);
			continue;
		}

#if __DEBUG__
		if(i == 0)
		{
			puts("ERROR: first poligon not on node?!");
			abort();
		}
#endif

		if(front.vertc > 0)
		{
			addtofront(&front);
			polygon_free(&front);
		}

		if(back.vertc > 0)
		{
			addtoback(&back);
			polygon_free(&back);
		}
	}

#if __DEBUG__
	if(node->polygoncount == 0)
	{
		puts("ERROR: node without polygons?!");
		abort();
	}
#endif

	if(front_count > 0)
	{
		node->children[0] = malloc(sizeof(bsp_node_t));
		bsp_make_node_from_polygons(node->children[0], node, FRONT, front_list, front_count);
	}

	else
		node->children[0] = NULL;

	free(front_list);

	if(back_count > 0)
	{
		node->children[1] = malloc(sizeof(bsp_node_t));
		bsp_make_node_from_polygons(node->children[1], node, BACK, back_list, back_count);
	}

	else
		node->children[1] = NULL;

	free(back_list);
}