#### Archived

This topic is now archived and is closed to further replies.

# Lets make a game...

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

## Recommended Posts

What came to my mind, is maybe we can start making a game here? For example, we can post some useful code and how it''s going to be used in the engine, and then after all we can combine that code for ,say, next tutorial on game-making? Here''s my first addition to this topic - CVector class:


class CVector
{
private:
void sub();

public:
GLfloat	x;
GLfloat	y;
GLfloat	z;

VERTEX3fv data;

// ructors

CVector(GLfloat x=0, GLfloat y=0, GLfloat z=0) : x(x), y(y), z(z) { sub(); }
CVector(CVector &V) : x(V.x), y(V.y), z(V.z) { sub();}
CVector& operator = (CVector& V);

GLfloat *GetData();

//	Boolean stuff

bool operator == (CVector& Vector);
bool operator != (CVector& Vector);

//	Add & Substract, Positive & Negative

CVector operator + (CVector& Vector);
CVector operator + ();
CVector& operator += (CVector& Vector);

// minus vector

CVector operator - (CVector& Vector);
CVector operator - ();
CVector &operator -= (CVector& Vector);

//	Multiply & Divide

CVector operator * (CVector& Vector);
CVector& operator *= (CVector& Vector);
CVector operator * (GLfloat d);
CVector& operator *= (GLfloat d);
CVector operator / (CVector& Vector);
CVector &operator /= (CVector& Vector);
CVector operator / (GLfloat d);
CVector& operator /= (GLfloat d);

bool operator > (CVector& Vector);
bool operator < (CVector& Vector);
//	Dot Product

GLfloat operator % (CVector& Vector);
//	Cross Product

CVector operator ^ (CVector& Vector);
CVector& operator ^= (CVector& Vector);

//	Set length (Normalize if 1) or Magnitude of vector

GLfloat operator ! ();
CVector operator | (GLfloat dLength);
CVector& operator |= (GLfloat dLength);

void Normalize();

void SetNormal(CVector vTriangle0, CVector vTriangle1, CVector vTriangle2 );

//	The angle between two vectors in radians

GLfloat Angle(CVector& Normal);

//	Reflect in Normal Vector

CVector Reflection(CVector& PlaneNormal);
//	Rotate dAngle Degrees (radians) Around Normal

CVector Rotate(GLfloat dAngle, CVector& Normal);

//	More Advanced Functions

GLfloat PlaneDistance(CVector Normal, CVector Point);

// Is Plane intersected?

bool IntersectedPlane(CVector vTriangle[], CVector vLine[]);
};

// Source

/* --------------------------------- VECTOR IMPLEMENTATION -------------------------------//
//----------------------------------------------------------------------------------------*/
CVector& CVector::operator = (CVector& V)
{	x = V.x;
y = V.y;
z = V.z;
sub();
return *this;
}

//	Boolean stuff
bool CVector::operator == (CVector& Vector)
{	return (x == Vector.x && y == Vector.y && z == Vector.z);
}
bool CVector::operator != (CVector& Vector)
{	return !(*this == Vector);
}

//	Add & Substract, Positive & Negative
CVector CVector::operator + (CVector& Vector)
{	return CVector(x + Vector.x, y + Vector.y, z + Vector.z);
}
CVector CVector::operator + ()
{	return CVector(*this);
}
CVector& CVector::operator += (CVector& Vector)
{	x += Vector.x;
y += Vector.y;
z += Vector.z;
sub();
return *this;
}
// minus vector
CVector CVector::operator - (CVector& Vector)
{	return CVector(x - Vector.x, y - Vector.y, z - Vector.z);
}
CVector CVector::operator - ()
{	return CVector(-x, -y, -z);
}
CVector &CVector::operator -= (CVector& Vector)
{	x -= Vector.x;
y -= Vector.y;
z -= Vector.z;
sub();
return *this;
}

//	Multiply & Divide
CVector CVector::operator * (CVector& Vector)
{	return CVector(x * Vector.x, y * Vector.y, z * Vector.z);
}
CVector &CVector::operator *= (CVector& Vector)
{	x *= Vector.x;
y *= Vector.y;
z *= Vector.z;
sub();
return *this;
}
CVector CVector::operator * (GLfloat d)
{	return CVector(x * d, y * d, z * d);
}
CVector &CVector::operator *= (GLfloat d)
{	x *= d;
y *= d;
z *= d;
sub();
return *this;
}
CVector CVector::operator / (CVector& Vector)
{	return CVector(x / Vector.x, y / Vector.y, z / Vector.z);
}

CVector &CVector::operator /= (CVector& Vector)
{	x /= Vector.x;
y /= Vector.y;
z /= Vector.z;
sub();
return *this;
}
CVector CVector::operator / (GLfloat d)
{	GLfloat _d = 1.0f / d;
return CVector(x * _d, y * _d, z * _d);
}
CVector &CVector::operator /= (GLfloat d)
{	GLfloat _d = 1.0f / d;
x *= _d;
y *= _d;
z *= _d;
sub();
return *this;
}

//	Dot Product
GLfloat CVector::operator % (CVector& Vector)
{	return x*Vector.x + y*Vector.y + z*Vector.z;
}
//	Cross Product
CVector CVector::operator ^ (CVector& Vector)
{	return CVector(
y * Vector.z - Vector.y * z,
z * Vector.x - Vector.z * x,
x * Vector.y - Vector.x * y);
}
CVector &CVector::operator ^= (CVector& Vector)
{	return *this = *this ^ Vector;
}

bool CVector::operator > (CVector& v)
{
return (x>v.x || y>v.y || z>v.z);
}

bool CVector::operator < (CVector& v)
{
return (x<v.x || y<v.y || z<v.z);
}

//	Set length (Normalize if 1) or Magnitude of vector
GLfloat CVector::operator ! ()
{	return sqrtf(x*x + y*y + z*z);
}
CVector CVector::operator | (GLfloat dLength)
{	return *this * (dLength / !*this);
}
CVector &CVector::operator |= (GLfloat dLength)
{	return *this = *this | dLength;
}

void CVector::Normalize()
{
GLfloat magnitude=!*this;
*this/=magnitude;
}

void CVector::SetNormal(CVector vTriangle0, CVector vTriangle1, CVector vTriangle2 )
{
*this = (vTriangle2-vTriangle0)^(vTriangle1-vTriangle0);				// Cross Product
this->Normalize();						// Use our function we created to normalize the normal (Makes it a length of one)
}

//	The angle between two vectors in radians
GLfloat CVector::Angle(CVector& Normal)
{	return acosf(*this % Normal);
}
//	Reflect in Normal Vector
CVector CVector::Reflection(CVector& PlaneNormal)
{	return (*this - PlaneNormal * 2.0 * (*this % PlaneNormal)) * !*this;
}
//	Rotate dAngle Degrees (radians) Around Normal
CVector CVector::Rotate(GLfloat dAngle, CVector& Normal)
{	GLfloat dCos = cosf(dAngle);
GLfloat dSin = sinf(dAngle);
return CVector(
*this * dCos +
((Normal * *this) * (1.0f - dCos)) * Normal +
(*this ^ Normal) * dSin);
}

GLfloat *CVector::GetData()
{	return data; }

void CVector::sub()
{
data[0] = x;
data[1] = y;
data[2] = z;
}
/* -------------------------------END VECTOR IMPLEMENTATION ------------------------------//
//----------------------------------------------------------------------------------------*/


" Do we need us? "

##### Share on other sites
OK, a forum is not the best place to start a project such as this one, we need a proper server and CVS. It could be a theme site, but it has to be properly commented and stepped through. Im up for it, i reckon i have stuff to offer, so feel free to sort out the proper details before we get started.

##### Share on other sites
Hey man,
I was talking about giving your code to public so they can use it in their projects.
I don''t know about CVS (repository), but SourceForge offers it (although I don''t know how to use it)
Would you like to start that kind of thing with me?
I got HEAPS of useful code that I don''t really use for game creation, so I thought maybe someone else can make the game using this code? )

Thanks.

" Do we need us? "

##### Share on other sites

On my computer, 10000000 calls to sqrt() takes 1.98 seconds, where 10000000 calls to sqrtf() takes 3.08 seconds, a fairly large difference. conclusion: sqrt() is better.

Also, in your functions where you calculate the reciprocal, you''re not using the initial value again so you can avoid creating a new variable _d by just doing d = 1 / d; then multiplying by d.

And you''d get another speed boost by getting rid of that sub() thing, I don''t see why you need the vars in array form =)

##### Share on other sites
Thanks Hairybudda, I''ll consider changing that. As for sub(), its just that I didn''t knew about unions. E.g

  union{struct{float x;float y;float z;};float data[3];}Thanks.

" Do we need us? "

##### Share on other sites
I'd like to make a couple of comments about the CVector class you've written (I'm not 'having a go', just passing on years of experience).

Firstly, it's generally regarded as good practice not to redefine the meaning of operators. By this I mean not changing the 'XOR' operator into something else. The reason for this is that anyone not familiar with your implementation would expect 'a ^= b' to actually be 'a = a xor b' rather than a cross product. Worse still, you can't change the precedence of the operator - does a cross product have higher or lower precedence than the '+', or other, operator (mathematically speaking, it should be higher). So, for example, you might be tempted to do the following:

CVector a,b,c;
// assign values to a,b,c
if (a > b ^ c)
{
// do stuff
}

This will generate a compiler error, complaining that there is no definition of the '^' operator that takes the given arguments (in this case: bool, CVector).

All because you can do something in C++, doesn't mean it's a good idea.

Secondly, member variables should be private. There's no reason here to expose them.

Thirdly, I'm assuming the 'source' bit would be in a '.cpp', otherwise you'd get multiple definitions of functions (in MSVC V6 at least). This will lead to inefficient code since none of it would be inlined, even with every inline option switched on it would never be inlined apart from the '.cpp' file containing the CVector source. This is because the translation unit processing a source file that includes the CVector class does not have the code in the implementation to hand to do the inlining (because it would be in another translation unit). And the linker wouldn't inline it since that would screw up all the relative jumps in the code. For a class this simple, put the code in the class declaration.

Fourth, I would personally have called the class CVector3D, so you can then have CVector2D and CVector4D. It would also eliminate any potential user confusion that the class may be implementing a custom 'std::vector' type. Also, using a single 'C' prefix could clash with the MFC classes (game objects defined as CObject?). Use a namespace or use a different prefix to avoid any potential problems (a problem prevented won't become a problem).

Lastly, I wrote a 3D vector class but declared it as a template so I could have vectors of floats, doubles, ints, bytes, etc.(bytes is useful to save disk space - quantize model data to 256 samples in x, y and z - saves 9 bytes per vertex!).

Skizz

[edited by - Skizz on February 3, 2003 6:17:52 AM]

##### Share on other sites
lol - so ... that''s fuc*ed then.

##### Share on other sites
Hello,

It''s not a nice thing to involve openGL specific types in a semi-generic vector class. I suggest you change them to floats instead.

Regards,
Deficte

##### Share on other sites
Another criticism of your vector class is that the == and != operators won''t be very reliable since they''re comparing floating point values. Because of the way floating point values work (if you don''t know how they work I suggest you read up on them - check Google) comparing them directly is pretty foolish. A better approach for comparing two vectors would be to check the angle between them.

Also what''s the point of your operator + that takes no argument? It just seems to make a copy of a vector.

##### Share on other sites
rm3: sqrtf is EXACTLY the same as a sqrt, except it casts to a float for you. If you set a float = sqrt that many times, and a float = sqrtf that many times.. they should be the same speed, just one gives a warning, and the other doesn''t. If you are using doubles... stick with the sqrt obviously .

##### Share on other sites
lol remind me to never post code here you guys are brutal

##### Share on other sites
You should welcome constructive criticism from others, it''s a significant aid to improving code (and many other things). In fact it''s probably the most significant aid since (in my experience) many people get stuck in coding ruts and, without someone else''s help, rarely uncover their own flaws.

##### Share on other sites
Further to what Dobbs posted, in general, try to avoid the ''=='' and ''!='' operators when used in conjunction with floating point values. I always use this code to demonstrate why those operators are dangerous with floating point values:

  int main (int argc, char *argv){	for (float value = 0.0f ; value < 2.0f ; value += 0.05f)	{		printf ("Does %.02f == 1? %s\n", value, value == 1.0f ? "Yes" : "No");	}	return 0;}

Try the above and see what happens. Then work out why.

Skizz

##### Share on other sites
when we are talking about square roots you could use a large lookup table to get the values you want

of course precision suffers a bit but who cares about precision

take a 2 mb chunk of your memory for the lookup table and you should be able to get squareroots from 0-2000 with a precision of 0.001

##### Share on other sites
2mb? You''d have to be nuts about your lookup table to use so much memory for it .

The way I see it

(0-2000)
100 * 2001 * 4 (float) / 1024 = ~781.25kb

Which still seems like quite a bit for a lookup table, it would probably be better to reduce precision by 10 to get it to 78.13kb

Although that is still quite a bit, there are a number of ways to optimize the memory while inflicting a smaller calculation cost. (i.e. do you really need a float to store a number thats 0-2000?)

Since we are all in a mood for constructive critism .

-------
Homepage: http://students.washington.edu/andrey

##### Share on other sites
quote:
Original post by Basiror
when we are talking about square roots you could use a large lookup table to get the values you want

of course precision suffers a bit but who cares about precision

take a 2 mb chunk of your memory for the lookup table and you should be able to get squareroots from 0-2000 with a precision of 0.001

2MB lookup table? are you sane? Ever heard about caches ?
With intrinsic functions enabled sqrt() or sqrtf() will generate something like:

fld var
fsqrt
fstp var

which takes about 80 clock cycles on a Pentium 3

##### Share on other sites
Thanks to everyone posting replies on this topic (and torring my code apart), I really appreciate that.
Although that code was originally been written by Bas Kuenen (with some of my updates), I will try to consider all your thoughts and ideas.
Thanks again.

" Do we need us? "

• 9
• 10
• 18
• 14
• 10