Original Post
Ok, here is how thinks are right now... I'm writing this game, a cover on Pong, SuperPong, and it MUST be ready on wednesday, and my program is almost ready. But one thing remains: the collision detection!
I'm using a plane class and a vector class from the book "OpenGL Game Developing". And it should work, because it works in a hockey demo demonstrated in the same book.
So, the problem is this: One of my balls(no not those balls) in SuperPong is not bouncing correct.
I have set one of my gamefield walls at x=50(it's a vertical one). And the ball doesn't even bounce back there, it just continues in the same direction.
The mystic part is that it eventually bounces back, but the plane seems to be at x=80 or something. And then on the way back from the mystic wall the program crashes when the ball reaches origo. The debugger says it's a Stack Overflow error, and complains about the vector class.
I know it is a hard issue, but please guys I need your help with this one! Really!
Here is the vector class:
#ifndef __VECTOR_H
#define __VECTOR_H
#include <math.h>
/*
VECTOR.H
scalar_t
CVector class
OpenGL Game Programming
by Kevin Hawkins and Dave Astle
Some operators of the CVector class based on
operators of the CVector class by Bas Kuenen.
Copyright (c) 2000 Bas Kuenen. All Rights Reserved.
homepage: baskuenen.cfxweb.net
*/
typedef float scalar_t;
class CVector
{
public:
scalar_t x;
scalar_t y;
scalar_t z; // x,y,z coordinates
public:
CVector(scalar_t a = 0, scalar_t b = 0, scalar_t c = 0) : x(a), y(b), z(c) {}
CVector(const CVector &vec) : x(vec.x), y(vec.y), z(vec.z) {}
// vector assignment
const CVector &operator=(const CVector &vec)
{
x = vec.x;
y = vec.y;
z = vec.z;
return *this;
}
// vecector equality
const bool operator==(const CVector &vec) const
{
return ((x == vec.x) && (y == vec.y) && (z == vec.z));
}
// vecector inequality
const bool operator!=(const CVector &vec) const
{
return !(*this == vec);
}
// vector add
const CVector operator+(const CVector &vec) const
{
return CVector(x + vec.x, y + vec.y, z + vec.z);
}
// vector add (opposite of negation)
const CVector operator+() const
{
return CVector(*this);
}
// vector increment
const CVector& operator+=(const CVector& vec)
{ x += vec.x;
y += vec.y;
z += vec.z;
return *this;
}
// vector subtraction
const CVector operator-(const CVector& vec) const
{
return CVector(x - vec.x, y - vec.y, z - vec.z);
}
// vector negation
const CVector operator-() const
{
return CVector(-x, -y, -z);
}
// vector decrement
const CVector &operator-=(const CVector& vec)
{
x -= vec.x;
y -= vec.y;
z -= vec.z;
return *this;
}
// scalar self-multiply
const CVector &operator*=(const scalar_t &s)
{
x *= s;
y *= s;
z *= s;
return *this;
}
// scalar self-divecide
const CVector &operator/=(const scalar_t &s)
{
const float recip = 1/s; // for speed, one divecision
x *= recip;
y *= recip;
z *= recip;
return *this;
}
// post multiply by scalar
const CVector operator*(const scalar_t &s) const
{
return CVector(x*s, y*s, z*s);
}
// pre multiply by scalar
friend inline const CVector operator*(const scalar_t &s, const CVector &vec)
{
return vec*s;
}
/* friend inline const CVector operator*(const CVector &vec, const scalar_t &s)
{
return CVector(vec.x*s, vec.y*s, vec.z*s);
}
*/ // divecide by scalar
const CVector operator/(scalar_t s) const
{
s = 1/s;
return CVector(s*x, s*y, s*z);
}
// cross product
const CVector CrossProduct(const CVector &vec) const
{
return CVector(y*vec.z - z*vec.y, z*vec.x - x*vec.z, x*vec.y - y*vec.x);
}
// cross product
const CVector operator^(const CVector &vec) const
{
return CVector(y*vec.z - z*vec.y, z*vec.x - x*vec.z, x*vec.y - y*vec.x);
}
// dot product
const scalar_t DotProduct(const CVector &vec) const
{
return x*vec.x + y*vec.x + z*vec.z;
}
// dot product
const scalar_t operator%(const CVector &vec) const
{
return x*vec.x + y*vec.x + z*vec.z;
}
// length of vector
const scalar_t Length() const
{
return (scalar_t)sqrt((double)(x*x + y*y + z*z));
}
// return the unit vector
const CVector UnitVector() const
{
return (*this) / Length();
}
// normalize this vector
void Normalize()
{
(*this) /= Length();
}
const double operator!() const
{
return sqrtf((x*x) + (y*y)+ (z*z));
}
// return vector with specified length
const CVector operator | (const double length) const
{
return (*this) * (length / !(*this));
}
// set length of vector equal to length
const CVector& operator |= (const float length)
{
return *this = *this | length;
}
// return angle between two vectors
const float inline Angle(const CVector& normal) const
{
return acosf(*this % normal);
}
// reflect this vector off surface with normal vector
const CVector inline Reflection(const CVector& normal) const
{
const CVector vec(*this | 1); // normalize this vector
return (vec - normal * 2.0 * (vec % normal)) * !*this;
}
};
#endif
And here is the collision code...
void CMainBall::Move(float deltaTime, CField *field)
{
if (deltaTime <= 0) return;
double fastestTime = deltaTime;
CPlane *planeCollision = NULL;
for (int idx = 0; idx < 4; idx++)
{
CPlane *plane = &field->fieldWalls[idx];
double collisionTime;
double aa, b, c;
// dot product
aa = plane->N % (a * 0.5);
b = plane->N % v;
c = plane->N % pos + plane->D - Radius;
if (aa == 0) // first degree
{
if (b != 0 && c != 0) // must have velocity
{
collisionTime = -c/b;
if (collisionTime >= 0 && collisionTime < fastestTime)
{
fastestTime = collisionTime;
planeCollision = plane;
}
}
}
else
{ // Second degree equation
double D = b*b - 4*aa*c; // Calc determinant
if (D >= 0)
{
// Calc solution (cannot be negative, so the negative solution is dropped)
collisionTime = (- b - sqrt(D)) / (2*aa);
if (collisionTime >= 0 && collisionTime < fastestTime)
{
fastestTime = collisionTime;
planeCollision = plane;
}
}
}
}
// apply friction (coefficient = 0.2)
if (v.Length() > 0.0)
a = -v * 0.2;
// Move to collision point & set velocity there
pos += v * fastestTime + a * (fastestTime*fastestTime*0.5);
v += a * fastestTime;
// only allow velocity to max out at 800
if (v.Length() > 800.0)
v |= 800.0; // set velocity equal to 800
if (planeCollision)
{ // Bounce - invert height direction
v = v.Reflection(planeCollision->N);
}
// Recursive call
Move(deltaTime - fastestTime, field);
}
[edited by - AfroMogli on March 27, 2004 4:35:10 AM]