Jump to content
  • Advertisement
Sign in to follow this  
Kasya

Matrix

This topic is 3770 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

Hello, i have a matrix class i don't know how to transform it into world space. my matrix class
template<class T> class _CMatrix {
	public:
		T row[16];

		//Constructors:
		_CMatrix() { memset(row, 0, sizeof(T)*16); }
		_CMatrix(T nrow[16]) { memset(row, nrow, sizeof(T)*16); }
		_CMatrix(_CMatrix &nm) { memset(row, nm.row, sizeof(T)*16); }


		//CMatrix - CMatrix Operators:
		_CMatrix &operator=(const _CMatrix &m) {

			memset(row, m.row, sizeof(T)*16);
			return *this;

		}

		_CMatrix operator*(const _CMatrix &m) {

			T temp[16];

			temp[0] = row[0] * m.row[0] + row[4] * m.row[1] + row[8] * m.row[2];
			temp[1] = row[1] * m.row[0] + row[5] * m.row[1] + row[9] * m.row[2];
			temp[2] = row[2] * m.row[0] + row[6] * m.row[1] + row[10] * m.row[2];
			temp[3] = 0;

			temp[4] = row[0] * m.row[4] + row[4] * m.row[5] + row[8] * m.row[6];
			temp[5] = row[1] * m.row[4] + row[5] * m.row[5] + row[9] * m.row[6];
			temp[6] = row[2] * m.row[4] + row[6] * m.row[5] + row[10] * m.row[6];
			temp[7] = 0;

			temp[8] = row[0] * m.row[8] + row[4] * m.row[9] + row[8] * m.row[10];
			temp[9] = row[1] * m.row[8] + row[5] * m.row[9] + row[9] * m.row[10];
			temp[10] = row[2] * m.row[8] + row[6] * m.row[9] + row[10] * m.row[10];
			temp[11] = 0;

			temp[12] = row[0] * m.row[12] + row[4] * m.row[13] + row[8] * m.row[14] + row[12];
			temp[13] = row[1] * m.row[12] + row[5] * m.row[13] + row[9] * m.row[14] + row[13];
			temp[14] = row[2] * m.row[12] + row[6] * m.row[13] + row[10] * m.row[14] + row[14];
			temp[15] = 1;

			Set(temp);
			return *this; 

		}

		//CMatrix - Scalar operators:
		_CMatrix &operator=(const T m[16]) {

			memset(row, m, sizeof(T)*16);
			return *this;

		}

		_CMatrix operator*(const T m[16]) {

			T temp[16];

			temp[0] = row[0] * m[0] + row[4] * m[1] + row[8] * m[2];
			temp[1] = row[1] * m[0] + row[5] * m[1] + row[9] * m[2];
			temp[2] = row[2] * m[0] + row[6] * m[1] + row[10] * m[2];
			temp[3] = 0;

			temp[4] = row[0] * m[4] + row[4] * m[5] + row[8] * m[6];
			temp[5] = row[1] * m[4] + row[5] * m[5] + row[9] * m[6];
			temp[6] = row[2] * m[4] + row[6] * m[5] + row[10] * m[6];
			temp[7] = 0;

			temp[8] = row[0] * m[8] + row[4] * m[9] + row[8] * m[10];
			temp[9] = row[1] * m[8] + row[5] * m[9] + row[9] * m[10];
			temp[10] = row[2] * m[8] + row[6] * m[9] + row[10] * m[10];
			temp[11] = 0;

			temp[12] = row[0] * m[12] + row[4] * m[13] + row[8] * m[14] + row[12];
			temp[13] = row[1] * m[12] + row[5] * m[13] + row[9] * m[14] + row[13];
			temp[14] = row[2] * m[12] + row[6] * m[13] + row[10] * m[14] + row[14];
			temp[15] = 1;

			Set(temp);
			return *this;

		}

		//Other Functions:
		void LoadIdentity() { 

			memset(row, 0, sizeof(T) * 16);
			row[0] = row[5] = row[10] = row[15] = 1;

		}

		void Translate(T x, T y, T z) {
		
			row[12] = x;
			row[13] = y;
			row[14] = z;

		}

		void TranslateInverse(T x, T y, T z) {
		
			row[12] = -x;
			row[13] = -y;
			row[14] = -z;

		}

		void SetRotationRadians(T x, T y, T z) {
		
			double cr = cos( x );
			double sr = sin( x );
			double cp = cos( y );
			double sp = sin( y );
			double cy = cos( z );
			double sy = sin( z );

			row[0] = ( cp*cy );
			row[1] = ( cp*sy );
			row[2] = ( -sp );
			row[3] = ( 0.0f );

			double srsp = sr*sp;
			double crsp = cr*sp;

			row[4] = ( srsp*cy-cr*sy );
			row[5] = ( srsp*sy+cr*cy );
			row[6] = ( sr*cp );

			row[8] = ( crsp*cy+sr*sy );
			row[9] = ( crsp*sy-sr*cy );
			row[10] = ( cr*cp );


		}

		void SetRotationRadiansInverse(T x, T y, T z) {
			
			double cr = cos( x );
			double sr = sin( x );
			double cp = cos( y );
			double sp = sin( y );
			double cy = cos( z );
			double sy = sin( z );	

			row[0] = ( cp*cy );
			row[4] = ( cp*sy );
			row[8] = ( -sp );

			double srsp = sr*sp;
			double crsp = cr*sp;

			row[1] = ( srsp*cy-cr*sy );
			row[5] = ( srsp*sy+cr*cy );
			row[9] = ( sr*cp );

			row[2] = ( crsp*cy+sr*sy );
			row[6] = ( crsp*sy-sr*cy );
			row[10] = ( cr*cp );

		}

		void SetRotationDegrees(T x, T y, T z) {

			_CVector3<T> angles;
			angles.x = x * 180/PI;
			angles.y = y * 180/PI;
			angles.z = z * 180/PI;
			SetRotationRadians(angles.x, angles.y, angles.z);

		}

		void SetRotationDegreesInverse(T x, T y, T z) {

			_CVector3<T> angles;
			angles.x = -x * 180/PI;
			angles.y = -y * 180/PI;
			angles.z = -z * 180/PI;
			SetRotationRadiansInverse(angles.x, angles.y, angles.z);

		}

		void RotateVector(_CVector3<T> v) {
			
			_CVector3<T> temp;

			temp.x = v.x * row[0] + v.y * row[4] + v.z * row[8];
			temp.y = v.x * row[1] + v.y * row[5] + v.z * row[9];
			temp.z = v.x * row[2] + v.y * row[6] + v.z * row[10];

			v.Set(temp);

		}

		void RotateVectorInverse(_CVector3<T> v) {
			
			_CVector3<T> temp;

			temp.x = v.x * row[0] + v.y * row[1] + v.z * row[2];
			temp.y = v.x * row[4] + v.y * row[5] + v.z * row[6];
			temp.z = v.x * row[8] + v.y * row[9] + v.z * row[10];

			v.Set(temp);

		}

		void Set(T nrow[16]) { memset(row, nrow, sizeof(T)*16);	}
		void Reset() { memset(row, 0, sizeof(T)*16); }
		


};

how can i transform it into world space? Thanks

Share this post


Link to post
Share on other sites
Advertisement
Transforming a space into another means to find the matrix that maps the local co-ordinate frame in the given space to the desired space. The frame itself isn't relocated or rotated or whatever, it just gets other co-ordinates that match it in the desired space.

In the local space a 3D cartesian co-ordinate frame is located at [0,0,0] and orientated with the basis vectors [1,0,0], [0,1,0], and [0,0,1] (what is usually called the local x, y, and z vectors). Say that the frame is located at [3,4,5] in world space. This means that the local origin [0,0,0] has world space co-ordinates [3,4,5]. So the transformation from local space to world space is a translation, so that
[0,0,0] -> [3,4,5]
and hence, as a matrix,
T(3,4,5)

The same principle works for the orientation, scaling, ... However, you have of course be aware of a suitable order of transformations, since matrix multiplication is non commutative.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kasya
Hello, i have a matrix class i don't know how to transform it into world space.
This is unrelated to your question, but I just wanted to point out a couple of things in your code:

1. IIRC, symbols that begin with an underscore followed by a capital letter are reserved by the implementation in C++. In any case, may I ask what the purpose of the underscore and 'C' prefixes is? Why not just call the class Matrix?

2. Are you sure your operator=() is implemented correctly? Did you perhaps mean to use memcpy()? (It looks likes this may apply to a couple other functions as well.)

3. I might be missing something here, but I don't think it's typical to ignore the 'homogenous' row/column of the matrix (i.e. [0, 0, 0, 1]) in matrix multiplication functions. This will probably lead to wrong results on occasion.

4. Again, I might be missing something (it's early), but it looks like your * operator overwrites the matrix on which it's called. Are you sure that's the behavior you're after? (Note: it's typical to implement binary operators as non-member functions rather than member functions.)

There are a few other things that look a bit suspicious, but I'll leave it at that for now.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Quote:
Original post by Kasya
Hello, i have a matrix class i don't know how to transform it into world space.
This is unrelated to your question, but I just wanted to point out a couple of things in your code:

1. IIRC, symbols that begin with an underscore followed by a capital letter are reserved by the implementation in C++. In any case, may I ask what the purpose of the underscore and 'C' prefixes is? Why not just call the class Matrix?

2. Are you sure your operator=() is implemented correctly? Did you perhaps mean to use memcpy()? (It looks likes this may apply to a couple other functions as well.)

3. I might be missing something here, but I don't think it's typical to ignore the 'homogenous' row/column of the matrix (i.e. [0, 0, 0, 1]) in matrix multiplication functions. This will probably lead to wrong results on occasion.

4. Again, I might be missing something (it's early), but it looks like your * operator overwrites the matrix on which it's called. Are you sure that's the behavior you're after? (Note: it's typical to implement binary operators as non-member functions rather than member functions.)

There are a few other things that look a bit suspicious, but I'll leave it at that for now.



i had some bugs here i fixed all of them.

------------

Quote:

Transforming a space into another means to find the matrix that maps the local co-ordinate frame in the given space to the desired space. The frame itself isn't relocated or rotated or whatever, it just gets other co-ordinates that match it in the desired space.

In the local space a 3D cartesian co-ordinate frame is located at [0,0,0] and orientated with the basis vectors [1,0,0], [0,1,0], and [0,0,1] (what is usually called the local x, y, and z vectors). Say that the frame is located at [3,4,5] in world space. This means that the local origin [0,0,0] has world space co-ordinates [3,4,5]. So the transformation from local space to world space is a translation, so that
[0,0,0] -> [3,4,5]
and hence, as a matrix,
T(3,4,5)

The same principle works for the orientation, scaling, ... However, you have of course be aware of a suitable order of transformations, since matrix multiplication is non commutative.


For object-world transformation i need to multiply matrix or what (like in OPENGL glPopMatrix(), glPushMatrix()). And For Projection Matrix, View Matrix what i need to do?
Thanks!

Share this post


Link to post
Share on other sites
Quote:
3. I might be missing something here, but I don't think it's typical to ignore the 'homogenous' row/column of the matrix (i.e. [0, 0, 0, 1]) in matrix multiplication functions. This will probably lead to wrong results on occasion.


you mean i need to use T row[4][4]
if im not wrong. i have a question. Why? Arent row[16] and row[4][4] equal?
Thanks!

Share this post


Link to post
Share on other sites
He means "why aren't you including index 3, 7, 11 and 15 in your multiplication?" If you don't include those, you don't have a proper multiplication routine.

Also, you might want to transpose the representation of your matrix so that it matches that of both OpenGL and Direct3D -- This is also good for SSE optimization later.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kasya
For object-world transformation i need to multiply matrix or what (like in OPENGL glPopMatrix(), glPushMatrix()). And For Projection Matrix, View Matrix what i need to do?

glPush-/-PopMatrix are a functionality of a stack of matrices, and not of the matrix itself. They furthur don't perform a multiplication. But the matrix product itself is of course functionality you have to implement. You already have approaches to that, although suffering from the problems jyk has enumerated. Moreover, you have to bear in mind that the matrix product isn't commutative, so that routines that alter the instance itself should be available as a pre- and a post-multiply versions.

Since it is questionable to implement matrix operations itself into a matrix class, it is even more questionable to implement matrix building routine like fromTranslation, fromRotation, fromPerspective directly into the matrix class. I suggest you either implement external routines that convert from a transformation to a matrix, or at least to create classes especially for transformations and projections, resp.

Share this post


Link to post
Share on other sites
I understand Translate Matrix. Its working. But i cannot use Rotation Matrix. It doesn't Rotate. What can i do?
Thanks!

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!