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();
}
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;
}
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.
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.0 f);
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.
for (int i=0;i<10 - 1;i++)
{
glPushMatrix();
glTranslated(-positionxone
glPushMatrix();
glTranslatef(0.0f,8.0f,0.0
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.
ASKER
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.
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;
}
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.
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.
ASKER
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?
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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 ();
}
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.
ASKER
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();
}
}
void drawEnemy (void) // Draw our enemy
{
for (int i=0;i<10 - 1;i++)
{
glPushMatrix();
glTranslated(-positionxone
glPushMatrix();
glTranslatef(0.0f,10.0f,0.
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();
}
ASKER
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?
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
*/
}
ASKER
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?
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
@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);
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
@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
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
ASKER
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.
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.
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.
ASKER
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.
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.
ASKER
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.
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,Sphe reb);// 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.
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,Sphe
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.