Solved

Opengl collision detection

Posted on 2011-03-19
27
1,642 Views
Last Modified: 2013-12-06
I am trying to do collision detection in opengl using bounding spheres. i am trying to create one sphere with a weapon and another with an enemy and check for collisions between these two.

This is for the distance between our objects.

GLfloat d;

This holds the x and y positions for my first point

GLfloat p1x;
GLfloat p1y;
GLfloat p1z;

This is the radius of the spheres

const p1radius = 1;
const p2radius = 1;

and finally the positions of the second object.

GLfloat p2x;
GLfloat p2y;
GLfloat p2z;


In the code below I am drawing a sphere around the weapon and the enemy. However when I check for collisions with this function it keeps saying there is a collision all the time.


void pointz (void)

{


glPushMatrix();
if (d <= p2radius + p1radius)
{
 output(0, 2, "You Win.");
}
else
{
 output(0,2, "You lose. ");
}
glPopMatrix();
}
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>
#include <GL/gl.h>
#include <gl/glu.h>
#include <GL/glut.h>
#include <cstdlib>
#include <ctime>
#include <iostream>


#include <math.h>
#include "Enemy.h"
#include "Item.h"
#include "Weapon.h"
#include "Skybox.h"
#include "CGfxOpenGL.h"
#include "timer.h"
//angle of rotation
float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
float cRadius = 10.0f; // our radius distance from our character
float lastx, lasty;
void DrawFloor();
void DrawSnowMan();
void DrawWeapon();
void drawitem();
void drawEnemy();
void collision();
//static int weapon = 0;
//void skybox();
Enemy enemy;
Item item; 
CSkybox skybox;
CGfxOpenGL opengl;
Weapon weapon;
GLfloat d;
using namespace std;
//positions of the cubes
float positionz[10];
float positionx[10];
float positionzaxis[10];
float positionxaxis[10];
float positionzone[10];
float positionxone[10];
int Score = 0;
int frame = 0;
float Weaponangle = 0.0;
bool bWeaponIsActive;
//float PI = 3.1415927f;
// Load in textures 
#define SNOW 0
//#define HORIZON 0

GLfloat p1x;
GLfloat p1y;
GLfloat p1z;


const int p1radius = 1;
const int p2radius = 0;


GLfloat p2x;
GLfloat p2y;
GLfloat p2z;

CGfxOpenGL *g_glRender = NULL;
 
CHiResTimer *g_hiResTimer = NULL;


static GLfloat spin = 0.0;
GLfloat light_diffuse[] = {0.0, 0.0, 0.0, 0.0};  /* Red diffuse light. */
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};  /* Infinite light location. */

//diffuse light color variables
GLfloat dlr = 1.0;
GLfloat dlg = 1.0;
GLfloat dlb = 1.0;
//ambient light color variables
GLfloat alr = 0.0;
GLfloat alg = 1.0;
GLfloat alb = 1.0;


//light position variables
GLfloat lx = 0.0;
GLfloat ly = 2.0;
GLfloat lz = 0.0;
GLfloat lw = 0.0;

CGfxOpenGL * CG;
CHiResTimer * CH;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =

{

  GLUT_BITMAP_9_BY_15,
  GLUT_BITMAP_TIMES_ROMAN_10,
  GLUT_BITMAP_TIMES_ROMAN_24
};

char defaultMessage[] = "GLUT means OpenGL.";
char *message = defaultMessage;

 //srand(time(0));
//int number=1;  //start with a value less than 20000
//int count=1;
//int maxrange = 1000;

/*double random ()
{

while (count<20000)
    {
      number = rand()%maxrange;  // generate a random number
                           //between 0 and whatever max you want
      count++; //increase loop count

  //   cout << "number is" << number;
   //  cout << "generated on try #: " << count;
    }
}*/
struct Vector3
{
float x;
float y;
float z;
};

struct BoundingBox
{
Vector3 max;
Vector3 min;
};

struct Image 
{
    unsigned long size_x;
    unsigned long size_y;
    char *data;
};

typedef struct Image Image;

const int textureCount = 1; // specifies # of textures


Image myTextureData[textureCount];  //array storing image texture info
GLuint theTexture[textureCount];  //array storing OpenGL texture info

/* texture filename list */
char* textureFilenames[textureCount] = {"Snow.bmp"};
int window_width = 800; //sets the width of the window
int window_height = 600; //sets the hight of the window

///////////////////////////////////////////////
//////////////////////////////////////////////

void selectFont(int newfont)
{
  font = fonts[newfont];
  glutPostRedisplay();
}

void collision (void) {

//Our distance is worked out with this simple little formula.

	d = sqrt(((p1x - p2x) * (p1x - p2x)) + ((p1y - p2y) * (p1y - p2y)) 
+ ((p1z - p2z) * (p1z - p2z)));
}

void spinDisplay(void)
{
   spin = spin + 2.0;
   if (spin > 360.0)
      spin = spin - 360.0;
   glutPostRedisplay();
}

void selectMessage(int msg)
{
  switch (msg) {
  case 1:
    message = "abcdefghijklmnop";
    break;
  case 2:
    message = "ABCDEFGHIJKLMNOP";
    break;
  }

}

void output(int x, int y, char *string)
{
  int len, i;

  glRasterPos2f(x, y);
  len = (int) strlen(string);
  for (i = 0; i < len; i++) {
    glutBitmapCharacter(font, string[i]);
  }
}



void pointz (void) 

{


glPushMatrix();
if (d <= p2radius + p1radius)
{
 output(0, 2, "You Win.");
}
else
{
 output(0,2, "You lose. ");
}
glPopMatrix();
}



void UpdateWeapon (void)
{
   if (bWeaponIsActive)
   {
      ++frame;

      if ((frame < 9) && (frame > 11))
      {
         Weaponangle = 90 * (sin (PI / 20 * frame));
      }
      
      if (frame == 20) bWeaponIsActive = false;  // hammer action is finished
   }
}


int imageLoader(const char *filename, Image *image) 
{
    FILE *file;

    unsigned long size;
    unsigned long i;
    unsigned short int planes;
    unsigned short int bpp;

    char temp;
	char finalName[80];

	glTexCoord2f(1.0, 0.0);

	strcpy_s(finalName, "" );
	strcat_s(finalName, filename);

    if ((file = fopen(finalName, "rb"))==NULL) 
	{
		printf("File Not Found : %s\n",finalName);
		return 0;
    }

    fseek(file, 18, SEEK_CUR);

	glTexCoord2f(1.0, 0.0);
    
	if ((i = fread(&image->size_x, 4, 1, file)) != 1) 
	{
		printf("Error reading width from %s.\n", finalName);
		return 0;
    }

    if ((i = fread(&image->size_y, 4, 1, file)) != 1) 
	{
		printf("Error reading height from %s.\n", finalName);
		return 0;
    }

    size = image->size_x * image->size_y * 3;

    if ((fread(&planes, 2, 1, file)) != 1) 
	{
		printf("Error reading planes from %s.\n", finalName);
		return 0;
    }

    if (planes != 1) 
	{
		printf("Planes from %s is not 1: %u\n", finalName, planes);
		return 0;
    }

    if ((i = fread(&bpp, 2, 1, file)) != 1) 
	{
		printf("Error reading bpp from %s.\n", finalName);
		return 0;
    }

    if (bpp != 24) 
	{
		printf("Bpp from %s is not 24: %u\n", finalName, bpp);
		return 0;
    }

    fseek(file, 24, SEEK_CUR);

    image->data = (char *) malloc(size);

    if (image->data == NULL) 
	{
		printf("Error allocating memory for color-corrected image data");
		return 0;
    }

    if ((i = fread(image->data, size, 1, file)) != 1) 
	{
		printf("Error reading image data from %s.\n", finalName);
		return 0;
    }

    for (i=0;i<size;i+=3) 
	{
		temp = image->data[i];
		image->data[i] = image->data[i+2];
		image->data[i+2] = temp;
    }
    return 1;
}



//////////////////////////////////////////////////////
////Texture Loader
//////////////////////////////////////////////////////

void textureLoader() 
{
	/* set the pixel storage, GL_UNPACK_ALIGNMENT : specifies alignment requirements
	   for the start of each pixel row in memory 1 = byte-alignment*/
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	for(int k=0; k < textureCount; k++) 
	{
		if(!imageLoader(textureFilenames[k], &myTextureData[k])) 
			exit(1);
		
		/* generate texture names */
		glGenTextures(1, &theTexture[k]);
		/* create a named texture bound to a texture target */
	    glBindTexture(GL_TEXTURE_2D, theTexture[k]);

		/* set the texture parameters */
		glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
		/* builds and load a set of mipmaps */
	   	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, myTextureData[k].size_x, myTextureData[k].size_y, GL_RGB, GL_UNSIGNED_BYTE, myTextureData[k].data);
	}
}

void DrawWeapon(void)
{
   glPushMatrix();
  // glRotatef(90.0f,5.0f,10.0f,5.0f);
   //glScalef (2.0, 0.4, 1.0);
   glTranslatef(0.5f,-1.0f,-1.9f);
  

 //  glRotatef ((GLfloat) weapon, 0.0, 0.0, 1.0);
   glutSolidSphere (1.0, 20, 16);

    glBegin(GL_POINTS);
    glVertex3f(p1x, p1y, p1z);
    glEnd();
   


   

	glPopMatrix();



}


void DrawSnowMan(void)
{

  // Draw Body	

  /* if (box->min.x>x) box->min.x = x;
   if (box->min.y>y) box->min.y = y;
   if (box->min.z>z) box->min.z = z;

   if (box->max.x<x) box->max.x = x;
   if (box->max.y<y) box->max.y = y;
   if (box->max.z<z) box->max.z = z;*/
	glTranslatef(0.0f ,0.1f, 0.0f);
	glutSolidSphere(0.75f,20,20);

  

  // Draw Head
	glTranslatef(0.0f, 1.0f, 0.0f);
	glutSolidSphere(0.4f,20,20);

   // Draw Hand 
	glPushMatrix();
    glTranslatef(0.5f ,-0.5f, 0.0f);
	glutSolidSphere(0.4f,20,20);
    glPopMatrix();

	//Draw Second hand
	glPushMatrix();
    glTranslatef(-0.5f ,-0.5f, 0.0f);
	glutSolidSphere(0.4f,20,20);
	
    glPopMatrix();


// Draw Eyes
	glPushMatrix();
	glColor3f(0.0f,0.0f,0.0f);
	glTranslatef(0.05f, 0.10f, -0.4f);
	glutSolidSphere(0.05f,10,10);
	glTranslatef(-0.1f, 0.0f, 0.0f);
	glutSolidSphere(0.05f,10,10);
	glPopMatrix();


// Draw Nose
	glPushMatrix();
	glColor3f(1.0f, 0.5f , 0.5f);
	
	glTranslatef(0.0f,0.0f,-0.2f);
	glRotatef(180.0f,0.0f,0.0f,0.0f);
	glutSolidCone(0.08f,0.5f,10,2);
	
    glPopMatrix();
	
}

void Itempositions (void) {
   
         for (int i=0;i<10;i++)
    {
    positionzaxis[i] = rand()%20 + 3;
    positionxaxis[i] = rand()%10 + 3;
    }


}

void Enemypositions (void) {
   
         for (int i=0;i<10;i++)
    {
    positionzone[i] = rand()%20 + 3;
    positionxone[i] = rand()%10 + 3;
    }


}


void drawEnemy (void) 
{

    for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
    
    glTranslated(-positionxone[i + 1] * 10, 0, -positionzone[i + 1] * 10); //translate the items
	glPushMatrix();
	glTranslatef(0.0f,8.0f,0.0f);
    enemy.DrawEnemy();
    glBegin(GL_POINTS);
    glVertex3f(p2x, p2y, p2z);
    glEnd();
	glPopMatrix();
    glPopMatrix();
	}
}

void drawitems (void) 
{

    for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
    
    glTranslated(-positionxaxis[i + 1] * 10, 0, -positionzaxis[i + 1] * 10); //translate the items
	glPushMatrix();
    item.DrawItem();
	glPopMatrix();
    glPopMatrix();
	}
}


void cubepositions (void) { //set the positions of the cubes

    for (int i=0;i<10;i++)
    {
    positionz[i] = rand()%10 + 3;
    positionx[i] = rand()%10 + 3;
    }
}
//draw the cube
void cube (void) {
    for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
    
    glTranslated(-positionx[i + 1] * 10, 0, -positionz[i + 1] * 10); //translate the cube
	
    // houseww
    glPushMatrix();
	glTranslatef(0,5,0);
    //glBindTexture(GL_TEXTURE_2D,texture[0]);
    glutSolidCube(12);                 // building
    
    glTranslatef(0,5,0);
    glPushMatrix();                   // roof
    glRotatef(-90,1,0,0);
    glutSolidCone(10.5,10,16,19);
    glPopMatrix();

    glTranslatef(.75,.20,-.75);         
    glPushMatrix();                   // chimney
    glScalef(2,8,2);
    glutSolidCube(.25);
    glPopMatrix();
    glPopMatrix();

    glTranslatef(0,-.65,2);
   // glutSolidCube(2); //draw the cube
    glPopMatrix();
    }
}
void init (void) {

    //enable LIGHT0, our Diffuse Light
	Itempositions();
	Enemypositions();
    cubepositions();
	CG->Init();
	
    glEnable (GL_LIGHT0); //enable LIGHT0, our Diffuse Light
    glEnable (GL_LIGHT1); //enable LIGHT1, our Ambient Light
    glEnable(GL_TEXTURE_2D);
    
	
     
   
	
}




void enable (void) {
    glEnable (GL_DEPTH_TEST); //enable the depth testing
    
    glEnable (GL_COLOR_MATERIAL);
    glShadeModel (GL_SMOOTH); //set the shader to smooth shader
    glEnable(GL_TEXTURE_2D);
}



void display (void) {
     glClearColor (0.0,0.0,0.0,1.0); //clear the screen to 
//blacks
  
     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
//clear the color buffer and the depth buffer
     enable();
     

    glColor3f(1.0f, 0.0f, 0.0f);

	CG->Prepare(CH->GetElapsedSeconds(1));
	CG->Render();
    
 
     
     
    glLoadIdentity(); 

    GLfloat DiffuseLight[] = {dlr, dlg, dlb}; //set DiffuseLight

    GLfloat AmbientLight[] = {alr, alg, alb}; //set AmbientLight

    glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight); //change
 
    glLightfv (GL_LIGHT1, GL_AMBIENT, AmbientLight); //change
 
    GLfloat LightPosition[] = {lx, ly, lz, lw}; //set the 

    glLightfv (GL_LIGHT0, GL_POSITION, LightPosition); 

    textureLoader();
   
    glTranslatef(0.0f, 0.0f, -cRadius);
    glRotatef(xrot,1.0,0.0,0.0);
    
	//glColor3f(1.0f, 1.0f, 1.0f);
    
    

    //output(0, 2, "Kill the Robots.");
    

    if (Score > 100)
	{
       output(0, 2, "You Win.");

	}
    glPushMatrix();
    //glutSolidCube(2); //Our character to follow*/
	glTranslatef(0.4f,0.0f,0.0f);
    DrawSnowMan();
	
	glPopMatrix();


	glPushMatrix();
    DrawWeapon();
    
    glPointSize(0.2);
    collision();
    pointz();





   // glRotatef ((GLfloat) weapon, 0.0, 0.0, 1.0);
	glPopMatrix();
    glRotatef(yrot,0.0,1.0,0.0);  
    glTranslated(-xpos,0.0f,-zpos); 
  
    cube(); //call the cube drawing function
    drawitems();
	glPushMatrix();

    drawEnemy();
  
    glPopMatrix();

    glPushMatrix();
    glScalef (2.0, 0.4, 1.0);
    DrawFloor();

   
	//CG->Prepare(CH->GetElapsedSeconds(1));
	//CG->Render();
	
    glPopMatrix();
    glutSwapBuffers(); //swap the buffers
	
    angle++; //increase the angle
}



void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport
 //to the current window specifications
    glMatrixMode (GL_PROJECTION); //set the matrix to projection
     
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 100.0); //set the perspective (angle of sight, width, height, , depth

    glMatrixMode (GL_MODELVIEW); //set the matrix back to model

}
void keyboard (unsigned char key, int x, int y) {
    if (key=='q')
    {
    xrot += 1;
    if (xrot >360) xrot -= 360;
    }
    if (key=='z')
    {
    xrot -= 1;
    if (xrot < -360) xrot += 360;
    }
    if (key=='w')
    {
    float xrotrad, yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xrotrad = (xrot / 180 * 3.141592654f); 
    xpos += float(sin(yrotrad));
    zpos -= float(cos(yrotrad));
    ypos -= float(sin(xrotrad));
    }
    if (key=='s')
    {
    float xrotrad, yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xrotrad = (xrot / 180 * 3.141592654f); 
    xpos -= float(sin(yrotrad));
    zpos += float(cos(yrotrad));
    ypos += float(sin(xrotrad));
    }
    if (key=='d')
    {
    float yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xpos += float(cos(yrotrad)) * 0.2;
    zpos += float(sin(yrotrad)) * 0.2;
    }
    if (key=='e')
	{
       // weapon = (weapon + 50) % 360;
        frame = 0;
		bWeaponIsActive = true;
		glutPostRedisplay();
	}
    if (key=='a')
    {
    float yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xpos -= float(cos(yrotrad)) * 0.2;
    zpos -= float(sin(yrotrad)) * 0.2;
    }
    if (key==27)
    {
    exit(0);
    }
}

void DrawFloor(void) { 

	   
       glBindTexture(GL_TEXTURE_2D, theTexture[SNOW]);
       glTranslatef(0.0f,-3.0f,3.0f);

 glBegin(GL_QUADS);
       
        glTexCoord2f(1.0f,0.0f);
        //glColor3f(0.2f, 0.2f, 0.2f);
        glVertex3f(-200.0,-0.5, -200);
        glTexCoord2f(1.0f,1.0f);
       // glColor3f(0.4f, 0.4f, 0.4f);
        glVertex3f(-200.0,-0.5, 200.0);
        glTexCoord2f(0,1.0f);
       // glColor3f(0.6f, 0.6f, 0.6f);
        glVertex3f(200.0, -0.5, 200.0);
        glTexCoord2f(0,0);
       // glColor3f(0.8f, 0.8f, 0.8f);
        glVertex3f(200.0, -0.5, -200.0);        
    glEnd();

}

void mouseMovement(int x, int y) {
    int diffx=x-lastx; //check the difference between the 
//current x and the last x position
    int diffy=y-lasty; //check the difference between the 
//current y and the last y position
    lastx=x; //set lastx to the current x position
    lasty=y; //set lasty to the current y position
    xrot += (float) diffy; //set the xrot to xrot with the addition
 //of the difference in the y position
    yrot += (float) diffx;    //set the xrot to yrot with the addition
 //of the difference in the x position
}



int main (int argc, char **argv) {
	CH = new CHiResTimer;
	CG = new CGfxOpenGL;
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowSize (500, 500); 
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Snow Man Game"); 
    init (); 

	glEnable(GL_TEXTURE_2D);

    
    UpdateWeapon();
    
    glutDisplayFunc (display); 
    glutIdleFunc (display); 
    glutReshapeFunc (reshape);
    glutPassiveMotionFunc(mouseMovement); //check for mouse
    
    glutKeyboardFunc (keyboard); 
    glutMainLoop (); 
    return 0;
}

Open in new window

0
Comment
Question by:tango2009
  • 10
  • 6
  • 5
  • +1
27 Comments
 
LVL 12

Expert Comment

by:satsumo
ID: 35173376
You aren't setting p1x, p1y, p1z, p2x, p2y or p2z.  Assuming they all start as zero, you have two spheres at (0, 0, 0).  So they are overlapping.
0
 

Author Comment

by:tango2009
ID: 35175620
How would I go about drawing a sphere for each enemy which I am trying to do below.


    for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
   
    glTranslated(-positionxone[i + 1] * 10, 0, -positionzone[i + 1] * 10); //translate the items
      glPushMatrix();
      glTranslatef(0.0f,8.0f,0.0f);
    enemy.DrawEnemy();
    glBegin(GL_POINTS);
    glVertex3f(p2x, p2y, p2z);
    glEnd();
      glPopMatrix();
    glPopMatrix();
      }
}

I thought this code would draw a sphere at every point where the enemy was being drawn.
0
 

Author Comment

by:tango2009
ID: 35183940
Could I set these values p2x, p2y and p2z to these values from the code above?

positionzone
positionxone

i am trying to have many spheres around enemies and then one around my player whcih can colllide with these spheres. my full code is below.



#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>
#include <GL/gl.h>
#include <gl/glu.h>
#include <GL/glut.h>
#include <cstdlib>
#include <ctime>
#include <iostream>


#include <math.h>
#include "Enemy.h"
#include "Objects.h"
#include "Item.h"
#include "Weapon.h"
#include "Skybox.h"
#include "CGfxOpenGL.h"
#include "timer.h"
//angle of rotation
float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
float cRadius = 10.0f; // our radius distance from our character
float lastx, lasty;
void DrawFloor();
void DrawSnowMan();
void DrawWeapon();
void drawitem();
void drawEnemy();
void collision();
static int weaponangle = 0;
//void skybox();
Enemy enemy;
Item item; 
Object object;
CSkybox skybox;
CGfxOpenGL opengl;
Weapon weapon;
GLfloat d;
using namespace std;
//positions of the cubes
float positionz[10];
float positionx[10];
float positionzaxis[10];
float positionxaxis[10];
float positionzone[10];
float positionxone[10];
float positionztwo[10];
float positionxtwo[10];
int Score = 0;
int frame = 0;
float pos[3] = { 1.0f, 2.0f, 3.0f };
float Weaponangle = 30.0f;
bool bWeaponIsActive;
//float PI = 3.1415927f;
// Load in textures 
#define SNOW 0
//#define WOOD 0

GLfloat p1x;
GLfloat p1y;
GLfloat p1z;

static GLfloat spin = 2.0;
const int p1radius = 1;
const int p2radius = 0;


GLfloat p2x =  positionzone[10];
GLfloat p2y;
GLfloat p2z =  positionxone[10];

CGfxOpenGL *g_glRender = NULL;
CHiResTimer *g_hiResTimer = NULL;



GLfloat light_diffuse[] = {0.0, 0.0, 0.0, 0.0};  /* Red diffuse light.*/
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
  /* Infinite light location. */

//diffuse light color variables
GLfloat dlr = 1.0;
GLfloat dlg = 1.0;
GLfloat dlb = 1.0;
//ambient light color variables
GLfloat alr = 0.0;
GLfloat alg = 1.0;
GLfloat alb = 1.0;


//light position variables
GLfloat lx = 0.0;
GLfloat ly = 2.0;
GLfloat lz = 0.0;
GLfloat lw = 0.0;

CGfxOpenGL * CG;
CHiResTimer * CH;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =

{

  GLUT_BITMAP_9_BY_15,
  GLUT_BITMAP_TIMES_ROMAN_10,
  GLUT_BITMAP_TIMES_ROMAN_24
};

char defaultMessage[] = "GLUT means OpenGL.";
char *message = defaultMessage;

// srand(time(0));


/*double random ()
{
    srand ( time(NULL) );
    int number=1;  //start with a value less than 20000
    int count=1;
    int maxrange = 300;

   while (count<300)
   {
     
	   number = rand()%maxrange;
     
     

	  count++;

       printf ("Random number: %d\n", number);
   }

 // srand ( 1 );
    
  return 0;
}*/
struct Vector3
{
float x;
float y;
float z;
};

struct BoundingBox
{
Vector3 max;
Vector3 min;
};

struct Image 
{
    unsigned long size_x;
    unsigned long size_y;
    char *data;
};

typedef struct Image Image;

const int textureCount = 1; // specifies # of textures
//const int textureCountone = 1;

Image myTextureData[textureCount];  //array storing image texture info
GLuint theTexture[textureCount];  //array storing OpenGL texture info

/* texture filename list */
char* textureFilenames[textureCount] = {"Snow.bmp"};
int window_width = 800; //sets the width of the window
int window_height = 600; //sets the hight of the window

///////////////////////////////////////////////
//////////////////////////////////////////////

void selectFont(int newfont)
{
  font = fonts[newfont];
  glutPostRedisplay();
}

void collision (void) {

//Our distance is worked out with this simple little formula.

	d = sqrt(((p1x - p2x) * (p1x - p2x)) + ((p1y - p2y) * (p1y - p2y)) 
+ ((p1z - p2z) * (p1z - p2z)));
}

void spinDisplay(void)
{
   spin = spin + 2.0;
   if (spin > 360.0)
      spin = spin - 360.0;
   glutPostRedisplay();
}

void selectMessage(int msg)
{
  switch (msg) {
  case 1:
    message = "abcdefghijklmnop";
    break;
  case 2:
    message = "ABCDEFGHIJKLMNOP";
    break;
  }

}

void output(int x, int y, char *string)
{
  int len, i;

  glRasterPos2f(x, y);
  len = (int) strlen(string);
  for (i = 0; i < len; i++) {
    glutBitmapCharacter(font, string[i]);
  }
}



void pointz (void) 

{


glPushMatrix();
if (d <= p2radius + p1radius)
{
 output(0, 2, "You Win.");
}
else
{
 output(0,2, "You lose. ");
}
glPopMatrix();
}



void UpdateWeapon (void)
{
   if (bWeaponIsActive)
   {
      ++frame;

      if ((frame < 9) && (frame > 11))
      {
         Weaponangle = 90 * (sin (PI / 20 * frame));
      }
      
      if (frame == 20) bWeaponIsActive = false;  // hammer action is finished
   }
}


int imageLoader(const char *filename, Image *image) 
{
    FILE *file;

    unsigned long size;
    unsigned long i;
    unsigned short int planes;
    unsigned short int bpp;

    char temp;
	char finalName[80];

	glTexCoord2f(1.0, 0.0);

	strcpy_s(finalName, "" );
	strcat_s(finalName, filename);

    if ((file = fopen(finalName, "rb"))==NULL) 
	{
		printf("File Not Found : %s\n",finalName);
		return 0;
    }

    fseek(file, 18, SEEK_CUR);

	glTexCoord2f(1.0, 0.0);
    
	if ((i = fread(&image->size_x, 4, 1, file)) != 1) 
	{
		printf("Error reading width from %s.\n", finalName);
		return 0;
    }

    if ((i = fread(&image->size_y, 4, 1, file)) != 1) 
	{
		printf("Error reading height from %s.\n", finalName);
		return 0;
    }

    size = image->size_x * image->size_y * 3;

    if ((fread(&planes, 2, 1, file)) != 1) 
	{
		printf("Error reading planes from %s.\n", finalName);
		return 0;
    }

    if (planes != 1) 
	{
		printf("Planes from %s is not 1: %u\n", finalName, planes);
		return 0;
    }

    if ((i = fread(&bpp, 2, 1, file)) != 1) 
	{
		printf("Error reading bpp from %s.\n", finalName);
		return 0;
    }

    if (bpp != 24) 
	{
		printf("Bpp from %s is not 24: %u\n", finalName, bpp);
		return 0;
    }

    fseek(file, 24, SEEK_CUR);

    image->data = (char *) malloc(size);

    if (image->data == NULL) 
	{
		printf("Error allocating memory for color-corrected image data");
		return 0;
    }

    if ((i = fread(image->data, size, 1, file)) != 1) 
	{
		printf("Error reading image data from %s.\n", finalName);
		return 0;
    }

    for (i=0;i<size;i+=3) 
	{
		temp = image->data[i];
		image->data[i] = image->data[i+2];
		image->data[i+2] = temp;
    }
    return 1;
}



//////////////////////////////////////////////////////
////Texture Loader
//////////////////////////////////////////////////////

void textureLoader() 
{
	/* set the pixel storage, GL_UNPACK_ALIGNMENT : specifies alignment requirements
	   for the start of each pixel row in memory 1 = byte-alignment*/
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	for(int k=0; k < textureCount; k++) 
	{
		if(!imageLoader(textureFilenames[k], &myTextureData[k])) 
			exit(1);
		
		/* generate texture names */
		glGenTextures(1, &theTexture[k]);
		/* create a named texture bound to a texture target */
	    glBindTexture(GL_TEXTURE_2D, theTexture[k]);

		/* set the texture parameters */
		glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
		glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
		/* builds and load a set of mipmaps */
	   	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, myTextureData[k].size_x, myTextureData[k].size_y, GL_RGB, GL_UNSIGNED_BYTE, myTextureData[k].data);
	}
}

void DrawWeapon(void)
{
     glPushMatrix();
      // put the object at its position
      glTranslatef(pos[0], pos[1], pos[2]);
      // rotate the object inplace around the x-axis
      glRotatef(weaponangle, 1.0f, 0.0f, 0.0f);
      glutWireSphere (1.0, 20, 16);
  glPopMatrix();
 /* glBegin(GL_POINTS);
    glVertex3f(p1x, p1y, p1z);
    glEnd();*/

}


void DrawSnowMan(void)
{

  // Draw Body	

 
	glTranslatef(0.0f ,0.1f, 0.0f);
	glutSolidSphere(0.75f,20,20);

  

  // Draw Head
	glTranslatef(0.0f, 1.0f, 0.0f);
	glutSolidSphere(0.4f,20,20);

   // Draw Hand 
	glPushMatrix();
    glTranslatef(0.5f ,-0.5f, 0.0f);
	glutSolidSphere(0.4f,20,20);
    glPopMatrix();

	//Draw Second hand
	glPushMatrix();
    glTranslatef(-0.5f ,-0.5f, 0.0f);
	glutSolidSphere(0.4f,20,20);
	
    glPopMatrix();


// Draw Eyes
	glPushMatrix();
	glColor3f(0.0f,0.0f,0.0f);
	glTranslatef(0.05f, 0.10f, -0.4f);
	glutSolidSphere(0.05f,10,10);
	glTranslatef(-0.1f, 0.0f, 0.0f);
	glutSolidSphere(0.05f,10,10);
	glPopMatrix();


// Draw Nose
	glPushMatrix();
	glColor3f(1.0f, 0.5f , 0.5f);
	
	glTranslatef(0.0f,0.0f,-0.2f);
	glRotatef(180.0f,0.0f,0.0f,0.0f);
	glutSolidCone(0.08f,0.5f,10,2);
	
    glPopMatrix();
	
}

void Itempositions (void) {
   
         for (int i=0;i<10;i++)
    {
    positionzaxis[i] = rand()%20 + 3;
    positionxaxis[i] = rand()%10 + 3;
    }


}

void Objectpositions (void)
{

         for (int i=0;i<10;i++)
    {
    positionztwo[i] = rand()%20 + 3;
    positionxtwo[i] = rand()%10 + 3;
    }


}

void Enemypositions (void) {
   
         for (int i=0;i<10;i++)
        
    {
   
    positionzone[i] = rand()%20 + 3;
    positionxone[i] = rand()%10 + 3;
    }


}


void drawEnemy (void) 
{
    
    for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
    
    glTranslated(-positionxone[i + 1] * 10, 0, -positionzone[i + 1] * 10); //translate the items
	glPushMatrix();
	glTranslatef(0.0f,10.0f,0.0f);
    enemy.DrawEnemy();
    glVertex3f(p2x, p2y, p2z);
    glBegin(GL_POINTS);
   // glVertex3f(p2x, p2y, p2z);
    glEnd();
    glPopMatrix();
	}
}

void drawitems (void) 
{

    for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
    glTranslated(-positionxaxis[i + 1] * 30, 0, -positionzaxis[i + 1] * 30); //translate the items
	glPushMatrix();
    item.DrawItem();
	glPopMatrix();
    glPopMatrix();
	}
}

void drawobjects (void)

{
        for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
    
    glTranslated(-positionxaxis[i + 1] * 10, 0, -positionzaxis[i + 1] * 10); //translate the items
	glPushMatrix();
    object.DrawUFO();
	glPopMatrix();
    glPopMatrix();
	}
}



void cubepositions (void) { //set the positions of the cubes

    for (int i=0;i<10;i++)
    {
    positionz[i] = rand()%10 + 3;
    positionx[i] = rand()%10 + 3;
    }
}
//draw the cube
void cube (void) {
    for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
    
    glTranslated(-positionx[i + 1] * 10, 0, -positionz[i + 1] * 10); //translate the cube
	//glColor3f(2.0f,0.0,1.0f);
    // house
    glPushMatrix();
	glTranslatef(0,5,0);
    glutSolidCube(12);                 // building
    
    glTranslatef(0,5,0);
    glPushMatrix();                   // roof
    glRotatef(-90,1,0,0);
    glutSolidCone(10.5,10,16,19);
    glPopMatrix();

    glTranslatef(.75,.20,-.75);         
    glPushMatrix();                   // chimney
    glScalef(2,8,2);
    glutSolidCube(.25);
    glPopMatrix();
    glPopMatrix();

    glTranslatef(0,-.65,2);
  
    glPopMatrix();
    }
}
void init (void) {

    //enable LIGHT0, our Diffuse Light
	Itempositions();
	Enemypositions();
    cubepositions();
	CG->Init();
	
    //glEnable (GL_LIGHT0); //enable LIGHT0, our Diffuse Light
    //glEnable (GL_LIGHT1); //enable LIGHT1, our Ambient Light
    glEnable(GL_TEXTURE_2D);
    
	
     
   
	
}




void enable (void) {
    glEnable (GL_DEPTH_TEST); //enable the depth testing
    
   // glEnable (GL_COLOR_MATERIAL);
   // glShadeModel (GL_SMOOTH); //set the shader to smooth shader
    glEnable(GL_TEXTURE_2D);
}



void display (void) {

      //  CG->Prepare(CH->GetElapsedSeconds(1));
      //  CG->Render();

     glClearColor (0.0,0.0,0.0,1.0); //clear the screen to 
//blacks
  

     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
//clear the color buffer and the depth buffer
     // CG->Prepare(CH->GetElapsedSeconds(1));
      //  CG->Render();
     enable();
     

  //  glColor3f(1.0f, 0.0f, 0.0f);

	
    
 
     
     
    glLoadIdentity(); 

    GLfloat DiffuseLight[] = {dlr, dlg, dlb}; //set DiffuseLight
 
    GLfloat AmbientLight[] = {alr, alg, alb}; //set AmbientLight

    glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight); //change
 
    glLightfv (GL_LIGHT1, GL_AMBIENT, AmbientLight); //change
 
    GLfloat LightPosition[] = {lx, ly, lz, lw}; //set the 

    glLightfv (GL_LIGHT0, GL_POSITION, LightPosition); 

    textureLoader();
   
    glTranslatef(0.0f, 0.0f, -cRadius);
    glRotatef(xrot,1.0,0.0,0.0);
    
	//glColor3f(1.0f, 1.0f, 1.0f);
    
    

  
    

    if (Score > 100)
	{
      // output(0, 2, "You Win.");

	}
    glPushMatrix();
    //glutSolidCube(2); //Our character to follow*/
	glColor3f(1.0f,1.0f,1.0f);
	glTranslatef(0.4f,0.0f,0.0f);
    output(0, 2, "Kill the Robots.");
    DrawSnowMan();
	
	glPopMatrix();


	glPushMatrix();
   
    glTranslatef (-1.0, 0.0, 0.0);
  //  glRotatef ((GLfloat) weaponangle, x, y, z);
   // glTranslatef (1.0, 0.0, 0.0);
    glPushMatrix();
	glColor3f(1.0f,1.0f,1.0f);
    //glScalef (2.0, 0.4, 1.0);
    DrawWeapon();
    
    glPointSize(0.2);
    glPopMatrix();
	glPopMatrix();
    glColor3f(0.91f,0.76f,0.65f);

    glRotatef(yrot,0.0,1.0,0.0);  
    glTranslated(-xpos,0.0f,-zpos); 
  
    cube(); //call the cube drawing function
	glPushMatrix();
    glColor3f(0.8f,0.498039f,0.196078f);
  
    drawitems();
	
	glPopMatrix();

  
	glPushMatrix();
    
    drawEnemy();
    collision();
    pointz();
    glPopMatrix();

    glPushMatrix();
	glColor3f(0.90f,0.91f,0.98f);
    glRotatef(spin,0.0f, 1.0f,0.0f);
	drawobjects();
    spin += 0.05f;
    glPopMatrix();

	glPushMatrix();
	

    glScalef (2.0, 0.4, 1.0);
    DrawFloor();

   
//	CG->Prepare(CH->GetElapsedSeconds(1));
	//CG->Render();
	
    glPopMatrix();
    glutSwapBuffers(); //swap the buffers
	
    angle++; //increase the angle
}



void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport
 //to the current window specifications
    glMatrixMode (GL_PROJECTION); //set the matrix to projection
     
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 100.0); //set the perspective (angle of sight, width, height, , depth

    glMatrixMode (GL_MODELVIEW); //set the matrix back to model

}
void keyboard (unsigned char key, int x, int y) {
    if (key=='q')
    {
    xrot += 1;
    if (xrot >360) xrot -= 360;
    }
    if (key=='z')
    {
    xrot -= 1;
    if (xrot < -360) xrot += 360;
    }
    if (key=='w')
    {
    float xrotrad, yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xrotrad = (xrot / 180 * 3.141592654f); 
    xpos += float(sin(yrotrad));
    zpos -= float(cos(yrotrad));
    ypos -= float(sin(xrotrad));
    }
    if (key=='s')
    {
    float xrotrad, yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xrotrad = (xrot / 180 * 3.141592654f); 
    xpos -= float(sin(yrotrad));
    zpos += float(cos(yrotrad));
    ypos += float(sin(xrotrad));
    }
    if (key=='d')
    {
    float yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xpos += float(cos(yrotrad)) * 0.2;
    zpos += float(sin(yrotrad)) * 0.2;
    }
    if (key=='e')
	{
        weaponangle = (weaponangle + 10) % 360;
        frame = 0;
		bWeaponIsActive = true;
		glutPostRedisplay();
	}
    if (key=='a')
    {
    float yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xpos -= float(cos(yrotrad)) * 0.2;
    zpos -= float(sin(yrotrad)) * 0.2;
    }
    if (key==27)
    {
    exit(0);
    }
}

void DrawFloor(void) { 

	   
       glBindTexture(GL_TEXTURE_2D, theTexture[SNOW]);
       glTranslatef(0.0f,-3.0f,3.0f);

 glBegin(GL_QUADS);
       
        glTexCoord2f(1.0f,0.0f);
        //glColor3f(0.2f, 0.2f, 0.2f);
        glVertex3f(-200.0,-0.5, -200);
        glTexCoord2f(1.0f,1.0f);
       // glColor3f(0.4f, 0.4f, 0.4f);
        glVertex3f(-200.0,-0.5, 200.0);
        glTexCoord2f(0,1.0f);
       // glColor3f(0.6f, 0.6f, 0.6f);
        glVertex3f(200.0, -0.5, 200.0);
        glTexCoord2f(0,0);
       // glColor3f(0.8f, 0.8f, 0.8f);
        glVertex3f(200.0, -0.5, -200.0);        
    glEnd();

}

void mouseMovement(int x, int y) {
    int diffx=x-lastx; //check the difference between the 
//current x and the last x position
    int diffy=y-lasty; //check the difference between the 
//current y and the last y position
    lastx=x; //set lastx to the current x position
    lasty=y; //set lasty to the current y position
    xrot += (float) diffy; //set the xrot to xrot with the addition
 //of the difference in the y position
    yrot += (float) diffx;    //set the xrot to yrot with the addition
 //of the difference in the x position
}



int main (int argc, char **argv) {
    CH = new CHiResTimer;
	CG = new CGfxOpenGL;
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowSize (500, 500); 
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Snow Man Game"); 
    init (); 

	glEnable(GL_TEXTURE_2D);

 
    
    UpdateWeapon();
    
    glutDisplayFunc (display); 
    glutIdleFunc (display); 
    glutReshapeFunc (reshape);
    glutPassiveMotionFunc(mouseMovement); //check for mouse
    
    glutKeyboardFunc (keyboard); 
    glutMainLoop (); 
    return 0;
}

Open in new window

0
 
LVL 12

Expert Comment

by:satsumo
ID: 35184213
No, because you aren't setting the position arrays either.

Where do you want the two spheres to be in 3D space?  Given that p1radius and p2 radius are both 1, the distance between them must be greater than 2, otherwise they will collide.

If it dosen't matter just choose some numbers, p1 as (0, 0, 0) and p2 as (2, 2, 2) will not overlap.
0
 

Author Comment

by:tango2009
ID: 35184463
I want to draw a sphere around each one of the enemies. these are not drawn at random so could I use a printf statement to find the positions of the enemies and draw spheres around each one?


I also want a sphere around the weapon. I move the weapon around with the character does this mean that if the sphere is drawn in the same pushmatrix will it move aswell or do I need to add sphere movement seperatly?
0
 
LVL 12

Accepted Solution

by:
satsumo earned 125 total points
ID: 35184875
If you draw the sphere inside the same push matrix it will draw in the same place as the model.

This code draws a sphere as three circles, one each for x, y and z axis.  This is quite good for showing which way the sphere is facing and using lines means you can see what the sphere surrounds.

void DrawSphere (float radius)
{
    int numVert;
    float angle = 0.f;
    glBegin (GL_LINELOOP);

    for (numVert = 0; numVert < 20; ++numVert)
    {
        glVertex3f (sin (angle) * radius, cos (angle) * radius, 0.f);
        angle += PI / 10;
    }

    glEnd ();
    glBegin (GL_LINELOOP);

    for (numVert = 0; numVert < 20; ++numVert)
    {
        glVertex3f (sin (angle) * radius, 0.f, cos (angle) * radius);
        angle += PI / 10;
    }

    glEnd ();
    glBegin (GL_LINELOOP);

    for (numVert = 0; numVert < 20; ++numVert)
    {
        glVertex3f (0.f, sin (angle) * radius, cos (angle) * radius);
        angle += PI / 10;
    }

    glEnd ();
}

Open in new window

0
 

Author Comment

by:tango2009
ID: 35185444
Using your code above if I draw a sphere for the weapon and the enemies how would I check if the two intersect. Would I simply use an if statement that checked the positions of the spheres and checked if they were close enough for a collision.
0
 
LVL 12

Expert Comment

by:satsumo
ID: 35185621
The code you have at the moment does check collisions.  The problem is its not very flexible, you'd have to put the coordinates of any sphere you want to test into p1x p2x, p1y, p2y, p1z, p2z and all the spheres have to have a radius of one.  This is more useful.

typedef struct
{
    float x;
    float y;
    float z;
    float radius;
}
Sphere;

bool SphereColliide (Sphere *a, Sphere *b)
{
    float d = sqrt(((a->x - b->x) * (a->x - b->x)) + ((a->y - b->y) * (a->y - b->y)) 
+ ((a->z - b->z) * (a->z - b->z)));
    return d < (a->radius + b->radius);
}

void SphereDraw (Sphere *sph)
{
    int numVert;
    float angle = 0.f;
    glBegin (GL_LINELOOP);

    for (numVert = 0; numVert < 20; ++numVert)
    {
        glVertex3f (sin (angle) * sph->radius, cos (angle) * sph->radius, 0.f);
        angle += PI / 10;
    }

    glEnd ();
    glBegin (GL_LINELOOP);

    for (numVert = 0; numVert < 20; ++numVert)
    {
        glVertex3f (sin (angle) * sph->radius, 0.f, cos (angle) * sph->radius);
        angle += PI / 10;
    }

    glEnd ();
    glBegin (GL_LINELOOP);

    for (numVert = 0; numVert < 20; ++numVert)
    {
        glVertex3f (0.f, sin (angle) * sph->radius, cos (angle) * sph->radius);
        angle += PI / 10;
    }

    glEnd ();
}

Open in new window

This way you can setup some sphere data and collide and draw them in a flexible way.  Another problem is that you're rendering the sphere after some matrix has been applied, but not colliding them with the same matrix.
0
 

Author Comment

by:tango2009
ID: 35189573
In the above code you are using SphereDraw to draw the spheres a and b and using SphereCollide to check the distance between them. How would I draw one of the spheres in the enemy function for example like this?

void drawEnemy (void) // Draw our enemy
{
   
    for (int i=0;i<10 - 1;i++)
    {
     
    glPushMatrix();
   
    glTranslated(-positionxone[i + 1] * 10, 0, -positionzone[i + 1] * 10); //translate the enemies
      glPushMatrix();
      glTranslatef(0.0f,10.0f,0.0f);
    enemyangle = enemyangle + 1.0f;
    glRotatef(enemyangle, 0.0f, 1.0f, 0.0f);
    enemy.DrawEnemy();
      Sphere *a;
   

    //glVertex3f(p2x, p2y, p2z);
   // glBegin(GL_POINTS);
   // glVertex3f(p2x, p2y, p2z);
    glEnd();
    glPopMatrix();
      }
}
0
 
LVL 12

Expert Comment

by:satsumo
ID: 35189928
You would define enemy as a class or struct with a sphere as part of it.  When you render the enemy you also render the sphere.

class Enemy : public Sphere
{
    public:
        float angle;
        void Draw (void);
}

void Enemy::Draw (void) 
{    
    glPushMatrix();
    glTranslatef (x, y, z); // this is the x, y, z inherited from the Sphere
    angle = angle + 1.0f;
    glRotatef (angle, 0.0f, 1.0f, 0.0f);
    enemy.DrawEnemy();
    DrawSphere (this);
    glPopMatrix();
}

Open in new window

0
 

Author Comment

by:tango2009
ID: 35190989
I already have enemy defined as a class that is why when I draw the enemy I use enemy.DrawEnemy.

In my header I have this

#ifndef __ENEMY_H
#define __ENEMY_H

// constants for arm and leg movement states
const char BACKWARD_STATE = 0;
const char FORWARD_STATE  = 1;

// index constants for accessing arm and leg array data
const char LEFT  = 0;
const char RIGHT = 1;

class Enemy : public Sphere
{
private:
      Enemy *theEnemy;
      char legStates[2];      
      char armStates[2];

      float legAngles[2];
      float armAngles[2];


      // draws a unit cube
      void DrawCube(float xPos, float yPos, float zPos);

      // methods to draw the parts of the Enemy
      void DrawArm(float xPos, float yPos, float zPos);
      void DrawHead(float xPos, float yPos, float zPos);
      void DrawTorso(float xPos, float yPos, float zPos);
      void DrawLeg(float xPos, float yPos, float zPos);
      void DrawFoot(float xPos, float yPos, float zPos);

public:

      Enemy();
      virtual ~Enemy();
    void Draw (void);
      // draws the entire Enemy
      void DrawEnemy();
    void Render();
      // updates the Enemy data
      void Prepare(float dt);
};

#endif


I have this error below

'Sphere' : base class undefined

I am guessing this is because it doesn't know what sphere is. One more thing would it be better to have the drawsphere function in the enemy class which is below and then call them in the main when checking for collisions?


#ifdef _WINDOWS
#include <windows.h>
#endif

//#include <gl/gl.h>
#include <gl/glut.h>

#include "Enemy.h"

//float enemyangle = 0.0f;
float legAngle[2] = {0.0f, 0.0f};
float armAngle[2] = {0.0f, 0.0f};

Enemy::Enemy()
{
	armAngles[LEFT] = 0.0;
	armAngles[RIGHT] = 0.0;
	legAngles[LEFT] = 0.0;
	legAngles[RIGHT] = 0.0;

	armStates[LEFT] = FORWARD_STATE;
	armStates[RIGHT] = BACKWARD_STATE;

	legStates[LEFT] = FORWARD_STATE;
	legStates[RIGHT] = BACKWARD_STATE;
}

Enemy::~Enemy()
{
}

void Enemy::DrawCube(float xPos, float yPos, float zPos)
{
	glPushMatrix();
		glTranslatef(xPos, yPos, zPos);
		glBegin(GL_POLYGON);
			glVertex3f(0.0f, 0.0f, 0.0f);	// top face
			glVertex3f(0.0f, 0.0f, -1.0f);
			glVertex3f(-1.0f, 0.0f, -1.0f);
			glVertex3f(-1.0f, 0.0f, 0.0f);
			glVertex3f(0.0f, 0.0f, 0.0f);	// front face
			glVertex3f(-1.0f, 0.0f, 0.0f);
			glVertex3f(-1.0f, -1.0f, 0.0f);
			glVertex3f(0.0f, -1.0f, 0.0f);
			glVertex3f(0.0f, 0.0f, 0.0f);	// right face
			glVertex3f(0.0f, -1.0f, 0.0f);
			glVertex3f(0.0f, -1.0f, -1.0f);
			glVertex3f(0.0f, 0.0f, -1.0f);
			glVertex3f(-1.0f, 0.0f, 0.0f);	// left face
			glVertex3f(-1.0f, 0.0f, -1.0f);
			glVertex3f(-1.0f, -1.0f, -1.0f);
			glVertex3f(-1.0f, -1.0f, 0.0f);
			glVertex3f(0.0f, 0.0f, 0.0f);	// bottom face
			glVertex3f(0.0f, -1.0f, -1.0f);
			glVertex3f(-1.0f, -1.0f, -1.0f);
			glVertex3f(-1.0f, -1.0f, 0.0f);
			glVertex3f(0.0f, 0.0f, 0.0f);	// back face
			glVertex3f(-1.0f, 0.0f, -1.0f);
			glVertex3f(-1.0f, -1.0f, -1.0f);
			glVertex3f(0.0f, -1.0f, -1.0f);
		glEnd();
	glPopMatrix();
}

void Enemy::DrawArm(float xPos, float yPos, float zPos)
{
	glPushMatrix();
		glColor3f(1.0f, 0.0f, 0.0f);	// red
		glTranslatef(xPos, yPos, zPos);
		glScalef(1.0f, 4.0f, 1.0f);		// arm is a 1x4x1 cube
		DrawCube(0.0f, 0.0f, 0.0f);
	glPopMatrix();
}

void Enemy::DrawHead(float xPos, float yPos, float zPos)
{
	glPushMatrix();
		glColor3f(1.0f, 1.0f, 1.0f);	// white
		glTranslatef(xPos, yPos, zPos);
		glScalef(2.0f, 2.0f, 2.0f);		// head is a 2x2x2 cube
		DrawCube(0.0f, 0.0f, 0.0f);
	glPopMatrix();
}

void Enemy::DrawTorso(float xPos, float yPos, float zPos)
{
	glPushMatrix();
		glColor3f(0.0f, 0.0f, 1.0f);	// blue
		glTranslatef(xPos, yPos, zPos);
		glScalef(3.0f, 5.0f, 2.0f);		// torso is a 3x5x2 cube
		DrawCube(0.0f, 0.0f, 0.0f);
	glPopMatrix();
}

void Enemy::DrawLeg(float xPos, float yPos, float zPos)
{
	glPushMatrix();
		glTranslatef(xPos, yPos, zPos);
		
		// draw the foot
		glPushMatrix();
			glTranslatef(0.0f, -0.5f, 0.0f);
			DrawFoot(0.0f, -5.0f, 0.0f);
		glPopMatrix();		
		
		glScalef(1.0f, 5.0f, 1.0f);		// leg is a 1x5x1 cube
		glColor3f(1.0f, 1.0f, 0.0f);	// yellow
		DrawCube(0.0f, 0.0f, 0.0f);
	glPopMatrix();
}

void Enemy::DrawFoot(float xPos, float yPos, float zPos)
{
	glPushMatrix();
		glColor3f(1.0f, 1.0f, 1.0f);
		glTranslatef(xPos, yPos, zPos);
		glScalef(1.0f, 0.5f, 3.0f);
		DrawCube(0.0f, 0.0f, 0.0f);
	glPopMatrix();
}

void Enemy::DrawEnemy()
{
	glPushMatrix();	
		//glTranslatef(xPos, yPos, zPos);	// draw Enemy at desired coordinates

		// draw head and torso parts
		DrawHead(1.0f, 2.0f, 0.0f);		
		DrawTorso(1.5f, 0.0f, 0.0f);

		// move the left arm away from the torso and rotate it to give "walking" effect
		glPushMatrix();
			glTranslatef(0.0f, -0.5f, 0.0f);
			glRotatef(armAngles[LEFT], 1.0f, 0.0f, 0.0f);
			DrawArm(2.5f, 0.0f, -0.5f);
		glPopMatrix();

		// move the right arm away from the torso and rotate it to give "walking" effect
		glPushMatrix();
			glTranslatef(0.0f, -0.5f, 0.0f);
			glRotatef(armAngles[RIGHT], 1.0f, 0.0f, 0.0f);
			DrawArm(-1.5f, 0.0f, -0.5f);
		glPopMatrix();

		// move the left leg away from the torso and rotate it to give "walking" effect
		glPushMatrix();					
			glTranslatef(0.0f, -5.5f, 0.0f);
			glRotatef(legAngles[LEFT], 1.0f, 0.0f, 0.0f);
			DrawLeg(-0.5f, -5.0f, -0.5f);
            
		glPopMatrix();

		// move the right leg away from the torso and rotate it to give "walking" effect
		glPushMatrix();
			glTranslatef(0.0f, -0.5f, 0.0f);
			glRotatef(legAngles[RIGHT], 1.0f, 0.0f, 0.0f);
			DrawLeg(1.5f, -5.0f, -0.5f);
		glPopMatrix();
        
	glPopMatrix();	// pop back to original coordinate system
}

void Enemy::Prepare(float dt)
{
	// if leg is moving forward, increase angle, else decrease angle
	for (char side = 0; side < 2; side++)
	{
		// arms
		if (armStates[side] == FORWARD_STATE)
			armAngles[side] += 20.0f * dt;
		else
			armAngles[side] -= 20.0f * dt;

		// change state if exceeding angles
		if (armAngles[side] >= 15.0f)
			armStates[side] = BACKWARD_STATE;
		else if (armAngles[side] <= -15.0f)
			armStates[side] = FORWARD_STATE;

		// legs
		if (legStates[side] == FORWARD_STATE)
			legAngles[side] += 20.0f * dt;
		else
			legAngles[side] -= 20.0f * dt;

		// change state if exceeding angles
		if (legAngles[side] >= 15.0f)
			legStates[side] = BACKWARD_STATE;
		else if (legAngles[side] <= -15.0f)
			legStates[side] = FORWARD_STATE;		
	}

}
void Enemy:: Render()
{
        /*      Enable depth testing
        */
      //  glEnable(GL_DEPTH_TEST);

        /*      Heres our rendering. Clears the screen
                to black, clear the color and depth
                buffers, and reset our modelview matrix.
        */
      ///  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
      //  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       // glLoadIdentity();

        /*      Increase rotation angle counter
        */
        //enemyangle = enemyangle + 1.0f;

        /*      Reset after we have completed a circle
        */
       // if (enemyangle >= 360.0f)
       // {
       //         enemyangle = 0.0f;
       // }

        glPushMatrix();
                glLoadIdentity();

                /*      Move to 0,0,-30 , rotate the robot on
                        its y axis, draw the robot, and dispose
                        of the current matrix.
                */
                glTranslatef(0.0f, 5.0f, -30.0f);
               // glRotatef(enemyangle, 0.0f, 1.0f, 0.0f);
                DrawEnemy();
        glPopMatrix();

        glFlush();

        /*      Bring back buffer to foreground
        */
        
}

Open in new window

0
 

Author Comment

by:tango2009
ID: 35194945
I have set out my spheres and I am using an if statement to try and check for collisions like this below

if(d <= a->radius + b->radius)
      
      {
         printf("Collision");
       weaponangle = (weaponangle + 10) % 360;
      }
      else
      {

      }

is this correct because I cannot seem to make any collisions?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 16

Assisted Solution

by:George Tokas
George Tokas earned 250 total points
ID: 35198276
bool SphereColliide (Sphere *a, Sphere *b)
{
    float d = sqrt(((a->x - b->x) * (a->x - b->x)) + ((a->y - b->y) * (a->y - b->y))
+ ((a->z - b->z) * (a->z - b->z)));
    return d < (a->radius + b->radius);
}
Will this return the correct value??
You returning a float type casted to bool??
Suggestion:
bool SphereColliide (Sphere *a, Sphere *b)
{
    bool result = 0;//no collision
     float d = sqrt(((a->x - b->x) * (a->x - b->x)) + ((a->y - b->y) * (a->y - b->y))
+ ((a->z - b->z) * (a->z - b->z)));
    //return d < (a->radius + b->radius);
  if(d <= (a->radius + b->radius)){result = 1;}//collision
  return result;
}
This way checking for collision. I am assuming the original code works because looks like so...

George Tokas.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35200733
@gtokas,
Just a suggestion that you can avoid expensive square roots. Assuming your code is correct, the following modification will be a significant performance improvement:
   float dsquared = (a->x - b->x) * (a->x - b->x)) + ((a->y - b->y) * (a->y - b->y)) + ((a->z - b->z) * (a->z - b->z);
   return dsquared  < (a->radius + b->radius) * (a->radius + b->radius);
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 35201178
@phoffric
Thanks for the suggestion..:-)
But the code isn't mine and I'm not using this way with Direct3D...
I like more simple ways depend in the case I have to deal with....

George Tokas.
0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 125 total points
ID: 35202049
Ok. Then..

@tango2009,
For performance improvements, try to avoid the sqrt (especially for game programming). It is faster to square a number x*x than take the sqrt of a number. So, use:

   float dsquared = (a->x - b->x) * (a->x - b->x)) + ((a->y - b->y) * (a->y - b->y)) + ((a->z - b->z) * (a->z - b->z);
   return dsquared  < (a->radius + b->radius) * (a->radius + b->radius);

rather than:

    float d = sqrt(((a->x - b->x) * (a->x - b->x)) + ((a->y - b->y) * (a->y - b->y)) + ((a->z - b->z) * (a->z - b->z)));
    return d < (a->radius + b->radius);
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35202126
Off topic comment. I noticed in previous question you were using C++. If using C++ for this project, then I recommend that you use a math Vector3D class (and likely a Matrix class that can be used as a Vector3D class). Then, to take the difference between two vectors, you would simply write:
    Vector3D deltaV = V2 - V1;
and then you could define an length() function to get the length of a vector.

Then the distance between two points (represented as vectors) might look like:
    unsigned int distance = (V2 - V1).length();

or, for performance, something like:
    unsigned int distanceSquared = (V2 - V1).lengthSquared();  // no sqrt() used here.

I think this is much easier on the eyes, and should be easier to write the code.
0
 
LVL 16

Assisted Solution

by:George Tokas
George Tokas earned 250 total points
ID: 35205575
@phoffric
No way off topic suggestion!!!
That was and what I meant about Direct3D...
I am using D3DXVECTOR3 for myself...
But there are simpler ways if you don't want to use vectors, especially when using a class that don't has that kind of members for - lets say - simplicity...
Anyway you covered the subject fully..:-)

George Tokas.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 35206772
@George,
Ahh, as having never used D3DXVECTOR3, I think I missed your point. But glad we're on the same page. Thanks for the clarification.
   Paul
0
 

Author Comment

by:tango2009
ID: 35216587
Thanks guys for the responses. I have drawn out the spheres in all of the right places around the enemies. I know this because I have simply drawn a wire cube in the SphereDraw function. It doesn't register a colllision. I am using the code from qtokas.

This part

bool SphereColliide (Sphere *a, Sphere *b)
{
    bool result = 0;//no collision
     float d = sqrt(((a->x - b->x) * (a->x - b->x)) + ((a->y - b->y) * (a->y - b->y))
+ ((a->z - b->z) * (a->z - b->z)));
    //return d < (a->radius + b->radius);
  if(d <= (a->radius + b->radius)){result = 1;}//collision
  return result;
}

It surely must be a problem with this part of the code most likely what float d is eqaul to. Can anyone see why this is not registering a collision.
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 35219884
Since you are using my (modificated) code I think that I am the responsible person to reply...
Place a breakpoint at if(d <=....
Place your spheres in position where they collide...
Report back the value of d along with the 2 sphere radius...
The meaning of:
if(d <= (a->radius + b->radius)){
is:
If the value of d is less or equal to the sum of the 2 sphere radius then the spheres are in contact (the equal part) or "merged" (the less part)...
But lets see if it works first...

George Tokas.
0
 

Author Comment

by:tango2009
ID: 35227234
When I am trying to set a breakpoint, this function doesn't have a hit count so I cannot get the values from it. I have noticed that I am not calling this function in the main or display function. Is this the problem and if so how can I call it in the display functon?
0
 
LVL 16

Expert Comment

by:George Tokas
ID: 35230511
Yes, if you don't call trhe function you will not get a return value...:-)
Don't worry I made the same too many times...:-)
Check out if the function works because with floats we can nver be sure...
If there is any problem there are some workarounds...

George Tokas.
0
 

Author Comment

by:tango2009
ID: 35236900
In the display function how do I have to call this function. Does it need to be in the same pushmatrix as the shapes I want to test for collisions on?

Also what values do I need to use in the function call? I thought I could like this

 SphereCollide(ball,circle);

ball and circle being the names of teh spheres I want to test collision with but this doesn't work.



0
 
LVL 16

Expert Comment

by:George Tokas
ID: 35239483
Sphere a has radius and coordinates in space  x, y, z .
Same as sphere b.
So since I assume there are instances of the same base object ANYWERE in the code you can read radius, x, y, z...
At least this way I am working - I mean instance of 3D object...
So you can call the function from wherever apropriate...
Example:
Spherea->setposition();
Sphereb->setposition();
bool collision = 0;
collision = SphereCollide(Spherea,Sphereb);// 1 returns collision
Collision detection doesn't has to do with rendering or whatever just after position change or (going to be) updated you are checking for collision...

George Tokas.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…
In addition to being a great web-based presentation tool, Prezi also makes it easy to save your presentation as a PDF to share with others as well. Learn how in this tutorial. Select the share icon from the top menu in your Prezi editor: Select "D…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now