Link to home
Start Free TrialLog in
Avatar of tango2009
tango2009

asked on

Opengl collision detection

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

Avatar of Member_2_5069294
Member_2_5069294

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.
Avatar of tango2009

ASKER

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.
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

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.
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?
ASKER CERTIFIED SOLUTION
Avatar of Member_2_5069294
Member_2_5069294

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
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.
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();
      }
}
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

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

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?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of phoffric
@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);
@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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@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
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.
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.
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?
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.
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.



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.