Skip to content
Snippets Groups Projects
Commit ceb0fac1 authored by Taddeüs Kroes's avatar Taddeüs Kroes
Browse files

Graphics assignment 11

Finished the complete assignment.
parent 85db55d9
No related branches found
No related tags found
No related merge requests found
......@@ -5,14 +5,10 @@
* Date ............ 23.11.2009
* Created by ...... Paul Melis
*
* Student name ....
* Student email ...
* Collegekaart ....
* Date ............
* Comments ........
*
*
* (always fill in these fields before submitting!!)
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6169676 & 6054129
* Date ............ 01.12.2010
*/
#include <stdlib.h>
......@@ -20,6 +16,8 @@
#include <assert.h>
#include "bsp.h"
#define DOTPROD_TRESHOLD 1e-3
/* Given a list of polygons builds a BSP tree by recursively choosing
* one polygon that defines a split plane and dividing the other polygons
* arbitrarily into left and right subsets. This does NOT result in a
......@@ -135,6 +133,37 @@ void
split_triangle_one_edge_intersection(polys *left_polygons, polys *right_polygons,
vec3 plane_p, vec3 plane_n, poly p, int *side, int in_plane)
{
// Indices to the other vertices, vl is the one left of
// the split plane and vr is the one on the right
int vl = (in_plane + 1) % 3, vr = (in_plane + 2) % 3, temp;
float t;
poly p2 = p;
// Swap vl and vr if vl is on the right of the split plane
if( side[vl] == 1 )
{
temp = vl;
vl = vr;
vr = temp;
}
// Find the intersection
if( !check_for_intersection(&t, plane_p, plane_n, p.pts[vl], p.pts[vr]) )
{
puts("Plane does not go through the vertices");
exit(1);
}
// Change one vertex of each triangle to the intersection on the plane,
// do the same for the texture coordinates of these vertices
p2.pts[vl] = p.pts[vr] =
v3_add(v3_multiply(p.pts[vl], 1-t), v3_multiply(p.pts[vr], t));
p2.tcoord[vl] = p.tcoord[vr] =
v3_add(v3_multiply(p.tcoord[vl], 1-t), v3_multiply(p.tcoord[vr], t));
// The triangle with vl should be on the left of the plane
AddPolyToPolylist(left_polygons, p);
AddPolyToPolylist(right_polygons, p2);
}
/* Triangle 'p' is known to intersect the plane defined
......@@ -156,6 +185,45 @@ void
split_triangle_two_edge_intersections(polys *left_polygons, polys *right_polygons,
vec3 plane_p, vec3 plane_n, poly p, int *side, int single)
{
// Indices to the other vertices
int v1 = (single + 1) % 3, v2 = (single + 2) % 3;
float t1, t2;
poly p2 = p, p3 = p;
// Find intersection points
if( !check_for_intersection(&t1, plane_p, plane_n, p.pts[single], p.pts[v1])
|| !check_for_intersection(&t2, plane_p, plane_n, p.pts[single], p.pts[v2]) )
{
puts("Plane does not go through both edges");
exit(1);
}
// Change the vertices of the triangles so that there's no overlap and
// p is on the opposite side of the plane as p2 and p3. Do the same for
// the texture coordinates
p.pts[v1] = p3.pts[v1] = p2.pts[single] =
v3_add(v3_multiply(p.pts[single], 1-t1), v3_multiply(p.pts[v1], t1));
p.pts[v2] = p3.pts[single] =
v3_add(v3_multiply(p.pts[single], 1-t2), v3_multiply(p.pts[v2], t2));
p.tcoord[v1] = p3.tcoord[v1] = p2.tcoord[single] =
v3_add(v3_multiply(p.tcoord[single], 1-t1), v3_multiply(p.tcoord[v1], t1));
p.tcoord[v2] = p3.tcoord[single] =
v3_add(v3_multiply(p.tcoord[single], 1-t2), v3_multiply(p.tcoord[v2], t2));
// As said, p is on the opposite side as p2 and p3
if( side[single] == -1 )
{
AddPolyToPolylist(left_polygons, p);
AddPolyToPolylist(right_polygons, p2);
AddPolyToPolylist(right_polygons, p3);
}
else
{
AddPolyToPolylist(right_polygons, p);
AddPolyToPolylist(left_polygons, p2);
AddPolyToPolylist(left_polygons, p3);
}
}
/* Polygon 'p' (a triangle) is known to straddle the plane defined by
......@@ -173,6 +241,20 @@ void
split_triangle(polys *left_polygons, polys *right_polygons,
vec3 plane_p, vec3 plane_n, poly p, int *side)
{
for( int i = 0; i < 3; i++ )
{
if( !side[i] )
{
// Vertex found on plane, there's one intersection
split_triangle_one_edge_intersection(left_polygons, right_polygons,
plane_p, plane_n, p, side, i);
return;
}
}
// No vertex found on plane, there are two intersections
split_triangle_two_edge_intersections(left_polygons, right_polygons, plane_p,
plane_n, p, side, side[0] == side[1] ? 2 : (side[1] == side[2] ? 0 : 1));
}
/*
......@@ -183,5 +265,74 @@ split_triangle(polys *left_polygons, polys *right_polygons,
BSPNode*
BuildBSPTree(polys *polygons)
{
}
polys *left_polygons, *right_polygons;
BSPNode *left_tree, *right_tree;
BSPNode *root;
poly split_poly, p;
float dot;
vec3 plane_p, plane_n;
int side[MAX_VERTICES], i, j, left, right;
// Arbitrary initial capacity for the lists, they will grow as
// needed automatically
left_polygons = CreatePolylist(4);
right_polygons = CreatePolylist(4);
// Pick a polygon which defines the split plane
split_poly = polygons->items[0];
plane_p = split_poly.pts[0];
plane_n = split_poly.normal[0];
// Sort the remaining polygons in seperate trees, one left and one right of
// the split plane. We'll assume that all polygons are triangles
for( i = 1; i < polygons->length; i++ )
{
p = polygons->items[i];
left = right = 0;
// Classify vertices
for( j = 0; j < p.points; j++ )
{
dot = v3_dotprod(v3_subtract(p.pts[j], plane_p), plane_n);
if( dot > DOTPROD_TRESHOLD )
{
side[j] = -1; // Left
left++;
}
else if( dot < -DOTPROD_TRESHOLD )
{
side[j] = 1; // Right
right++;
}
else
side[j] = 0; // On
}
// Classify triangle
if( !right )
AddPolyToPolylist(left_polygons, p); // Left
else if( !left )
AddPolyToPolylist(right_polygons, p); // Right
else
split_triangle(left_polygons, right_polygons, plane_p, plane_n, p, side); // Straddling
}
// Recursively subdivide the left and right lists
left_tree = left_polygons->length ? BuildBSPTree(left_polygons) : NULL;
right_tree = right_polygons->length ? BuildBSPTree(right_polygons) : NULL;
// We can free the child polygon lists, as each child polygon
// will now have been stored in a BSP node
DestroyPolylist(left_polygons);
DestroyPolylist(right_polygons);
// Create tree node and return it
root = (BSPNode*) malloc(sizeof(BSPNode));
root->polygon = split_poly;
root->left_child = left_tree;
root->right_child = right_tree;
return root;
}
......@@ -3,14 +3,10 @@
* Date ............ 23.11.2009
* Created by ...... Paul Melis
*
* Student name ....
* Student email ...
* Collegekaart ....
* Date ............
* Comments ........
*
*
* (always fill in these fields before submitting!!)
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6169676 & 6054129
* Date ............ 01.12.2010
*/
#if defined(__GNUC__)
......@@ -137,15 +133,12 @@ InitializePolygonlists(void)
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#if 0
// Tree
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "tree.obj", texture_names, num_textures,
0.6, 5.0, 16.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#endif
#if 0
// Fish bowl
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "fishbowl.obj", texture_names, num_textures,
......@@ -157,23 +150,18 @@ InitializePolygonlists(void)
loadPolygonalObject(model_polygons, "goldfish.obj", texture_names, num_textures,
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#endif
#if 0
// Fence
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "hek.obj", texture_names, num_textures,
1.0, 0.0, 0.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#endif
#if 0
// A transparent cow (moooh!)
ClearPolylist(model_polygons);
loadPolygonalObject(model_polygons, "cow.obj", texture_names, num_textures,
10.0, -3.0, -15.0, 0.0);
AppendPolylist(scene_polygons, model_polygons);
#endif
// The skydome
polylistSkydome = CreatePolylist(1000);
......@@ -240,8 +228,7 @@ InitializePolygonlists(void)
printf("%d transparent polygons\n", scene_transparent_polygons->length);
// Build BSP tree
bsp_root = BuildBSPTreeIncorrect(scene_transparent_polygons);
bsp_root = BuildBSPTree(scene_transparent_polygons);
}
void
......@@ -418,9 +405,32 @@ DrawPolylist(polys * list)
void
DrawBSPTree(BSPNode *node, vec3 eye_position)
{
// Check if the tree is empty
if( !node )
return;
BSPNode *first, *last;
poly p = node->polygon;
// Check if the eye position is on the left or right side of the polygon
if( v3_dotprod(v3_subtract(eye_position, p.pts[0]), p.normal[0]) > 0 )
{
first = node->right_child;
last = node->left_child;
}
else
{
first = node->left_child;
last = node->right_child;
}
// Draw the tree on the other side of the polygon from the eye point, then
// the polygon itself and finally the tree on the same side of the polygon
DrawBSPTree(first, eye_position);
DrawPolygon(p);
DrawBSPTree(last, eye_position);
}
void
SetupCamera(void)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment