Jump to content
  • Advertisement
Sign in to follow this  
mysterio123

bounding sphere collision detection problem

This topic is 2294 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So i'm stuck on my coding because im having some bugs with the collision detection. When the player sphere isn't even near the other spheres, the sphere still had an reaction. I've tried changing the collision detection part of the code but it still gives me the old bugs! Here's my code.

main.cpp

#include <math.h>
#include "freeglut.h"
#include "loadTGA.h"
#include "mmenu.h"
#include "timer.h"
#include "collide.h"
#include <iostream>
#include <sstream>
#include <string>
#include <time.h>
TextureImage texture[10];
TextureImage mainmenu[10];
#define movespeed 0.5f
#define mainm 1
#define ingame 2
float limit = 1000;
mmenu mmenu;
timer *Timer;
collide collision;
int score = 0;
float bx;
float bz;
float bx1;
float bz1;
float bx2;
float bz2;
float bx3;
float bz3;
float bx4;
float bz4;
float bx5;
float bz5;
float bx6;
float bz6;
float bx7;
float bz7;
float bx8;
float bz8;
float bx9;
float bz9;
int gamemode = mainm;
enum {
LEFT = 0,
FRONT,
RIGHT,
BACK,
TOP,
BOTTOM,
};
typedef struct {
bool mLButtonUp;
bool mRButtonUp;
int mX, mY;
} SMouse;
typedef struct {
float mEyeX, mEyeY, mEyeZ;
float mLookX, mLookY, mLookZ;
float mUpX, mUpY, mUpZ;
float mPitch, mRoll, mYaw;
} SCamera;
SCamera camera;
SMouse mouse;

bool keys[256];
string IntToString( int n )
{
ostringstream s;
s << n;
return s.str();
}
void renderCharacters (float posX, float posY, void *font, string s)
{
for (int i = 0; i < s.length(); i++)
{
glRasterPos2f (posX, posY);
glutBitmapCharacter (font, s.at(i));
posX += 15.8;
}
}
void init (void) {
glClearColor (0.0, 0.0, 0.0, 0.0); // set background colour to black
camera.mEyeX = 0;
camera.mEyeY = 0;
camera.mEyeZ = 0;
camera.mYaw = 180.0/180 * 3.142;
camera.mPitch = 0;
camera.mLookX = sin (camera.mYaw) * 5;
camera.mLookZ = cos (camera.mYaw) * 5;
camera.mLookY = camera.mPitch;
camera.mUpX = 0;
camera.mUpY = 1;
camera.mUpZ = 0;
Timer = new timer();
bx = rand() % 800 + - 800;
bz = rand() % 800 + - 800;
bx1 = rand() % 800 + - 800;
bz1 = rand() % 800 + - 800;
bx2 = rand() % 800 + - 800;
bz2 = rand() % 800 + - 800;
bx3 = rand() % 800 + - 800;
bz3 = rand() % 800 + - 800;
bx4 = rand() % 800 + - 800;
bz4 = rand() % 800 + - 800;
bx5 = rand() % 800 + - 800;
bz5 = rand() % 800 + - 800;
bx6 = rand() % 800 + - 800;
bz6 = rand() % 800 + - 800;
bx7 = rand() % 800 + - 800;
bz7 = rand() % 800 + - 800;
bx8 = rand() % 800 + - 800;
bz8 = rand() % 800 + - 800;
bx9 = rand() % 800 + - 800;
bz9 = rand() % 800 + - 800;
glEnable (GL_TEXTURE_2D);
loadTGA (&amp;texture

, "Images/left.tga");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
loadTGA (&amp;texture[FRONT], "Images/left.tga");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
loadTGA (&amp;texture

, "Images/left.tga");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

loadTGA (&amp;texture[BACK], "Images/left.tga");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
loadTGA (&amp;texture[TOP], "Images/left.tga");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
loadTGA (&amp;texture[BOTTOM], "Images/floor.tga");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
loadTGA( &amp;mainmenu[ 0 ], "Images/mstart.tga");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
loadTGA( &amp;mainmenu[ 1 ], "Images/mexit.tga");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable (GL_DEPTH_TEST);
glEnable(GL_VERTEX_ARRAY);
glShadeModel (GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (50.0, 1.33, 45.0, 5000.0);
glMatrixMode (GL_MODELVIEW);
}
void ccollision(){
if(collision.collision(bx, bz, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz = 100000;
score++;
}
else if(collision.collision(bx1, bz1, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz1 = 100000;
score++;
}
else if(collision.collision(bx2, bz2, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz2 = 100000;
score++;
}
else if(collision.collision(bx3, bz3, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz3 = 100000;
score++;
}
else if(collision.collision(bx4, bz4, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz4 = 100000;
score++;
}
else if(collision.collision(bx5, bz5, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz5 = 100000;
score++;
}
else if(collision.collision(bx6, bz6, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz6 = 100000;
score++;
}
else if(collision.collision(bx7, bz7, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz7 = 100000;
score++;
}
else if(collision.collision(bx8, bz8, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz8 = 100000;
score++;
}
else if(collision.collision(bx9, bz9, 50, camera.mEyeX,camera.mEyeZ+200, 50) == true)
{
bz9 = 100000;
score++;
}
}
void Update(){
if(gamemode == ingame){
if ((keys['a'] == true) || (keys['A'] == true))
{
if(camera.mEyeX + (movespeed * camera.mLookZ) < limit -100 &amp;&amp; camera.mEyeX + (movespeed * camera.mLookZ) > -limit+100)
camera.mEyeX += camera.mLookZ * movespeed;
if(camera.mEyeZ - (movespeed * camera.mLookX) < limit-100 &amp;&amp; camera.mEyeZ - (movespeed * camera.mLookX) > -limit+100)
camera.mEyeZ -= camera.mLookX * movespeed;
}
if ((keys['d'] == true) || (keys['D'] == true))
{
if(camera.mEyeX - (movespeed * camera.mLookZ) < limit-100 &amp;&amp; camera.mEyeX - (movespeed * camera.mLookZ) > -limit+100)
camera.mEyeX -= camera.mLookZ * movespeed;
if(camera.mEyeZ + (movespeed * camera.mLookX) < limit-100 &amp;&amp; camera.mEyeZ + (movespeed * camera.mLookX) > -limit+100)
camera.mEyeZ += camera.mLookX * movespeed;
}
if ((keys['w'] == true) || (keys['W'] == true))
{
if(camera.mEyeX + (movespeed * camera.mLookX) < limit-100 &amp;&amp; camera.mEyeX + (movespeed * camera.mLookX) > -limit+100)
camera.mEyeX += camera.mLookX * movespeed;
if(camera.mEyeZ + (movespeed * camera.mLookZ) < limit-100 &amp;&amp; camera.mEyeZ + (movespeed * camera.mLookZ) > -limit+100)
camera.mEyeZ += camera.mLookZ * movespeed;
}
if ((keys['s'] == true) || (keys['S'] == true))
{
if(camera.mEyeX - (movespeed * camera.mLookX) < limit-100 &amp;&amp; camera.mEyeX - (movespeed * camera.mLookX) > -limit+100)
camera.mEyeX -= camera.mLookX * movespeed;
if(camera.mEyeZ - (movespeed * camera.mLookZ) < limit-100 &amp;&amp; camera.mEyeZ - (movespeed * camera.mLookZ) > -limit+100)
camera.mEyeZ -= camera.mLookZ * movespeed;
}
Timer->UpdateTime();
}
}
void rescale (GLsizei w, GLsizei h) {
glViewport (0, 0, w, h);
}
void keyboard (unsigned char key, int x, int y)
{
keys[key] = true;
}
void keyboardUp (unsigned char key, int x, int y)
{
keys[key] = false;
}

void onMouseClick (int button, int state, int x, int y) {
if (gamemode == mainm) {
if (state == GLUT_DOWN) {
switch ( button ) {
case GLUT_LEFT_BUTTON :
if (x <= 525 &amp;&amp; x >= 275 &amp;&amp; y >= 250 &amp;&amp; y <= 300){ // Start button
gamemode = ingame;
}
if (x <= 525 &amp;&amp; x >= 275 &amp;&amp; y >= 310 &amp;&amp; y <= 360){ // exit button
glutLeaveMainLoop();
}
break;
case GLUT_RIGHT_BUTTON : break;
case GLUT_MIDDLE_BUTTON : break;
}
}
}
else if (gamemode == ingame){
if (state == GLUT_DOWN) {
switch ( button ) {
case GLUT_LEFT_BUTTON : break;
case GLUT_RIGHT_BUTTON : break;
case GLUT_MIDDLE_BUTTON : break;
}
}
}
}
void onMouseMove (int x, int y) {
if (gamemode == ingame){
if (!mouse.mLButtonUp) {
int deltax = (x - mouse.mX) * 5;
int deltay = y - mouse.mY;
camera.mYaw -= ((deltax/360.0) * 3.142) * 0.1;
camera.mPitch -= deltay * 0.1;
mouse.mX = x;
mouse.mY = y;
if (camera.mYaw < -3.142 * 2) camera.mYaw += 3.142 * 2;
if (camera.mYaw > 3.142 * 2) camera.mYaw -= 3.142 * 2;
camera.mLookX = sin (camera.mYaw) * 5;
camera.mLookY = camera.mPitch;
camera.mLookZ = cos (camera.mYaw) * 5;
}
}
}
void world (void) {
glEnable(GL_TEXTURE_2D);
//Left
glBindTexture(GL_TEXTURE_2D,texture

.id);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(-limit,-limit,-limit); //Upper Left
glTexCoord2f(0,1); glVertex3f(-limit,limit,-limit); //Bottom Left
glTexCoord2f(1,1); glVertex3f(-limit,limit,limit); //Bottom Left Depth
glTexCoord2f(1,0); glVertex3f(-limit,-limit,limit); //Upper Left Depth
glEnd();
//Right
glBindTexture(GL_TEXTURE_2D,texture

.id);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(limit,-limit,limit); //Upper Right Depth
glTexCoord2f(0,1); glVertex3f(limit,limit,limit); //Bottom Right Depth
glTexCoord2f(1,1); glVertex3f(limit,limit,-limit); //Bottom Right
glTexCoord2f(1,0); glVertex3f(limit,-limit,-limit); //Upper Right
glEnd();
//Back
glBindTexture(GL_TEXTURE_2D,texture[BACK].id);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(-limit,-limit,limit); //Upper Right
glTexCoord2f(0,1); glVertex3f(-limit,limit,limit); //Bottom Right
glTexCoord2f(1,1); glVertex3f(limit,limit,limit); //Bottom Left
glTexCoord2f(1,0); glVertex3f(limit,-limit,limit); //Upper Left
glEnd();


//Front
glBindTexture(GL_TEXTURE_2D,texture[FRONT].id);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(limit,-limit,-limit); //Upper Left Depth
glTexCoord2f(0,1); glVertex3f(limit,limit,-limit); //Bottom Left Depth
glTexCoord2f(1,1); glVertex3f(-limit,limit,-limit); //Bottom Right Depth
glTexCoord2f(1,0); glVertex3f(-limit,-limit,-limit); //Upper Right Depth
glEnd();

//Top
glRotatef(-90,0,1,0);
glBindTexture(GL_TEXTURE_2D,texture[TOP].id);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(-limit,limit,limit); //Upper Right Depth
glTexCoord2f(0,1); glVertex3f(-limit,limit,-limit); //Upper Right
glTexCoord2f(1,1); glVertex3f(limit,limit,-limit); //Upper Left
glTexCoord2f(1,0); glVertex3f(limit,limit,limit); //Upper Left Depth
glEnd();
//Bottom
glBindTexture(GL_TEXTURE_2D,texture[BOTTOM].id);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(limit,-limit,limit); //Bottom Left Depth
glTexCoord2f(0,1); glVertex3f(limit,-limit,-limit); //Bottom Left
glTexCoord2f(1,1); glVertex3f(-limit,-limit,-limit); //Bottom Right
glTexCoord2f(1,0); glVertex3f(-limit,-limit,limit); //Bottom Right Depth
glEnd();
glDisable(GL_TEXTURE_2D);
}
void drawsphere(void){
glColor3f(1,0,0);
glutSolidSphere(50,50,50);
glColor3f(1,1,1);
}
void drawpsphere(void){
glColor3f(1,1,0);
glutSolidSphere(50,50,50);
glColor3f(1,1,1);
}
void drawall (void) {
glPushMatrix();
world();
glPushMatrix();
glTranslatef(bx,-500,bz);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx1,-500,bz1);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx2,-500,bz2);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx3,-500,bz3);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx4,-500,bz4);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx5,-500,bz5);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx6,-500,bz6);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx7,-500,bz7);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx8,-500,bz8);
drawsphere();
glPopMatrix();
glPushMatrix();
glTranslatef(bx9,-500,bz9);
drawsphere();
glPopMatrix();
glPopMatrix();
glPushMatrix();
glTranslatef(camera.mEyeX,camera.mEyeY-500,camera.mEyeZ+200);
drawpsphere();
glPopMatrix();
glPushMatrix();
mmenu.orthogonalStart ();
string s = "Time Left: " + IntToString(30-Timer->getTime());
renderCharacters(275,20,GLUT_BITMAP_TIMES_ROMAN_24,s.c_str());
string sc = "Score : " + IntToString(score);
renderCharacters(300,580,GLUT_BITMAP_TIMES_ROMAN_24,sc.c_str());
mmenu.orthogonalEnd ();
glPopMatrix();
}
void doMainLoop (void) {
Update();
}
void MyDisplay (void) {
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
gluLookAt (camera.mEyeX, camera.mEyeY, camera.mEyeZ,
camera.mEyeX + camera.mLookX, camera.mEyeY + camera.mLookY, camera.mEyeZ + camera.mLookZ,
camera.mUpX, camera.mUpY, camera.mUpZ);
if(gamemode == mainm){
mmenu.orthogonalStart ();
mmenu.mstart();
mmenu.mexit();
mmenu.orthogonalEnd ();
}else if(gamemode == ingame)
{
drawall();
}
ccollision();
doMainLoop();
glutSwapBuffers ();
glutPostRedisplay ();
}
void main (int argc, char * argv[]) {
glutInit (&amp;argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (800, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Very fun game");
init();
glutDisplayFunc (MyDisplay);
glutReshapeFunc (rescale);
glutMouseFunc (onMouseClick);
glutMotionFunc (onMouseMove);

for (int i=0; i<256;i++)
{
keys = false;
}
glutKeyboardFunc (keyboard);
glutKeyboardUpFunc (keyboardUp);

glutMainLoop ();
}


collide.h
#include <iostream>
#include <math.h>
using namespace std;
class collide{
private:
float x1;
float z1;
float radius1;
float x2;
float z2;
float radius2;
float distance;
float distx;
float distz;
public:
bool collision (float x1, float z1, float radius1, float x2, float z2, float radius2);
};


collide.cpp


#include "collide.h"
bool collide::collision(float x1, float z1, float radius1, float x2, float z2, float radius2)
{
/*distance = sqrt(((x1 - x2) * (x1 - x2)) + ((z1 - z2) * (z1 - z2)));*/
distx = x1 - x2;
distz = z1 - z2;
distance = sqrt((distx * distx) + (distz * distz));
if (distance < (radius1 + radius2))
{
return true;
}
else
{
return false;
}

}


As you can see there's nothing wrong with the collision code at all!! but i still have no idea why its not working as it should!


EDIT: I've finally solved it!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Edited by crabcorer00lz

Share this post


Link to post
Share on other sites
Advertisement
The simplest possible way to do bounding-sphere test is to measure the (squared) distance between the two objects in question and to compare the result with the (squared again) sum of their radii. The reason we use the squared distances is to avoid the costly square-root calculation. The code will look something like this:

bool collide::collision(float x1, float z1, float radius1, float x2, float z2, float radius2)
{
float vecx = x1 - x2;
float vecy = y1 - y2;
float vecz = z1 - z2
float dist = vecx * vecx + vecy * vecy + vecz * vecz;
float minDist = radius1 - radius2;
return dist <= minDist * minDist;
}

Keep in mind that if your spheres are moving too fast they will pass through each other. Edited by hentailoli

Share this post


Link to post
Share on other sites

The simplest possible way to do bounding-sphere test is to measure the (squared) distance between the two objects in question and to compare the result with the (squared again) sum of their radii. The reason we use the squared distances is to avoid the costly square-root calculation. The code will look something like this:

bool collide::collision(float x1, float z1, float radius1, float x2, float z2, float radius2)
{
float vecx = x1 - x2;
float vecy = y1 - y2;
float vecz = z1 - z2
float dist = vecx * vecx + vecy * vecy + vecz * vecz;
float minDist = radius1 - radius2;
return dist <= minDist * minDist;
}

Keep in mind that if your spheres are moving too fast they will pass through each other.


moving too fast. that explains it too. ill give the code a try and see what happens!

Share this post


Link to post
Share on other sites

[quote name='hentailoli' timestamp='1345647831' post='4972223']
The simplest possible way to do bounding-sphere test is to measure the (squared) distance between the two objects in question and to compare the result with the (squared again) sum of their radii. The reason we use the squared distances is to avoid the costly square-root calculation. The code will look something like this:

bool collide::collision(float x1, float z1, float radius1, float x2, float z2, float radius2)
{
float vecx = x1 - x2;
float vecy = y1 - y2;
float vecz = z1 - z2
float dist = vecx * vecx + vecy * vecy + vecz * vecz;
float minDist = radius1 - radius2;
return dist <= minDist * minDist;
}

Keep in mind that if your spheres are moving too fast they will pass through each other.


moving too fast. that explains it too. ill give the code a try and see what happens!
[/quote]

okay ive tried it but its still not working! same bug i had with the previous code!! anyway isnt minDist supposed to be minDist = radius1 + radius2?

Share this post


Link to post
Share on other sites
could it be because there are some spheres that are on the negative axis?

EDIT: No it wasn't. im very stuck on this.

EDIT NO.2: the collision only works when the other sphere are on the 0 axis. Im having a huge headache trying to solve this major bug before i can proceed Edited by crabcorer00lz

Share this post


Link to post
Share on other sites
Saying it doesn't work doesn't say much. Have you made a hard coded case.
collision(0, 0,1, .5,0, 1);

and checked what numbers you get?

Share this post


Link to post
Share on other sites

Saying it doesn't work doesn't say much. Have you made a hard coded case.
collision(0, 0,1, .5,0, 1);

and checked what numbers you get?


distance i got was 0.25. its correct right?

Share this post


Link to post
Share on other sites
Here is an article about sphere-sphere intersection test. Check it out if you want to understand why the following code will work even for fast moving spheres:
http://www.gamedev.n...detection-r1234


BOOL bSphereTest(CObject3D* obj1, CObject3D* obj2)
{
//Initialize the return value
*t = 0.0f;
// Relative velocity
D3DVECTOR dv = obj2->prVelocity - obj1->prVelocity;
// Relative position
D3DVECTOR dp = obj2->prPosition - obj1->prPosition;
//Minimal distance squared
float r = obj1->fRadius + obj2->fRadius;
//dP^2-r^2
float pp = dp.x * dp.x + dp.y * dp.y + dp.z * dp.z - r*r;
//(1)Check if the spheres are already intersecting
if ( pp < 0 ) return true;
//dP*dV
float pv = dp.x * dv.x + dp.y * dv.y + dp.z * dv.z;
//(2)Check if the spheres are moving away from each other
if ( pv >= 0 ) return false;
//dV^2
float vv = dv.x * dv.x + dv.y * dv.y + dv.z * dv.z;
//(3)Check if the spheres can intersect within 1 frame
if ( (pv + vv) <= 0 && (vv + 2 * pv + pp) >= 0 ) return false;
//tmin = -dP*dV/dV*2
//the time when the distance between the spheres is minimal
float tmin = -pv/vv;
//Discriminant/(4*dV^2) = -(dp^2-r^2+dP*dV*tmin)
return ( pp + pv * tmin > 0 );
}
Edited by hentailoli

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!