Lets make a game...

Started by
15 comments, last by HellRiZZer 21 years, 2 months ago
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:
  
// Header

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? "

Ionware Productions - Games and Game Tools Development

Advertisement
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.
*st0ned*
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? "


Ionware Productions - Games and Game Tools Development

About your code:

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 =)

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? "


Ionware Productions - Games and Game Tools Development

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]
lol - so ... that''s fuc*ed then.
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
Regards,
Deficte
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.
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 .

This topic is closed to new replies.

Advertisement