Can I get some feedback on my sector code? I just made the sector structure up and want to know if I’m going in the right direction. I would also be interested in feedback on my code structure.
This is a full program that should compile with the GLUT library (win/mac/lin). (google for GLUT)
Blue rings follow behind the cursor and slide against the sector walls if the cursor moves outside.
#include <gl\glut.h>
#include <math.h>
#undef SCREEN_WIDTH
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define PIXEL_WIDTH 10/(float)SCREEN_WIDTH
#define PIXEL_HEIGHT 7.5/(float)SCREEN_HEIGHT
#define pi 3.1415926
#define MAX_GUYS 1 //guy at pos[3] in sector follows carrot[3]
struct guy_struct { float carrot[3]; float pos[3]; int sector;};
guy_struct guy[100];
#define MAX_SECTORS 8
int last_sector = 0;
struct sector_struct { int begin; };
sector_struct sector[MAX_SECTORS];
#define MAX_LINES 64
int last_line = 0;
struct line_struct { float slope; float shift; float pos[3]; char below;
float slope2;float shift2; int portal;};
line_struct line[MAX_LINES];
void timer(int t) {
glutPostRedisplay();
}
float linesIntersectAtX( float slope1, float shift1, float slope2, float shift2) {
return( (shift2 - shift1) / (slope1 - slope2) );
}
void checkBounds(float *o, int this_sector) { //check coordinate o against walls, move within sector if needed
for(int i = sector[this_sector].begin; i < sector[this_sector+1].begin; i++) {
float slope = line[i].slope;
float shift = line[i].shift;
float slope2 = line[i].slope2;
float shift2 = *(o+2) - *(o+0) * slope2;
char line_crossed = 0;
if( line[i].below ) { //should object be below line?
if( *(o+0) * slope + shift > *(o+2) ) //did object cross boundary?
line_crossed = 1;
} else {
if( *(o+0) * slope + shift < *(o+2) ) //did object cross boundary?
line_crossed = 1;
}
if(line_crossed) {
if(line[i].portal != 99) //99 == wall
guy[0].sector = line[i].portal;
else { //move coordinate o within sector
*(o+0) = linesIntersectAtX(slope, shift, slope2, shift2);
if(slope < 99) *(o+2) = *(o+0) * slope + shift;
glBegin(GL_LINES);//draw line perpendicular to intersected wall
glColor3f(0,1,1);
glVertex3f(-10,0,-10*slope2+shift2);
glVertex3f( 10,0, 10*slope2+shift2);
glEnd();
}
}
}
}
void moveGuys(void) {
for(int i = 0; i < MAX_GUYS; i++) {
float o[] = { guy[i].carrot[0] - guy[i].pos[0], //pass coordinate o to checkbounds()
guy[i].carrot[1] - guy[i].pos[1],
guy[i].carrot[2] - guy[i].pos[2] };
o[0] = guy[i].pos[0] + o[0]/10;
o[1] = guy[i].pos[1] + o[1];
o[2] = guy[i].pos[2] + o[2]/10;
checkBounds( o, guy[i].sector );
guy[i].pos[0] = o[0];
guy[i].pos[1] = o[1];
guy[i].pos[2] = o[2];
}
}
void drawGuys(void) { // just need one guy
for(int i = 0; i < MAX_GUYS; i++) {
glPushMatrix();
glTranslatef(guy[i].pos[0], guy[i].pos[1], guy[i].pos[2]);
glScalef(.5,.5,.5);
glBegin(GL_TRIANGLE_STRIP);
for(int k = 0; k < 21; k++) { //blue ring 1
glColor3f(i%2,sin(k/10.0*pi),!(i%2));
glVertex3f(cos(k/10.0*pi),sin(k/10.0*pi),-.125);
glVertex3f(cos(k/10.0*pi),sin(k/10.0*pi),0.125);
}
for( k = 0; k < 21; k++) { //blue ring 2
glColor3f(i%2,cos(k/10.0*pi),!(i%2));
glVertex3f(0.125, cos(k/10.0*pi), sin(k/10.0*pi));
glVertex3f(-.125, cos(k/10.0*pi), sin(k/10.0*pi));
}
for( k = 0; k < 21; k++) { //white ring
glColor3f(1,1,1);
glVertex3f(cos(k/10.0*pi), 0.125, sin(k/10.0*pi));
glVertex3f(cos(k/10.0*pi), -.125, sin(k/10.0*pi));
}
glEnd();
glPopMatrix();
}
}
void drawSectors(void) {
glColor3f(1,1,1);
for(int i = 0; i <= last_sector; i++) {
glBegin(GL_LINE_LOOP);
for(int k = sector[i].begin; k < sector[i+1].begin; k++)
glVertex3fv(line[k].pos);
glEnd();
}
}
void drawBoard(void) { //checkered board background
glDepthMask(GL_FALSE);
glBegin(GL_QUADS);
for(int x = -5; x < 5; x+=2) {
for(int z = -5; z < 5; z++) {
glColor3f(.5,.3,.5);glVertex3f(x+1,0,z+1);
glColor3f(.3,.3,.3);glVertex3f(x+0,0,z+1);
glVertex3f(x+0,0,z+0);
glVertex3f(x+1,0,z+0);
x++;z++;
glColor3f(.6,.4,.6);glVertex3f(x+1,0,z+1);
glColor3f(.3,.3,.3);glVertex3f(x+0,0,z+1);
glVertex3f(x+0,0,z+0);
glVertex3f(x+1,0,z+0);
x--;
}
}
glEnd();
glDepthMask(GL_TRUE);
}
void renderScene(void) //**RENDERSCENE**//
{
glutTimerFunc( 1000/60.0, timer, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(0,0,-10);
glRotatef(90,1,0,0);
moveGuys();
drawBoard();
drawGuys();
drawSectors();
glPopMatrix();
glutSwapBuffers();
}
void processNormalKeys(unsigned char key, int x, int y) {
switch (key) {
case 27:
exit(0);
break;
}
}
void processMouseMotion(int x, int y) { //resolution dependant 800x600
guy[0].carrot[0] = x*PIXEL_WIDTH-5;
guy[0].carrot[2] = y*PIXEL_HEIGHT-3.75;
}
void sectorSlopes(void) { //find line[i].slope and perpendicular slope2 line[i].slope2
float x,y;
for( int s = 0; s <= last_sector; s++) {
for(int i = sector[s].begin; i < sector[s+1].begin; i++) {
int a = i, b = i+1;
if( b == sector[s+1].begin ) b = sector[s].begin;
x = line[b].pos[0] - line[a].pos[0];
y = line[b].pos[2] - line[a].pos[2];
if(x) line[a].slope = y/x;
else {
if(line[a].pos[2] > line[b].pos[2])
line[a].slope = 999;
else line[a].slope = -999;
}
line[a].shift = line[a].pos[2] - line[a].pos[0] * line[a].slope;
if( line[a].pos[0] < line[b].pos[0] )
line[a].below = 1;
else line[a].below = 0;
if(line[a].slope) line[a].slope2 = -1/line[a].slope;
else line[a].slope2 = 999;
line[a].shift2 = line[a].pos[2] - line[a].pos[0] * line[a].slope2;//shift = y - xM
line[a].portal = 99;
}
}
}
void createSectorSquare(void) { //create 1 square sector
sector[0].begin = 0;
sector[1].begin = 4;
last_sector = 0;
last_line = 3;
line[0].pos[0] = 2;
line[0].pos[1] = 0;
line[0].pos[2] = 2;
line[1].pos[0] =-2;
line[1].pos[1] = 0;
line[1].pos[2] = 2;
line[2].pos[0] =-2;
line[2].pos[1] = 0;
line[2].pos[2] =-2;
line[3].pos[0] = 2;
line[3].pos[1] = 0;
line[3].pos[2] =-2;
sectorSlopes();
}
void createSectorOval(void) { //create 1 oval sector (fun)
sector[0].begin = 0;
sector[1].begin = 24;
last_sector = 0;
last_line = 23;
for(int i = 0; i < 24; i++) {
line[i].pos[0] = cos(i/12.0*pi+pi/24.0) * 4;
line[i].pos[1] = 0;
line[i].pos[2] = sin(i/12.0*pi+pi/24.0) * 2;
}
sectorSlopes();
}
void createSectorOctagons(void) { //create 2 connected octagons
sector[0].begin = 0;
sector[1].begin = 8;
sector[2].begin = 16;
last_sector = 1;
last_line = 15;
float shift = cos(3/4.0*pi+pi/8.0) * 2;
for(int i = 0; i < 8; i++) {
line[i].pos[0] = cos(i/4.0*pi+pi/8.0) * 2 - shift;
line[i].pos[1] = 0;
line[i].pos[2] = sin(i/4.0*pi+pi/8.0) * 2;
}
for( i = 8; i < 16; i++) {
line[i].pos[0] = cos(i/4.0*pi+pi/8.0) * 2 + shift;
line[i].pos[1] = 0;
line[i].pos[2] = sin(i/4.0*pi+pi/8.0) * 2;
}
sectorSlopes();
line[ 3].portal = 1;
line[15].portal = 0;
}
void initSectors(void) { //comment out all but one of these functions
createSectorOctagons();
//createSectorOval();
//createSectorSquare();
}
void initGuys(void) { //guy[0] is the ball, only 1 is needed
for(int i = 0; i < MAX_GUYS; i++) {
guy[i].carrot[0] = 0;
guy[i].carrot[1] = 0;
guy[i].carrot[2] = 0;
guy[i].pos[0] = 0;
guy[i].pos[1] = 0;
guy[i].pos[2] = 0;
guy[i].sector = 0;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(SCREEN_WIDTH,SCREEN_HEIGHT);
glutCreateWindow("Sector Test");
glutDisplayFunc(renderScene);
glutPassiveMotionFunc(processMouseMotion);
glutKeyboardFunc(processNormalKeys);
glutTimerFunc( 1, timer, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-2,2,-1.5,1.5,4,400);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
glClearColor(.6, .4, .6, 0.0);
initGuys();
initSectors();
glutMainLoop();
return(0);
}