Commit 7e4cf888 authored by Sander van Veen's avatar Sander van Veen

Added subject 'graphics' and 'operating systems'.

Graphics include the following assignments:
 - ass1
 - ass2
 - ass4
 - ass6

Operating systems include the following assignments:
 - ass1
 - ass2
parent 16673a76
CC=gcc
WARNING_FLAGS=-Wall -Wextra -Werror-implicit-function-declaration -Wshadow -Wstrict-prototypes -pedantic-errors
CFLAGS=-g -O2 -std=c99 $(WARNING_FLAGS)
LDFLAGS=-g -lGL -lglut
.c.o:
$(CC) -c $(CFLAGS) $<
all: trirast
trirast: main.o trirast.o
$(CC) $(LDFLAGS) -o trirast main.o trirast.o
clean:
rm -f *.o
rm -f trirast
trirast.o : types.h trirast.c
types.o : types.h
main.o : triangles.h trirast.h types.h main.c
triangles.o : triangles.h triangles.h
trirast.o : types.h trirast.h
/* Computer Graphics, Assignment, Triangle Rasterization
*
* Date ............ 28.07.2008
* Created by ...... Paul Melis
*/
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "types.h"
#include "trirast.h"
#include "triangles.h"
// Number of drawable pixels, i.e. x coordinates passed to PutPixel()
// should be in the range [0, framebuffer_width[. Analogous for y.
// (These values must both be a power of 2)
const int framebuffer_width = 128;
const int framebuffer_height = 64;
const int zoomed_pixel_size = 7;
int screen_width, screen_height;
int draw_optimized = 0;
int zoom = 1;
int scene = 1;
int draw_corners = 0;
int color_by_putpixel_count = 0;
byte *framebuffer;
void
InitOpenGL(void)
{
// Set the background color
glClearColor(0., 0., 0., 0.);
// Allocate a framebuffer, to be filled during triangle rasterization
framebuffer = (byte*)malloc(framebuffer_width*framebuffer_height*3);
// Setup texturing state (as we display the rasterization framebuffer
// using a textured quad)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
}
void PutPixel(int x, int y, byte r, byte g, byte b)
{
if (x < 0 || y < 0 || x >= framebuffer_width || y >= framebuffer_height)
{
printf("PutPixel(): x, y coordinates (%d, %d) outside of visible area!\n",
x, y);
return;
}
// The pixels in framebuffer[] are layed out sequentially,
// with the R, G and B values one after the other, e.g
// RGBRGBRGB...
framebuffer[3*(framebuffer_width*y+x)] = r;
framebuffer[3*(framebuffer_width*y+x)+1] = g;
framebuffer[3*(framebuffer_width*y+x)+2] = b;
}
void
DrawTriangles(void)
{
struct triangle tri;
for (unsigned int t = 0; t < sizeof(triangles)/sizeof(struct triangle); t++)
{
tri = triangles[t];
if (draw_optimized)
{
/* draw the triangle with the given color */
draw_triangle_optimized(
vertices[tri.i].x, vertices[tri.i].y,
vertices[tri.j].x, vertices[tri.j].y,
vertices[tri.k].x, vertices[tri.k].y,
colors[tri.c].r, colors[tri.c].g, colors[tri.c].b);
}
else
{
/* draw the triangle with the given color */
draw_triangle(
vertices[tri.i].x, vertices[tri.i].y,
vertices[tri.j].x, vertices[tri.j].y,
vertices[tri.k].x, vertices[tri.k].y,
colors[tri.c].r, colors[tri.c].g, colors[tri.c].b);
}
if (draw_corners)
{
PutPixel(vertices[tri.i].x, vertices[tri.i].y, 255, 255, 255);
PutPixel(vertices[tri.j].x, vertices[tri.j].y, 255, 255, 255);
PutPixel(vertices[tri.k].x, vertices[tri.k].y, 255, 255, 255);
}
}
}
void
DrawTrianglesOpenGL(void)
{
struct triangle tri;
glDisable(GL_TEXTURE_2D);
glBegin(GL_TRIANGLES);
for (unsigned int t = 0; t < sizeof(triangles)/sizeof(struct triangle); t++)
{
tri = triangles[t];
/* draw the triangle with the given color */
glColor3ub(colors[tri.c].r, colors[tri.c].g, colors[tri.c].b);
glVertex2f(vertices[tri.i].x, vertices[tri.i].y);
glVertex2f(vertices[tri.j].x, vertices[tri.j].y);
glVertex2f(vertices[tri.k].x, vertices[tri.k].y);
}
glEnd();
if (draw_corners)
{
glColor3ub(255, 255, 255);
glBegin(GL_POINTS);
for (unsigned int t = 0; t < sizeof(triangles)/sizeof(struct triangle); t++)
{
tri = triangles[t];
glVertex2f(vertices[tri.i].x, vertices[tri.i].y);
glVertex2f(vertices[tri.j].x, vertices[tri.j].y);
glVertex2f(vertices[tri.k].x, vertices[tri.k].y);
}
glEnd();
}
}
void
TestRasterizationSpeed(void)
{
const int N = 1000;
struct timeval t0, t1;
double diff;
//srand(123456);
gettimeofday(&t0, NULL);
if (draw_optimized)
{
for (int t = 0; t < N; t++)
{
draw_triangle_optimized(
rand()%framebuffer_width, rand()%framebuffer_height,
rand()%framebuffer_width, rand()%framebuffer_height,
rand()%framebuffer_width, rand()%framebuffer_height,
colors[t%6].r, colors[t%6].g, colors[t%6].b);
}
}
else
{
for (int t = 0; t < N; t++)
{
draw_triangle(
rand()%framebuffer_width, rand()%framebuffer_height,
rand()%framebuffer_width, rand()%framebuffer_height,
rand()%framebuffer_width, rand()%framebuffer_height,
colors[t%6].r, colors[t%6].g, colors[t%6].b);
}
}
gettimeofday(&t1, NULL);
/* calculate time used */
diff = t1.tv_sec - t0.tv_sec + (t1.tv_usec - t0.tv_usec)*1.0e-6;
printf("%d triangles in %.6f seconds, %.1f triangles/sec\n", N, diff, N/diff);
}
void
DrawPixels(void)
{
const int N = 1000000;
struct timeval t0, t1;
gettimeofday(&t0, NULL);
srand(123456);
for (int i = 0; i < N; i++)
{
PutPixel(rand()%framebuffer_width, rand()%framebuffer_height,
rand()%255, rand()%255, rand()%255);
}
gettimeofday(&t1, NULL);
/* calculate time used */
double diff = (t1.tv_sec + t1.tv_usec/1000000.0) - (t0.tv_sec + t0.tv_usec/1000000.0);
printf("%d pixels in %.6f seconds, %.1f pixels/sec\n", N, diff, N/diff);
}
void
DrawScene(void)
{
/* clear the draw buffer */
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
// clear the rasterization framebuffer
memset(framebuffer, 0, 3*framebuffer_width*framebuffer_height);
if (scene == 1)
DrawTriangles();
else if (scene == 2)
TestRasterizationSpeed();
else if (scene == 4)
DrawPixels();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (scene != 9)
{
if (zoom)
glOrtho(0, framebuffer_width, 0, framebuffer_height, -1, 1);
else
glOrtho(0, screen_width, 0, screen_height, -1, 1);
// Draw textured quad
glEnable(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
framebuffer_width, framebuffer_height,
0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer);
glColor3f(1, 1, 1);
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2i(0, 0);
glTexCoord2i(1, 0);
glVertex2i(framebuffer_width, 0);
glTexCoord2i(1, 1);
glVertex2i(framebuffer_width, framebuffer_height);
glTexCoord2i(0, 1);
glVertex2i(0, framebuffer_height);
glEnd();
}
else
{
if (zoom)
glOrtho(-0.5, framebuffer_width-0.5, -0.5, framebuffer_height-0.5, -1, 1);
else
glOrtho(-0.5, screen_width-0.5, -0.5, screen_height-0.5, -1, 1);
DrawTrianglesOpenGL();
glDisable(GL_TEXTURE_2D);
glColor3f(1, 1, 0);
glBegin(GL_POINTS);
glVertex2i(0, 0);
glVertex2i(framebuffer_width-1, framebuffer_height-1);
glEnd();
}
// finally, swap the draw buffers to make the triangles appear on screen
glutSwapBuffers();
}
void
KeyPressed(unsigned char key, int x, int y)
{
switch (key)
{
case '1':
case '2':
case '3':
case '4':
case '9':
{
scene = key - '0';
glutPostRedisplay();
break;
}
case 'o':
{
draw_optimized = 1 - draw_optimized;
printf("draw_optimized set to %d\n", draw_optimized);
glutPostRedisplay();
break;
}
case 'z':
{
zoom = 1 - zoom;
glutPostRedisplay();
break;
}
case 'd':
{
// debug
color_by_putpixel_count = 1 - color_by_putpixel_count;
printf("color_by_putpixel_count set to %d\n", color_by_putpixel_count);
glutPostRedisplay();
break;
}
case 'c':
{
// triangle corners
draw_corners = 1 - draw_corners;
glutPostRedisplay();
break;
}
case 'q':
exit(0);
}
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
screen_width = framebuffer_width * zoomed_pixel_size;
screen_height = framebuffer_height * zoomed_pixel_size;
glutInitWindowSize(screen_width, screen_height);
glutInitWindowPosition(20, 20);
glutCreateWindow("Triangle rasterization");
glutDisplayFunc(&DrawScene);
glutIdleFunc(&DrawScene);
//glutReshapeFunc(&ReSizeScene);
//glutSpecialFunc(&specialKeyPressed);
glutKeyboardFunc(&KeyPressed);
//glutMouseFunc(&mouseFunc);
//glutMotionFunc(&motionFunc);
InitOpenGL();
glutMainLoop();
return 1;
}
// Note: this file is only meant to be #included by main.c
#include "types.h"
struct color colors[] =
{
{ 255, 0, 0 },
{ 0, 255, 0 },
{ 0, 0, 255 },
{ 255, 255, 0 },
{ 0, 255, 255 },
{ 255, 0, 255 },
};
struct vertex vertices[] =
{
{ 0, 0 },
{ 10, 0 },
{ 0, 10 },
{ 10, 10 },
{ 30, 10 },
{ 10, 30 },
{ 40, 50 },
{ 23, 63 },
{ 60, 30 },
{ 110, 20 },
{ 80, 50 },
{ 100, 55 },
};
struct triangle triangles[] =
{
// i, j, k, c
{ 0, 1, 2, 0 },
{ 1, 2, 3, 1 },
{ 3, 4, 5, 2 },
{ 4, 5, 6, 0 },
{ 5, 7, 6, 1 },
{ 8, 9, 10, 2 },
{ 10, 9, 11, 1 },
};
/* Computer Graphics, Assignment, Triangle Rasterization
* Filename ........ trirast.c
* Description ..... Implements triangle rasterization
* Date ............ 11.08.2008
* Created by ...... Paul Melis
*
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129
* Date ............ 09-09-2010
* Comments ........
*/
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "types.h"
#define MIN(x, y, z) fminf(fminf(x, y), z)
#define MAX(x, y, z) fmaxf(fmaxf(x, y), z)
#define RAST(X, Y, a, b) ((y##a-y##b)*X+(x##b-x##a)*Y+x##a*y##b-x##b*y##a)
#define X_DIFF(a, b) (y##a-y##b)
#define Y_DIFF(a, b) (x##b-x##a - (x-x_min)*(y##a-y##b))
/*
* Rasterize a single triangle.
* The triangle is specified by its corner coordinates
* (x0,y0), (x1,y1) and (x2,y2).
* The triangle is drawn in color (r,g,b).
*/
void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2,
byte r, byte g, byte b)
{
GLint x, y;
GLfloat alpha, beta, gamma;
// Calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
// Precalculated vars
GLfloat rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1);
for( y = y_min; y <= y_max; y++ )
{
for( x = x_min; x <= x_max; x++ )
{
alpha = RAST(x, y, 1, 2) / rast_alpha;
beta = RAST(x, y, 2, 0) / rast_beta;
gamma = RAST(x, y, 0, 1) / rast_gamma;
if( alpha >= 0 && beta >= 0 && gamma >= 0
&& ( (alpha > 0 || rast_alpha_offset > 0)
&& (beta > 0 || rast_beta_offset > 0)
&& (gamma > 0 || rast_gamma_offset > 0) ) )
{
PutPixel(x, y, r, g, b);
}
}
}
}
void draw_triangle_optimized(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b)
{
// Calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y, drawing;
// Precalculated variables
GLfloat rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_div = 1 / rast_alpha,
rast_beta_div = 1 / rast_beta,
rast_gamma_div = 1 / rast_gamma,
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1);
// Initialize incremental multipliers at (0,0) of bounding box
GLfloat alpha = RAST(x_min, y_min, 1, 2),
beta = RAST(x_min, y_min, 2, 0),
gamma = RAST(x_min, y_min, 0, 1),
k, l, m;
// Loop through the triangle's bounding box
for( y = y_min; y <= y_max; y++ )
{
drawing = 0;
for( x = x_min; x <= x_max; x++ )
{
k = alpha * rast_alpha_div;
l = beta * rast_beta_div;
m = gamma * rast_gamma_div;
if( k >= 0 && l >= 0 && m >= 0
&& (k > 0 || rast_alpha_offset > 0)
&& (l > 0 || rast_beta_offset > 0)
&& (m > 0 || rast_gamma_offset > 0) )
{
PutPixel(x, y, r, g, b);
drawing = 1;
}
else if( drawing )
break;
// Increment the multipliers horizontally
alpha += X_DIFF(1, 2);
beta += X_DIFF(2, 0);
gamma += X_DIFF(0, 1);
}
// Increment the multipliers vertically
alpha += Y_DIFF(1, 2);
beta += Y_DIFF(2, 0);
gamma += Y_DIFF(0, 1);
}
}
#ifndef TRIRAST_H
#define TRIRAST_H
#include "types.h"
void draw_triangle(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b);
void draw_triangle_optimized(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b);
#endif
/* Computer Graphics, Assignment, Triangle Rasterization
* Filename ........ trirast.c
* Description ..... Implements triangle rasterization
* Date ............ 11.08.2008
* Created by ...... Paul Melis
*
* Student name .... Sander van Veen
* Student email ... sandervv@gmail.com
* Collegekaart .... 6167969
* Date ............
* Comments ........
*/
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "types.h"
#define MIN(x,y,z) fminf(fminf(x, y), z)
#define MAX(x,y,z) fmaxf(fmaxf(x, y), z)
#define RAST(X,Y,a,b) ((y##a-y##b)*X+(x##b-x##a)*Y+x##a*y##b-x##b*y##a)
/*
* Rasterize a single triangle.
* The triangle is specified by its corner coordinates
* (x0,y0), (x1,y1) and (x2,y2).
* The triangle is drawn in color (r,g,b).
*/
void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2,
byte r, byte g, byte b)
{
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y;
GLfloat alpha, beta, gamma,
rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1);
for( y = y_min; y <= y_max; y++ )
{
for( x = x_min; x <= x_max; x++ )
{
alpha = RAST(x, y, 1, 2) / rast_alpha;
beta = RAST(x, y, 2, 0) / rast_beta;
gamma = RAST(x, y, 0, 1) / rast_gamma;
//printf("alpha: %f\n", alpha);
//printf("beta: %f\n", beta);
//printf("gamma: %f\n", gamma);
if( alpha >= 0 && beta >= 0 && gamma >= 0
&& ( (alpha > 0 || rast_alpha_offset > 0)
&& (beta > 0 || rast_beta_offset > 0)
&& (gamma > 0 || rast_gamma_offset > 0) ) )
{
PutPixel(x, y, r, g, b);
}
}
}
}
void draw_triangle_optimized(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b)
{
// Calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y,
x_diff = x_max - x_min + 1;
// Precalculated vars
GLfloat rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_div = 1 / rast_alpha,
rast_beta_div = 1 / rast_beta,
rast_gamma_div = 1 / rast_gamma,
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1),
d_alpha_x = (y1-y2) * rast_alpha_div,
d_beta_x = (y2-y0) * rast_beta_div,
d_gamma_x = (y0-y1) * rast_gamma_div,
d_alpha_y = (x2-x1 - x_diff*(y1-y2)) * rast_alpha_div,
d_beta_y = (x0-x2 - x_diff*(y2-y0)) * rast_beta_div,
d_gamma_y = (x1-x0 - x_diff*(y0-y1)) * rast_gamma_div;
// Initialize incremental multipliers at (0,0)
GLfloat alpha = RAST(x_min, y_min, 1, 2) * rast_alpha_div,
beta = RAST(x_min, y_min, 2, 0) * rast_beta_div,
gamma = RAST(x_min, y_min, 0, 1) * rast_gamma_div;
// Loop through the triangle's bounding box
for( y = y_min; y <= y_max; y++ )
{
for( x = x_min; x <= x_max; x++ )
{
if( alpha >= 0 && beta >= 0 && gamma >= 0
&& ( (alpha > 0 || rast_alpha_offset > 0)
&& (beta > 0 || rast_beta_offset > 0)
&& (gamma > 0 || rast_gamma_offset > 0) ) )
{
PutPixel(x, y, r, g, b);
}
// Increment the multipliers horizontally
alpha += d_alpha_x;
beta += d_beta_x;
gamma += d_gamma_x;
}
// Increment the multipliers vertically
alpha += d_alpha_y;
beta += d_beta_y;
gamma += d_gamma_y;
}
}
#ifndef TYPES_H
#define TYPES_H
typedef unsigned char byte;
struct vertex
{
float x, y;
};
struct color
{
byte r, g, b;
};
struct triangle
{
// vertex indices
int i, j, k;
// color index
int c;
};
void PutPixel(int x, int y, byte r, byte g, byte b);
#endif
CC=gcc
WARNING_FLAGS=-Wall -Wextra -Werror-implicit-function-declaration -Wshadow -Wstrict-prototypes -pedantic-errors
CFLAGS=-g -O2 -std=c99 $(WARNING_FLAGS)
LDFLAGS=-g -lGL -lglut -lGLU
.c.o:
$(CC) -c $(CFLAGS) $<
all: main
main: main.o normals.o polys.o
$(CC) $(LDFLAGS) -o main $^
clean:
rm -f *.o
rm -f main
normals.o : normals.h polys.h normals.c
main.o : normals.h polys.h main.c
normals.o : polys.h normals.h
polys.o : polys.h
polys.o : polys.h polys.c
/* Computer Graphics, Assignment, Shading
*
* Filename ........ main.c
* Description ..... Creates OpenGL window and draws the scene.
* Date ............ 19.08.2008
*/
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626
#endif
#include "polys.h"
#include "normals.h"
polys *polylistFlat = NULL;
polys *polylistGouraud = NULL;
float camDistance = 25.0;
float camRotZ = 45.0, camAzimuth = 20.0;
float saved_camRotZ, saved_camAzimuth, saved_camDistance;
int mouse_mode = 0;
int mx, my;
#define color_roof {1.0,0.2,0.0,0.0}
#define color_wall {0.7,0.7,0.7,0.0}
#define color_garden {0.1,1.0,0.0,0.0}
#define base_NW {-1.5, -1.0, 1.0}
#define base_NE { 1.5, -1.0, 1.0}
#define base_SW {-1.5, -1.0,-1.0}
#define base_SE { 1.5, -1.0,-1.0}
#define base2_NW {-1.5, 1.5, 1.0}
#define base2_NE { 1.5, 1.5, 1.0}
#define base2_SW {-1.5, 1.5,-1.0}
#define base2_SE { 1.5, 1.5,-1.0}
#define base2_W {-1.5, 2.5, 0.0}
#define base2_E { 1.5, 2.5, 0.0}
#define roof_NW {-1.8, 1.3, 1.2}
#define roof_NE { 1.8, 1.3, 1.2}
#define roof_SW {-1.8, 1.3,-1.2}
#define roof_SE { 1.8, 1.3,-1.2}
#define roof_W {-1.8, 2.5, 0.0}
#define roof_E { 1.8, 2.5, 0.0}
#define garden_E {-4.5, 0.0, 0.0}
#define garden_NE {-3.5, 0.0, 3.5}
#define garden_NW { 3.5, 0.0, 3.5}
#define garden_W { 4.5, 0.0, 0.0}
#define garden_SW { 3.5, 0.0,-3.5}
#define garden_SE {-3.5, 0.0,-3.5}
#define n { 0.0, 0.0, 0.0}
#define nn { n, n, n, n, n, n}
#define center {0.0,0.0,0.0}
poly garden = {6, {garden_E,garden_NE,garden_NW,garden_W,garden_SW,garden_SE}, nn, n, center, color_garden};
poly wall_E = {5, {base_NE,base_SE,base2_SE,base2_E,base2_NE,n}, nn, n, center, color_wall};
poly wall_W = {5, {base_NW,base_SW,base2_SW,base2_W,base2_NW,n}, nn, n, center, color_wall};
poly wall_N = {4, {base_NW,base_NE,base2_NE,base2_NW,n,n}, nn, n, center, color_wall};
poly wall_S = {4, {base_SW,base_SE,base2_SE,base2_SW,n,n}, nn, n, center, color_wall};
poly roof_N = {4, {roof_NE,roof_NW,roof_W,roof_E,n,n}, nn, n, center, color_roof};
poly roof_S = {4, {roof_SE,roof_SW,roof_W,roof_E,n,n}, nn, n, center, color_roof};
GLfloat lightPosition[] = {2.0f, 10.0f, 2.0f, 0.0f};
GLfloat lightAmbient[] = {0.3f, 0.3f, 0.3f, 1.0f};
GLfloat lightDiffuse[] = {2.0f, 2.0f, 2.0f, 1.0f};
GLfloat lightSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f};
void
createSphere(polys* list, double sx, double sy, double sz,
double ox, double oy, double oz, double r, double g, double b)
{
int latitude,longitude;
double dToR = M_PI/180.0;
GLfloat x, y, z;
poly p;
p.points = 4;
p.color[0] = r;
p.color[1] = g;
p.color[2] = b;
p.color[3] = 0;
p.inside.x = ox;
p.inside.y = oy;
p.inside.z = oz;
for (latitude = -90; latitude < 90; latitude += 10)
{
for (longitude = 0; longitude <= 360; longitude += 10)
{
x = ox + sin(longitude * dToR) * cos(latitude * dToR)*sx;
y = oy + sin(latitude * dToR)*sy;
z = oz + cos(longitude * dToR) * cos(latitude * dToR)*sz;
p.pts[0] = p.pts[3];
p.pts[1] = p.pts[2];
p.pts[2].x = x;
p.pts[2].y = y;
p.pts[2].z = z;
x = ox + sin(longitude * dToR) * cos((latitude+10) * dToR)*sx;
y = oy + sin((latitude+10) * dToR)*sy;
z = oz + cos(longitude * dToR) * cos((latitude+10) * dToR)*sz;
p.pts[3].x = x;
p.pts[3].y = y;
p.pts[3].z = z;
if (longitude != 0)
AddPolyToPolylist(list,p);
}
}
}
void
InitializePolygonlist(void)
{
polylistFlat = CreatePolylist(6);
AddPolyToPolylist(polylistFlat, wall_E);
AddPolyToPolylist(polylistFlat, wall_W);
AddPolyToPolylist(polylistFlat, wall_S);
AddPolyToPolylist(polylistFlat, wall_N);
AddPolyToPolylist(polylistFlat, roof_S);
AddPolyToPolylist(polylistFlat, roof_N);
polylistGouraud = CreatePolylist(10);
createSphere(polylistGouraud,6,3,6,0,-3,0,0,1,0);
printf("%d polygons to flat shade\n", polylistFlat->length);
printf("%d polygons to gouraud shade\n", polylistGouraud->length);
calcNormalsFlat(polylistFlat);
calcNormalsGouraud(polylistGouraud);
}
void
InitGL(void)
{
GLfloat light_ambient[] = {0.4,0.4,0.4,0.0};
GLfloat mat_shininess[] = { 50.0 };
glClearColor(0.7,0.7,1,1);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
glEnable(GL_COLOR_MATERIAL);
}
void
ReSizeGLScene(int Width, int Height)
{
if (Height == 0)
Height=1;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
}
void
drawPolylist(polys* list)
{
int i,j;
poly p;
for (i = 0; i < list->length; i++)
{
p = list->items[i];
glColor3f(p.color[0], p.color[1], p.color[2]);
glBegin(GL_POLYGON);
for (j = 0; j < p.points; j++)
{
glNormal3f(p.normal[j].x, p.normal[j].y, p.normal[j].z);
glVertex3f(p.pts[j].x, p.pts[j].y, p.pts[j].z);
}
glEnd();
}
}
void SetupCamera(void)
{
float cx, cy, cz;
float t;
float beta, gamma;
glLoadIdentity();
// degrees -> radians
beta = camAzimuth / 180.0 * M_PI;
gamma = camRotZ / 180.0 * M_PI;
cx = camDistance;
cy = cz = 0.0;
// Rotate around Z
t = cx;
cx = cx * cos(beta) + cy * sin(beta);
cy = t * sin(beta) + cy * cos(beta);
// Rotate around Y
t = cx;
cx = cx * cos(gamma) - cz * sin(gamma);
cz = t * sin(gamma) + cz * cos(gamma);
gluLookAt (cx, cy, cz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void
DrawGLScene(void)
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_no_specular[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_position[] = { 5.0, 5.0, 5.0, 0.0 };
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
SetupCamera();
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_no_specular);
drawPolylist(polylistFlat);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
drawPolylist(polylistGouraud);
glutSwapBuffers();
}
void
keyPressed(unsigned char key, int x, int y)
{
switch (key)
{
case 'q':
exit(-1);
break;
}
}
void
specialKeyPressed(int key, int x, int y)
{
}
static void
mouseFunc(int button, int state, int x, int y)
{
// guard against both left and right buttons being pressed at the same time,
// by only responding when a mouse button is pressed while another one
// hasn't been pressed yet
if (state == GLUT_DOWN && mouse_mode == 0)
{
if (button == GLUT_LEFT_BUTTON)
{
mouse_mode = GLUT_LEFT_BUTTON;
saved_camRotZ = camRotZ;
saved_camAzimuth = camAzimuth;
mx = x;
my = y;
}
else if (button == GLUT_RIGHT_BUTTON)
{
mouse_mode = GLUT_RIGHT_BUTTON;
saved_camDistance = camDistance;
my = y;
}
}
else if (state == GLUT_UP && button == mouse_mode)
{
// pressed button released
mouse_mode = 0;
}
}
static void
motionFunc(int x, int y)
{
int dx, dy;
if (mouse_mode == GLUT_LEFT_BUTTON)
{
dx = mx - x;
dy = my - y;
camRotZ = saved_camRotZ - dx * 0.25;
camAzimuth = saved_camAzimuth - dy * 0.25;
if (camAzimuth > 89.99)
camAzimuth = 89.99;
else if (camAzimuth < -89.99)
camAzimuth = -89.99;
}
else if (mouse_mode == GLUT_RIGHT_BUTTON)
{
dy = my - y;
camDistance = saved_camDistance - dy * 0.5;
if (camDistance < 0.5)
camDistance = 0.5;
else if (camDistance > 100.0)
camDistance = 100.0;
}
}
int
main(int argc, char **argv)
{
InitializePolygonlist();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(0, 0);
glutCreateWindow("Shading");
glutDisplayFunc(&DrawGLScene);
glutIdleFunc(&DrawGLScene);
glutReshapeFunc(&ReSizeGLScene);
glutSpecialFunc(&specialKeyPressed);
glutKeyboardFunc(&keyPressed);
glutMotionFunc(&motionFunc);
glutMouseFunc(&mouseFunc);
InitGL();
glutMainLoop();
}
/* Computer Graphics, Assignment, Intersections
* Filename ........ normals.c
* Description ..... Calculates Plane/Vertex normals
* Date ............ 19.08.2008
*
* Student name ....
* Student email ...
* Collegekaart ....
* Date ............
* Comments ........
*
* (always fill in these fields before submitting!!)
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "normals.h"
// Calculate flat shading normal for the given polygons. Note that
// you have to set normals for all *vertices* of the polygon, so you
// have to set the normal[] array in the poly struct.
void calcNormalsFlat(polys* list)
{
poly item;
int length = (*list).length;
for( int i = 0; i < length; i++ )
{
item = (*list).items[i];
for( int p = 0; p < item.points; p++ )
{
}
// int points;
// point pts[MAX_VERTICES];
// point normal[MAX_VERTICES]; // Vertex normals
// point pnormal; // Overall polygon normal
}
}
// Calculate normals for Gouraud shading. Again, the data to fill in
// is each poly's normal[] array. You can use poly's pnormal field
// to store temporary values if you like.
void calcNormalsGouraud(polys* list)
{
// To have some form of shading on the sphere, as shown in
// the assignment, we initally do flat shading here
calcNormalsFlat(list);
}
/* Computer Graphics, Assignment, Intersections
* Filename ........ normals.c
* Description ..... Calculates Plane/Vertex normals
* Date ............ 19.08.2008
*/
#ifndef NORMALS_H
#define NORMALS_H
#include "polys.h"
void calcNormalsFlat(polys* list);
void calcNormalsGouraud(polys* list);
#endif
/* Computer Graphics, Assignment, Shading
*
* Filename ........ polys.c
* Description ..... Functions to manage lists of polygons
* Date ............ 19.08.2008
* Created by ...... Jurgen Sturm
* Cleaned up by ... Paul Melis
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "polys.h"
/* Create a list of polys, and immediately reserve space for `n' polys */
polys*
CreatePolylist(int n)
{
polys *l;
l = (polys*) malloc(sizeof(polys));
if (l == NULL)
{
printf("CreatePolylist(): could not allocate memory (l): %s\n",
strerror(errno));
exit(-1);
}
if (n > 0)
{
l->items = (poly*) malloc(n * sizeof(poly));
if (l->items == NULL)
{
printf("CreatePolylist(): could not allocate memory (data): %s\n",
strerror(errno));
exit(-1);
}
l->capacity = n;
l->length = 0;
}
else
{
l->capacity = 0;
l->length = 0;
l->items = NULL;
}
return l;
}
void
DestroyPolylist(polys *list)
{
if (list == NULL)
return;
list->capacity = 0;
list->length = 0;
free(list->items);
list = NULL;
}
/* exit() if no memory available, returns 0 if poly* is NULL, 1 otherwise */
int
GrowPolylist(polys *list, int delta)
{
poly *newdata;
if (list == NULL)
return 0;
newdata = (poly*) realloc(list->items, (list->capacity + delta)*sizeof(poly));
if (newdata == NULL)
{
printf("GrowPolylist(): could not allocate memory: %s\n",
strerror(errno));
exit(-1);
}
list->capacity += delta;
list->items = newdata;
return 1;
}
/* exit() if no memory available, returns 0 if poly* is NULL, 1 otherwise.
* Decreasing the data segment can, and will, destroy polygons if the new
* segment cannot contain all current data.
* The data segment cannot be reduced to a size less than 0 (size is clamped
* to zero).
* The new data segment will be a NULL pointer if the new size is 0. */
int
ShrinkPolylist(polys *list, int delta)
{
int n;
poly *newdata;
if (list == NULL)
return 0;
n = list->capacity - delta;
if (n < 1)
{
free(list->items);
list->items = NULL;
list->capacity = 0;
list->length = 0;
return 1;
}
newdata = (poly*)realloc(list->items, (list->capacity + delta)*sizeof(poly));
if (newdata == NULL)
{
printf("ShrinkPolylist(): could not allocate memory: %s\n",
strerror(errno));
exit(-1);
}
list->capacity -= delta;
list->items = newdata;
/* update list->length if neccesary */
if (list->length > list->capacity)
list->length = list->capacity;
return 1;
}
/* poly's are structs of (point) arrays, so they are passed by value instead
* of by reference (as do arrays) */
void
AddPolyToPolylist(polys *list, poly p)
{
int i;
if (list == NULL)
return;
for (i = 0; i < p.points; i++)
{
p.normal[i].x = 0;
p.normal[i].y = 0;
p.normal[i].z = 0;
}
/* polylist is full, so first add some space */
if (list->length == list->capacity)
{
/* grow arbitrary amount */
if (GrowPolylist(list, 8) != 1)
{
printf("AddPolyToList(): failed");
exit(-1);
}
}
list->items[list->length] = p;
list->length++;
}
polys*
CopyPolylist(polys* list)
{
int i;
polys *copy;
if (list == NULL)
return NULL;
copy = CreatePolylist(list->capacity);
/* not the most efficient, but certainly easiest & least error-prone */
for (i = 0; i < list->length; i++)
AddPolyToPolylist(copy, list->items[i]);
return copy;
}
/* Computer Graphics, Assignment, Shading
*
* Filename ........ polys.h
* Description ..... Functions to manage lists of polygons (header file)
* Date ............ 01.09.2006
* Created by ...... Jurgen Sturm
*
*/
#ifndef POLYS_H
#define POLYS_H
#include <GL/gl.h>
#define MAX_VERTICES 6
typedef struct point
{
GLdouble x;
GLdouble y;
GLdouble z;
}
point;
typedef struct poly
{
int points;
point pts[MAX_VERTICES];
point normal[MAX_VERTICES]; // Vertex normals
point pnormal; // Overall polygon normal
point inside;
GLfloat color[4];
}
poly;
typedef struct polys
{
/* size of the poly array "items" below */
int capacity;
/* number of poly's stored, also index of the first free position
* in the "items" array. If this number is equal to "capacity" above,
* then this list is full */
int length;
/* poly pointer to array of size "capacity" */
poly *items;
}
polys;
/* Create a list of polys, and immediately reserve space for `n' polys */
polys* CreatePolylist(int numpolys);
/* Destroy a list of polygons */
void DestroyPolylist(polys *list);
/* exit() if no memory available, returns 0 if poly* is NULL, 1 otherwise */
int IncreasePolylist(polys *list, int delta);
/* exit() if no memory available, returns 0 if poly* is NULL, 1 otherwise.
* Decreasing the data segment can, and will, destroy polygons if the new
* segment cannot contain all current data.
* The data segment cannot be reduced to a size less than 0 (size is clamped
* to zero).
* The new data segment will be a NULL pointer if the new size is 0. */
int DecreasePolylist(polys *list, int delta);
/* poly's are structs of (point) arrays, so they are passed by value instead
* of by reference (as do arrays)
* Silently fails if `list' is a NULL pointer.
* exit()'s if we need more memory but cannot allocate it. */
void AddPolyToPolylist(polys *list, poly p);
/* Copies the list of polys `list', calls AddPolytoPolylist() for each poly
* in the given list.
* exit()'s if it cannot allocate memory. */
polys* CopyPolylist(polys *list);
#endif
CC=gcc
CXX=g++
BULLET=./bullet32
#BULLET=./bullet64
WARNING_FLAGS=-Wall -Wextra -Werror-implicit-function-declaration -Wshadow -Wstrict-prototypes -pedantic
CFLAGS=-g -O2 -std=c99 $(WARNING_FLAGS) -fno-strict-aliasing -m32
CXXFLAGS=-g -O2 -W -Wall -I${BULLET}/include -m32
LDFLAGS=-g -lGL -lGLU -lglut -L${BULLET}/lib -m32
LIBS=-lBulletDynamics -lBulletCollision -lLinearMath
.c.o:
$(CC) -c $(CFLAGS) $<
.cpp.o:
$(CXX) -c $(CXXFLAGS) $<
all: singlecurve multicurve
singlecurve: singlecurve.o bezier.o
$(CC) $(LDFLAGS) -o singlecurve singlecurve.o bezier.o
multicurve: multicurve.o bezier.o v3math.o plymodel.o rply.o physics.o
$(CXX) $(LDFLAGS) -o multicurve multicurve.o bezier.o v3math.o plymodel.o rply.o physics.o $(LIBS)
clean:
rm -f *.o
rm -f singlecurve
rm -f multicurve
bezier.o : bezier.h bezier.c
singlecurve.o : bezier.h singlecurve.c
multicurve.o : bezier.h multicurve.c plymodel.h physics.h
v3math.o : v3math.h v3math.c
plymodel.o : plymodel.c plymodel.h
rply.o : rply.c rply.h
physics.o : physics.h
/* Computer Graphics, Assignment, Bezier curves
* Filename ........ bezier.c
* Description ..... Bezier curves
* Date ............ 22.07.2009
* Created by ...... Paul Melis
*
* Student name .... Sander van Veen
* Student email ... <sandervv@gmail.com>
* Collegekaart .... 6167969
* Date ............
* Comments ........
*
*
* (always fill in these fields before submitting!!)
*/
#include <math.h>
#include "bezier.h"
#include <stdio.h>
int F(int x) { return !x ? 1 : x * F(x-1); }
/* Given a Bezier curve defined by the 'num_points' control points
* in 'p' compute the position of the point on the curve for parameter
* value 'u'.
*
* Return the x and y values of the point by setting *x and *y,
* respectively.
*/
void
evaluate_bezier_curve(float *x, float *y, control_point p[], int n, float u)
{
*x = 0.0;
*y = 0.0;
float u_diff = 1 - u,
scalar;
for( int i = 0; i < n; i++ )
{
//printf("p[%d]: (%f, %f), ", i, p[i].x, p[i].y);
scalar = ((float) F(n-1) / (F(i) * F(n-i-1)) ) * powf(u, i) * powf(u_diff, n-i-1);
//printf("scalar: %f\n", scalar);
*x += scalar * p[i].x;
*y += scalar * p[i].y;
//printf("x: %f, y: %f\n", *x, *y);
}
}
/* Draw a Bezier curve defined by the control points in p[], which
* will contain 'n' points.
*
* Draw the line segments you compute directly on the screen
* as a single GL_LINE_STRIP. This is as simple as using
*
* glBegin(GL_LINE_STRIP);
* glVertex2f(..., ...);
* ...
* glEnd();
*
* DO NOT SET ANY COLOR!
*
* The 'num_segments' parameter determines the "discretization" of the Bezier
* curve and is the number of straight line segments that should be used
* to approximate the curve.
*
* Call evaluate_bezier_curve() to compute the necessary points on
* the curve.
*/
void
draw_bezier_curve(int num_segments, control_point p[], int n)
{
float x = 0.0,
y = 0.0;
glBegin(GL_LINE_STRIP);
for( float u = 0.0; u <= 1; u += 1.0/num_segments )
{
evaluate_bezier_curve(&x, &y, p, n, u);
//printf("segments: %d, points: %d\n", num_segments, n);
glVertex2f(x, y);
}
glEnd();
}
/* Find the intersection of a cubic Bezier curve with the line X=x.
Return 1 if an intersection was found and place the corresponding y
value in *y.
Return 0 if no intersection exists.
*/
int
intersect_cubic_bezier_curve(float *y, control_point p[], float x)
{
// Newton-Raphson's Method
// x_1 = x_0 - f(x_0) / f'(x_0)
// x_{n+1} = x_n - f(x_b) / f'(x_n)
return 0;
}
#ifndef BEZIER_H
#define BEZIER_H
#include <GL/gl.h>
// A single control point of a Bezier curve
typedef struct control_point
{
float x;
float y;
}
control_point;
void evaluate_bezier_curve(float *x, float *y, control_point p[], int num_points, float u);
void draw_bezier_curve(int num_segments, control_point p[], int num_points);
int intersect_cubic_bezier_curve(float *y, control_point p[], float x);
#endif
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
Work in progress, functionality will be added on demand.
If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h"
*/
#ifndef BULLET_C_API_H
#define BULLET_C_API_H
#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
#ifdef BT_USE_DOUBLE_PRECISION
typedef double plReal;
#else
typedef float plReal;
#endif
typedef plReal plVector3[3];
typedef plReal plQuaternion[4];
#ifdef __cplusplus
extern "C" {
#endif
/** Particular physics SDK (C-API) */
PL_DECLARE_HANDLE(plPhysicsSdkHandle);
/** Dynamics world, belonging to some physics SDK (C-API)*/
PL_DECLARE_HANDLE(plDynamicsWorldHandle);
/** Rigid Body that can be part of a Dynamics World (C-API)*/
PL_DECLARE_HANDLE(plRigidBodyHandle);
/** Collision Shape/Geometry, property of a Rigid Body (C-API)*/
PL_DECLARE_HANDLE(plCollisionShapeHandle);
/** Constraint for Rigid Bodies (C-API)*/
PL_DECLARE_HANDLE(plConstraintHandle);
/** Triangle Mesh interface (C-API)*/
PL_DECLARE_HANDLE(plMeshInterfaceHandle);
/** Broadphase Scene/Proxy Handles (C-API)*/
PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
PL_DECLARE_HANDLE(plCollisionWorldHandle);
/**
Create and Delete a Physics SDK
*/
extern plPhysicsSdkHandle plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.
extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk);
/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
extern plCollisionBroadphaseHandle plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback);
extern void plDestroyBroadphase(plCollisionBroadphaseHandle bp);
extern plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle);
extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
/* todo: add pair cache support with queries like add/remove/find pair */
extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk);
/* todo: add/remove objects */
/* Dynamics World */
extern plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk);
extern void plDeleteDynamicsWorld(plDynamicsWorldHandle world);
extern void plStepSimulation(plDynamicsWorldHandle, plReal timeStep);
extern void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
extern void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
/* Rigid Body */
extern plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape );
extern void plDeleteRigidBody(plRigidBodyHandle body);
/* Collision Shape definition */
extern plCollisionShapeHandle plNewSphereShape(plReal radius);
extern plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z);
extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCompoundShape();
extern void plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
extern void plDeleteShape(plCollisionShapeHandle shape);
/* Convex Meshes */
extern plCollisionShapeHandle plNewConvexHullShape();
extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
/* Concave static triangle meshes */
extern plMeshInterfaceHandle plNewMeshInterface();
extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
extern void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling);
/* SOLID has Response Callback/Table/Management */
/* PhysX has Triggers, User Callbacks and filtering */
/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */
/* typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle rbHandle, plVector3 pos); */
/* typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle rbHandle, plQuaternion orientation); */
/* get world transform */
extern void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
extern void plGetPosition(plRigidBodyHandle object,plVector3 position);
extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation);
/* set world transform (position/orientation) */
extern void plSetPosition(plRigidBodyHandle object, const plVector3 position);
extern void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);
extern void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);
typedef struct plRayCastResult {
plRigidBodyHandle m_body;
plCollisionShapeHandle m_shape;
plVector3 m_positionWorld;
plVector3 m_normalWorld;
} plRayCastResult;
extern int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res);
/* Sweep API */
/* extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */
/* Continuous Collision Detection API */
// needed for source/blender/blenkernel/intern/collision.c
double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
#ifdef __cplusplus
}
#endif
#endif //BULLET_C_API_H
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BROADPHASE_INTERFACE_H
#define BROADPHASE_INTERFACE_H
struct btDispatcherInfo;
class btDispatcher;
#include "btBroadphaseProxy.h"
class btOverlappingPairCache;
struct btBroadphaseRayCallback
{
///added some cached data to accelerate ray-AABB tests
btVector3 m_rayDirectionInverse;
unsigned int m_signs[3];
btScalar m_lambda_max;
virtual ~btBroadphaseRayCallback() {}
virtual bool process(const btBroadphaseProxy* proxy) = 0;
};
#include "LinearMath/btVector3.h"
///The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
///Some implementations for this broadphase interface include btAxisSweep3, bt32BitAxisSweep3 and btDbvtBroadphase.
///The actual overlapping pair management, storage, adding and removing of pairs is dealt by the btOverlappingPairCache class.
class btBroadphaseInterface
{
public:
virtual ~btBroadphaseInterface() {}
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) =0;
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0;
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0;
virtual btOverlappingPairCache* getOverlappingPairCache()=0;
virtual const btOverlappingPairCache* getOverlappingPairCache() const =0;
///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
///will add some transform later
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
///reset broadphase internal structures, to ensure determinism/reproducability
virtual void resetPool(btDispatcher* dispatcher) {};
virtual void printStats() = 0;
};
#endif //BROADPHASE_INTERFACE_H
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BROADPHASE_PROXY_H
#define BROADPHASE_PROXY_H
#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedAllocator.h"
/// btDispatcher uses these types
/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
/// to facilitate type checking
/// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code
enum BroadphaseNativeTypes
{
// polyhedral convex shapes
BOX_SHAPE_PROXYTYPE,
TRIANGLE_SHAPE_PROXYTYPE,
TETRAHEDRAL_SHAPE_PROXYTYPE,
CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
CONVEX_HULL_SHAPE_PROXYTYPE,
CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
CUSTOM_POLYHEDRAL_SHAPE_TYPE,
//implicit convex shapes
IMPLICIT_CONVEX_SHAPES_START_HERE,
SPHERE_SHAPE_PROXYTYPE,
MULTI_SPHERE_SHAPE_PROXYTYPE,
CAPSULE_SHAPE_PROXYTYPE,
CONE_SHAPE_PROXYTYPE,
CONVEX_SHAPE_PROXYTYPE,
CYLINDER_SHAPE_PROXYTYPE,
UNIFORM_SCALING_SHAPE_PROXYTYPE,
MINKOWSKI_SUM_SHAPE_PROXYTYPE,
MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
CUSTOM_CONVEX_SHAPE_TYPE,
//concave shapes
CONCAVE_SHAPES_START_HERE,
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
TRIANGLE_MESH_SHAPE_PROXYTYPE,
SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
///used for demo integration FAST/Swift collision library and Bullet
FAST_CONCAVE_MESH_PROXYTYPE,
//terrain
TERRAIN_SHAPE_PROXYTYPE,
///Used for GIMPACT Trimesh integration
GIMPACT_SHAPE_PROXYTYPE,
///Multimaterial mesh
MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,
EMPTY_SHAPE_PROXYTYPE,
STATIC_PLANE_PROXYTYPE,
CUSTOM_CONCAVE_SHAPE_TYPE,
CONCAVE_SHAPES_END_HERE,
COMPOUND_SHAPE_PROXYTYPE,
SOFTBODY_SHAPE_PROXYTYPE,
HFFLUID_SHAPE_PROXYTYPE,
HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
INVALID_SHAPE_PROXYTYPE,
MAX_BROADPHASE_COLLISION_TYPES
};
///The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
///It stores collision shape type information, collision filter information and a client object, typically a btCollisionObject or btRigidBody.
ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy
{
BT_DECLARE_ALIGNED_ALLOCATOR();
///optional filtering to cull potential collisions
enum CollisionFilterGroups
{
DefaultFilter = 1,
StaticFilter = 2,
KinematicFilter = 4,
DebrisFilter = 8,
SensorTrigger = 16,
CharacterFilter = 32,
AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
};
//Usually the client btCollisionObject or Rigidbody class
void* m_clientObject;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
void* m_multiSapParentProxy;
int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
btVector3 m_aabbMin;
btVector3 m_aabbMax;
SIMD_FORCE_INLINE int getUid() const
{
return m_uniqueId;
}
//used for memory pools
btBroadphaseProxy() :m_clientObject(0),m_multiSapParentProxy(0)
{
}
btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
:m_clientObject(userPtr),
m_collisionFilterGroup(collisionFilterGroup),
m_collisionFilterMask(collisionFilterMask),
m_aabbMin(aabbMin),
m_aabbMax(aabbMax)
{
m_multiSapParentProxy = multiSapParentProxy;
}
static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType)
{
return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE);
}
static SIMD_FORCE_INLINE bool isConvex(int proxyType)
{
return (proxyType < CONCAVE_SHAPES_START_HERE);
}
static SIMD_FORCE_INLINE bool isConcave(int proxyType)
{
return ((proxyType > CONCAVE_SHAPES_START_HERE) &&
(proxyType < CONCAVE_SHAPES_END_HERE));
}
static SIMD_FORCE_INLINE bool isCompound(int proxyType)
{
return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
}
static SIMD_FORCE_INLINE bool isInfinite(int proxyType)
{
return (proxyType == STATIC_PLANE_PROXYTYPE);
}
}
;
class btCollisionAlgorithm;
struct btBroadphaseProxy;
///The btBroadphasePair class contains a pair of aabb-overlapping objects.
///A btDispatcher can search a btCollisionAlgorithm that performs exact/narrowphase collision detection on the actual collision shapes.
ATTRIBUTE_ALIGNED16(struct) btBroadphasePair
{
btBroadphasePair ()
:
m_pProxy0(0),
m_pProxy1(0),
m_algorithm(0),
m_internalInfo1(0)
{
}
BT_DECLARE_ALIGNED_ALLOCATOR();
btBroadphasePair(const btBroadphasePair& other)
: m_pProxy0(other.m_pProxy0),
m_pProxy1(other.m_pProxy1),
m_algorithm(other.m_algorithm),
m_internalInfo1(other.m_internalInfo1)
{
}
btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1)
{
//keep them sorted, so the std::set operations work
if (proxy0.m_uniqueId < proxy1.m_uniqueId)
{
m_pProxy0 = &proxy0;
m_pProxy1 = &proxy1;
}
else
{
m_pProxy0 = &proxy1;
m_pProxy1 = &proxy0;
}
m_algorithm = 0;
m_internalInfo1 = 0;
}
btBroadphaseProxy* m_pProxy0;
btBroadphaseProxy* m_pProxy1;
mutable btCollisionAlgorithm* m_algorithm;
union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version.
};
/*
//comparison for set operation, see Solid DT_Encounter
SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b)
{
return a.m_pProxy0 < b.m_pProxy0 ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1);
}
*/
class btBroadphasePairSortPredicate
{
public:
bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
{
const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1;
const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1;
const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1;
const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1;
return uidA0 > uidB0 ||
(a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm);
}
};
SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b)
{
return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1);
}
#endif //BROADPHASE_PROXY_H
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_ALGORITHM_H
#define COLLISION_ALGORITHM_H
#include "LinearMath/btScalar.h"
#include "LinearMath/btAlignedObjectArray.h"
struct btBroadphaseProxy;
class btDispatcher;
class btManifoldResult;
class btCollisionObject;
struct btDispatcherInfo;
class btPersistentManifold;
typedef btAlignedObjectArray<btPersistentManifold*> btManifoldArray;
struct btCollisionAlgorithmConstructionInfo
{
btCollisionAlgorithmConstructionInfo()
:m_dispatcher1(0),
m_manifold(0)
{
}
btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp)
:m_dispatcher1(dispatcher)
{
(void)temp;
}
btDispatcher* m_dispatcher1;
btPersistentManifold* m_manifold;
int getDispatcherId();
};
///btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatcher.
///It is persistent over frames
class btCollisionAlgorithm
{
protected:
btDispatcher* m_dispatcher;
protected:
int getDispatcherId();
public:
btCollisionAlgorithm() {};
btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci);
virtual ~btCollisionAlgorithm() {};
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
virtual void getAllContactManifolds(btManifoldArray& manifoldArray) = 0;
};
#endif //COLLISION_ALGORITHM_H
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
///btDbvtBroadphase implementation by Nathanael Presson
#ifndef BT_DBVT_BROADPHASE_H
#define BT_DBVT_BROADPHASE_H
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
//
// Compile time config
//
#define DBVT_BP_PROFILE 0
//#define DBVT_BP_SORTPAIRS 1
#define DBVT_BP_PREVENTFALSEUPDATE 0
#define DBVT_BP_ACCURATESLEEPING 0
#define DBVT_BP_ENABLE_BENCHMARK 0
#define DBVT_BP_MARGIN (btScalar)0.05
#if DBVT_BP_PROFILE
#define DBVT_BP_PROFILING_RATE 256
#include "LinearMath/btQuickprof.h"
#endif
//
// btDbvtProxy
//
struct btDbvtProxy : btBroadphaseProxy
{
/* Fields */
//btDbvtAabbMm aabb;
btDbvtNode* leaf;
btDbvtProxy* links[2];
int stage;
/* ctor */
btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask)
{
links[0]=links[1]=0;
}
};
typedef btAlignedObjectArray<btDbvtProxy*> btDbvtProxyArray;
///The btDbvtBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees (see btDbvt).
///One tree is used for static/non-moving objects, and another tree is used for dynamic objects. Objects can move from one tree to the other.
///This is a very fast broadphase, especially for very dynamic worlds where many objects are moving. Its insert/add and remove of objects is generally faster than the sweep and prune broadphases btAxisSweep3 and bt32BitAxisSweep3.
struct btDbvtBroadphase : btBroadphaseInterface
{
/* Config */
enum {
DYNAMIC_SET = 0, /* Dynamic set index */
FIXED_SET = 1, /* Fixed set index */
STAGECOUNT = 2 /* Number of stages */
};
/* Fields */
btDbvt m_sets[2]; // Dbvt sets
btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list
btOverlappingPairCache* m_paircache; // Pair cache
btScalar m_prediction; // Velocity prediction
int m_stageCurrent; // Current stage
int m_fupdates; // % of fixed updates per frame
int m_dupdates; // % of dynamic updates per frame
int m_cupdates; // % of cleanup updates per frame
int m_newpairs; // Number of pairs created
int m_fixedleft; // Fixed optimization left
unsigned m_updates_call; // Number of updates call
unsigned m_updates_done; // Number of updates done
btScalar m_updates_ratio; // m_updates_done/m_updates_call
int m_pid; // Parse id
int m_cid; // Cleanup index
int m_gid; // Gen id
bool m_releasepaircache; // Release pair cache on delete
bool m_deferedcollide; // Defere dynamic/static collision to collide call
bool m_needcleanup; // Need to run cleanup?
#if DBVT_BP_PROFILE
btClock m_clock;
struct {
unsigned long m_total;
unsigned long m_ddcollide;
unsigned long m_fdcollide;
unsigned long m_cleanup;
unsigned long m_jobcount;
} m_profiling;
#endif
/* Methods */
btDbvtBroadphase(btOverlappingPairCache* paircache=0);
~btDbvtBroadphase();
void collide(btDispatcher* dispatcher);
void optimize();
/* btBroadphaseInterface Implementation */
btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
void calculateOverlappingPairs(btDispatcher* dispatcher);
btOverlappingPairCache* getOverlappingPairCache();
const btOverlappingPairCache* getOverlappingPairCache() const;
void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
void printStats();
static void benchmark(btBroadphaseInterface*);
void performDeferredRemoval(btDispatcher* dispatcher);
///reset broadphase internal structures, to ensure determinism/reproducability
virtual void resetPool(btDispatcher* dispatcher);
};
#endif
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _DISPATCHER_H
#define _DISPATCHER_H
#include "LinearMath/btScalar.h"
class btCollisionAlgorithm;
struct btBroadphaseProxy;
class btRigidBody;
class btCollisionObject;
class btOverlappingPairCache;
class btPersistentManifold;
class btStackAlloc;
struct btDispatcherInfo
{
enum DispatchFunc
{
DISPATCH_DISCRETE = 1,
DISPATCH_CONTINUOUS
};
btDispatcherInfo()
:m_timeStep(btScalar(0.)),
m_stepCount(0),
m_dispatchFunc(DISPATCH_DISCRETE),
m_timeOfImpact(btScalar(1.)),
m_useContinuous(false),
m_debugDraw(0),
m_enableSatConvex(false),
m_enableSPU(true),
m_useEpa(true),
m_allowedCcdPenetration(btScalar(0.04)),
m_useConvexConservativeDistanceUtil(true),
m_convexConservativeDistanceThreshold(0.0f),
m_stackAllocator(0)
{
}
btScalar m_timeStep;
int m_stepCount;
int m_dispatchFunc;
mutable btScalar m_timeOfImpact;
bool m_useContinuous;
class btIDebugDraw* m_debugDraw;
bool m_enableSatConvex;
bool m_enableSPU;
bool m_useEpa;
btScalar m_allowedCcdPenetration;
bool m_useConvexConservativeDistanceUtil;
btScalar m_convexConservativeDistanceThreshold;
btStackAlloc* m_stackAllocator;
};
///The btDispatcher interface class can be used in combination with broadphase to dispatch calculations for overlapping pairs.
///For example for pairwise collision detection, calculating contact points stored in btPersistentManifold or user callbacks (game logic).
class btDispatcher
{
public:
virtual ~btDispatcher() ;
virtual btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold=0) = 0;
virtual btPersistentManifold* getNewManifold(void* body0,void* body1)=0;
virtual void releaseManifold(btPersistentManifold* manifold)=0;
virtual void clearManifold(btPersistentManifold* manifold)=0;
virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1) = 0;
virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0;
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) =0;
virtual int getNumManifolds() const = 0;
virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0;
virtual btPersistentManifold** getInternalManifoldPointer() = 0;
virtual void* allocateCollisionAlgorithm(int size) = 0;
virtual void freeCollisionAlgorithm(void* ptr) = 0;
};
#endif //_DISPATCHER_H
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_MULTI_SAP_BROADPHASE
#define BT_MULTI_SAP_BROADPHASE
#include "btBroadphaseInterface.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "btOverlappingPairCache.h"
class btBroadphaseInterface;
class btSimpleBroadphase;
typedef btAlignedObjectArray<btBroadphaseInterface*> btSapBroadphaseArray;
///The btMultiSapBroadphase is a research project, not recommended to use in production. Use btAxisSweep3 or btDbvtBroadphase instead.
///The btMultiSapBroadphase is a broadphase that contains multiple SAP broadphases.
///The user can add SAP broadphases that cover the world. A btBroadphaseProxy can be in multiple child broadphases at the same time.
///A btQuantizedBvh acceleration structures finds overlapping SAPs for each btBroadphaseProxy.
///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=328
///and http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329
class btMultiSapBroadphase :public btBroadphaseInterface
{
btSapBroadphaseArray m_sapBroadphases;
btSimpleBroadphase* m_simpleBroadphase;
btOverlappingPairCache* m_overlappingPairs;
class btQuantizedBvh* m_optimizedAabbTree;
bool m_ownsPairCache;
btOverlapFilterCallback* m_filterCallback;
int m_invalidPair;
struct btBridgeProxy
{
btBroadphaseProxy* m_childProxy;
btBroadphaseInterface* m_childBroadphase;
};
public:
struct btMultiSapProxy : public btBroadphaseProxy
{
///array with all the entries that this proxy belongs to
btAlignedObjectArray<btBridgeProxy*> m_bridgeProxies;
btVector3 m_aabbMin;
btVector3 m_aabbMax;
int m_shapeType;
/* void* m_userPtr;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
*/
btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask)
:btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask),
m_aabbMin(aabbMin),
m_aabbMax(aabbMax),
m_shapeType(shapeType)
{
m_multiSapParentProxy =this;
}
};
protected:
btAlignedObjectArray<btMultiSapProxy*> m_multiSapProxies;
public:
btMultiSapBroadphase(int maxProxies = 16384,btOverlappingPairCache* pairCache=0);
btSapBroadphaseArray& getBroadphaseArray()
{
return m_sapBroadphases;
}
const btSapBroadphaseArray& getBroadphaseArray() const
{
return m_sapBroadphases;
}
virtual ~btMultiSapBroadphase();
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
void addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase);
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
virtual btOverlappingPairCache* getOverlappingPairCache()
{
return m_overlappingPairs;
}
virtual const btOverlappingPairCache* getOverlappingPairCache() const
{
return m_overlappingPairs;
}
///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
///will add some transform later
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
{
aabbMin.setValue(-1e30f,-1e30f,-1e30f);
aabbMax.setValue(1e30f,1e30f,1e30f);
}
void buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
virtual void printStats();
void quicksort (btBroadphasePairArray& a, int lo, int hi);
///reset broadphase internal structures, to ensure determinism/reproducability
virtual void resetPool(btDispatcher* dispatcher);
};
#endif //BT_MULTI_SAP_BROADPHASE
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OVERLAPPING_PAIR_CALLBACK_H
#define OVERLAPPING_PAIR_CALLBACK_H
class btDispatcher;
struct btBroadphasePair;
///The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache.
class btOverlappingPairCallback
{
public:
virtual ~btOverlappingPairCallback()
{
}
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0;
virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher) = 0;
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher) = 0;
};
#endif //OVERLAPPING_PAIR_CALLBACK_H
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_TRIANGLE_DETECTOR_H
#define SPHERE_TRIANGLE_DETECTOR_H
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
class btSphereShape;
class btTriangleShape;
/// sphere-triangle to match the btDiscreteCollisionDetectorInterface
struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
{
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle, btScalar contactBreakingThreshold);
virtual ~SphereTriangleDetector() {};
private:
bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold);
bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);
btSphereShape* m_sphere;
btTriangleShape* m_triangle;
btScalar m_contactBreakingThreshold;
};
#endif //SPHERE_TRIANGLE_DETECTOR_H
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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