- Ball::Ball(GLdouble x, GLdouble y, GLdouble z, GLdouble velX, GLdouble velY, GLdouble velZ, GLdouble accelX, GLdouble accelY, GLdouble accelZ, int ballIndex, GLuint textureObject):x(x),y(y),z(z),velX(velX),velY(velY),velZ(velZ),accelX(accelX),accelY(accelY),accelZ(accelZ),ballIndex(ballIndex),textureObject(textureObject)
{
setupTexture();
radius = BALL_SIZE;
collided = false;
}
Ball::Ball(GLdouble x, GLdouble y, GLdouble z, int ballIndex, GLuint textureObject):x(x),y(y),z(z),ballIndex(ballIndex),textureObject(textureObject)
{
init();
setupTexture();
}
void Ball::init()
{
velX=0;
velY=0;
velZ=0;
accelX=0;
accelY=0;
accelZ=0;
rotateDeg = 0;
rotX = 1;
rotY = 0;
rotZ = 0;
angularVelocity=0;
angularAcceleration=0;
radius = BALL_SIZE;
collided = false;
}
//check collision with table
bool Ball::checkCollision(GLdouble planex1, GLdouble planex2,GLdouble planez1,GLdouble planez2,double secSinceLastTime)
{
bool collisionFlag = false;
M3DVector3d myMoveVec = {velX * secSinceLastTime,velY * secSinceLastTime,velZ * secSinceLastTime};
if (x-radius+myMoveVec[0] < planex1)
{
velX = -velX;
x=planex1+radius;
collisionFlag = true;
}
else if (x+radius+myMoveVec[0] > planex2)
{
velX = -velX;
x=planex2-radius;
collisionFlag = true;
}
if (z-radius+myMoveVec[2] < planez2)
{
velZ = -velZ;
z=planez2 + radius;
collisionFlag = true;
}
else if (z+radius+myMoveVec[2] > planez1)
{
velZ = -velZ;
z=planez1 - radius;
collisionFlag = true;
}
return false;
}
double magnitudeFromComponents3D(float x,float y,float z)
{
return sqrt(pow(x,2)+pow(y,2)+pow(z,2));
}
double radiansToDegrees(double A)
{
return A*(180 / PI);
}
double degreesToRadians(double A)
{
return A*0.0174532925;
}
double angleBetweenVectors(float Vx, float Vy, float Vz, float Bx, float By, float Bz)
{
double topLine = (Vx*Bx) + (Vy*By) + (Vz*Bz);
double bottomLine = magnitudeFromComponents3D(Vx,Vy,Vz)*magnitudeFromComponents3D(Bx,By,Bz);
return radiansToDegrees(acos(topLine/bottomLine));
}
double sec(double theta)
{
return 1/radiansToDegrees(cos(theta));
}
float applyFrictionTo(float pre)
{
float k = 0.03; // coefficient of friction
return (pre*(1-exp(-k)))/k; // t = 1
}
//check collision with another ball
bool Ball::checkCollision(Ball *otherBall,double secSinceLastTime)
{
if(collided)
{
return true;
}
if(otherBall->collided)
{
if(otherBall->collidedBall->ballIndex == this->ballIndex)
{
return true;
}
}
return true;
}
void Ball::collide(Ball *otherBall,double secSinceLastTime)
{
if((pow((x-otherBall ->x),2)+pow((z-otherBall ->z),2))<0.015)
{
float bx = otherBall ->x-x;
float by = otherBall ->y-y;
float bz = otherBall ->z-z;
float mag = magnitudeFromComponents3D(bx,by,bz);
// get unit normal
float ubx = bx/mag;
float ubz = bz/mag;
// get unit tangent
float utx = -ubz;
float utz = ubx;
// project velocities onto normal and tangent
float v1n = ubx*velX+ubz*velZ;
float v1tA = utx*velX+utz*velZ;
float v2n = ubx*otherBall ->velX+ubz*otherBall->velZ;
float v2tA = utx*otherBall->velX+utz*otherBall->velZ;
float v1nA = (v1n*(1-1)+2*v2n)/2;
float v2nA = (v2n*(1-1)+2*v1n)/2;
float v1nx = ubx*v1nA;
float v1nz = ubz*v1nA;
float v1tx = utx*v1tA;
float v1tz = utz*v1tA;
float v2nx = ubx*v2nA;
float v2nz = ubz*v2nA;
float v2tx = utx*v2tA;
float v2tz = utz*v2tA;
velX=v1nx+v1tx;
velZ=v1nz+v1tz;
otherBall->velX=v2nx+v2tx;
otherBall->velZ=v2nz+v2tz;
}
}
I am really new to opengl and c++, I was working on a billiards game. I have everything working except for the collisions. I needed to try to finish up my CheckCollision method also double checking my collide method would be appreciated as well. I can't figure out how to compare to balls and then find there distance and then calculate there speed before and after the collision. I have some of the ideas down but I am lost on how I can get to where I need to go. I've just been reading online articles and so forth trying to figure it all out. Any suggestions or help would be greatly appreciated.
1