Commit ceb0fac1 authored by Taddeüs Kroes's avatar Taddeüs Kroes

Graphics assignment 11

Finished the complete assignment.
parent 85db55d9
......@@ -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)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment