Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Getting a hold of the rotation from the 3x3 section of a 4x4  (Read 4658 times)

0 Members and 1 Guest are viewing this topic.

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« on: April 03, 2011, 03:40:59 am »
Aight so I am working on a SFML-inspired wrapper for SFML :P Kind of like adding a sf::Renderer class that supports 3D coordinates (Opposed to do direct OpenGL calls in sf::Drawable::Render).

Anyway to my problem. I am implementing right now a class that would be a 3D version of sf::Drawable that I call Graphics::Object that has a 4x4 matrix where the 3x3 section contains the 3D rotation which is calculated like this:


Stolen from Wikipedia :)

What I want is convert the 3x3 section of the matrix to a vector with dimension 3. Currently my API looks like this:
Code: [Select]
void SetRotation( const Vector3f aRotation );
void SetRotation( const float anX, const float anY, const float anZ );
Matrix33f GetRotation() const;


But I want it to look like this:
Code: [Select]
void SetRotation( const Vector3f aRotation );
void SetRotation( const float anX, const float anY, const float anZ );
Vector3f GetRotation() const;

Notice the change in the return value type of GetRotation()

So is there any magical mathematician here that knows how to do that? :D
I myself have problem with math. But well I have the standard mathematical vector and matrix operations implemented and working.

Would it be easy enough to just have a Zero-vector and multiply it with the matrix?
Code: [Select]
return Vector3f::Zero * myMatrix.Get33();
EDIT: Well after some thought... that would just give me another zero vector wouldn't it?

What I want the returned vector to represent is the amount of rotation for each axis.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #1 on: April 03, 2011, 10:26:43 am »
I think what you need is the "Matrix & quaternions FAQ":
http://www.j3d.org/matrix_faq/matrfaq_latest.html

Seems like you need this one in particular:
Q37. How do I generate Euler angles from a rotation matrix?

But maybe you should just store the rotation instead of extracting it from the matrix?
Laurent Gomila - SFML developer

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #2 on: April 03, 2011, 03:00:17 pm »
Looked at how you did it in sf::Drawable. Much easier and I'll probably go with that. ^^
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #3 on: April 03, 2011, 04:02:41 pm »
I'm wondering how you can get this to compile:
Code: [Select]

const Matrix3& Drawable::GetMatrix() const
{
    // First recompute it if needed
    if (!myMatrixUpdated)
    {
        myMatrix = Matrix3::Transformation(myOrigin, myPosition, myRotation, myScale);
        myMatrixUpdated = true;
    }

    return myMatrix;
}



the function is set to be constant but you clearly change values in the object. How can it then be constant?
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #4 on: April 03, 2011, 04:05:26 pm »
The members that I change are declared mutable ;)
Laurent Gomila - SFML developer

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #5 on: April 03, 2011, 04:19:50 pm »
Cool it worked :D

And now while I still got your attention. How does scaling work. Remember from my class that my teacher talked about the 3 values that are left untouched in a 4x4 that the scaling could be placed there. Though looking around at wikipedia it looks like the scaling would occupy the same places as the rotation.

Well the important thing is that it is compatible with OpenGL's glLoadMatrix function.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #6 on: April 03, 2011, 04:28:37 pm »
A scaling matrix has the scale factors on its diagonal (x=0,0 y=1,1 and z=2,2).

So when you multiply it with an existing matrix you end up multiplying all the elements of the first column by the X scale factor, the second column by the Y scale factor and the third column by the Z scale factor.
Laurent Gomila - SFML developer

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #7 on: April 03, 2011, 04:36:38 pm »
Quote from: "Laurent"
A scaling matrix has the scale factors on its diagonal (x=0,0 y=1,1 and z=2,2).

So when you multiply it with an existing matrix you end up multiplying all the elements of the first column by the X scale factor, the second column by the Y scale factor and the third column by the Z scale factor.


I thought as much, I'll have to ask what my teachers talked about, maybe that was something DirectX specific(That's what they teach us -.-) though I doubt it, probably me that misunderstood something.

But if I have a matrix that is rotated in all 3 axises and then scale the matrix. Wouldn't mean that the scale affects the rotation somehow?

Just thinking on that on the position (0,0) is also the place for the cos(angle) for both y-rotation and z-rotation. Won't this conflict somehow?
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #8 on: April 03, 2011, 04:44:02 pm »
Yep. If you apply a rotation followed by a scale, and then try to extract the resulting rotation, you most likely won't find the initial one.
Laurent Gomila - SFML developer

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #9 on: April 03, 2011, 04:56:58 pm »
Quote from: "Laurent"
Yep. If you apply a rotation followed by a scale, and then try to extract the resulting rotation, you most likely won't find the initial one.


Well I'm going with your way so that won't be a problem. But HOW do I apply the scale to my orientation? Here's my version of your GetMatrix function:
Code: [Select]
const Matrix44f &Graphics::Object::GetMatrix() const
{
    if( myOrientationUpdated == false )
    {
        Matrix33f rotation = Matrix33f::CreateRotateAroundX( myRotation.x );
        rotation = Matrix33f::CreateRotateAroundY( myRotation.y ) * rotation;
        rotation = Matrix33f::CreateRotateAroundZ( myRotation.z ) * rotation;
        myOrientation.SetRotation( rotation );
        myOrientation.SetPosition( myPosition );
        myOrientation.SetScale( myScale );
        myOrientationUpdated = true;
    }
    return myOrientation.myMatrix;
}


And currently in my SetScale function for the matrix:
Code: [Select]

void SetScale(const Vector3<Type> &aScale)
{
    myData[INDEX4(0,0)] *= aScale.x;
    myData[INDEX4(1,1)] *= aScale.y;
    myData[INDEX4(2,2)] *= aScale.z;
}


What am I doing wrong because I try to scale by 0.1f on all axis but it looks REALLY weird and absolutely not scaled to a 1/10 of it's original size.

Might be that I am applying the rotation wrong in the GetMatrix function. Been some time since I had the 3D Math class and I can't access my old assignments from my home computer.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #10 on: April 03, 2011, 05:07:44 pm »
Your way of doing it looks wrong, but maybe I just misunderstand what you're doing.

Can I see the implementation of the Orientation class (or whatever myOrientation is an instance of)?
Laurent Gomila - SFML developer

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #11 on: April 03, 2011, 05:13:27 pm »
The Orientation class is a wrapper to make it simpler to work with the matrix. You know instead of working directly with the mathematical operations I define a set of functions with names on them on what they are supposed to do. (It was an assignment and I think that was the explanation...)

Orientation -> http://pastebin.com/qtc2fJNN
Matrix44 -> http://pastebin.com/zNMFuVn0

Notice: There's some things I've changed in Matrix44 and I need to update it in some functions that I don't use. (Since it's a template the functions don't get compiled and I don't get an error)
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #12 on: April 03, 2011, 06:44:39 pm »
I see.

So SetScale and SetPosition would rather be ApplyTranslation and ApplyScale. It's meant to be equivalent to a multiplication by a translation or scale matrix. Right?

Your formulas in SetScale and SetPosition are incorrect; to find the correct ones simply write the matrix multiplication corresponding to what you want to do (with "a, b, c ..." instead of actual values) and simplify the result.

For example, SetScale should multiply all the elements of the 3x3 matrix, not only the diagonal ones.

And I think your API is not clear, you should either:
1. always combine transformations in the same order, regardless the order the user sets them (like I do in SFML)
2. combine transformations on the fly (respecting the order the user calls them), but rename your functions to make it clear what happens
Laurent Gomila - SFML developer

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #13 on: April 03, 2011, 10:04:37 pm »
Quote from: "Laurent"
So SetScale and SetPosition would rather be ApplyTranslation and ApplyScale. It's meant to be equivalent to a multiplication by a translation or scale matrix. Right?
Naah almost I think. Translation is defined in Orientation. Though the "Set*" functions do a hard absolute set to that value. Don't know if that's different from apply, but I think so.

Quote from: "Laurent"
Your formulas in SetScale and SetPosition are incorrect; to find the correct ones simply write the matrix multiplication corresponding to what you want to do (with "a, b, c ..." instead of actual values) and simplify the result.

They are in SetScale, that's why it don't work but it's correct in SetPosition. I know since I used the same class to create a software 3D renderer ^^

Quote from: "Laurent"
For example, SetScale should multiply all the elements of the 3x3 matrix, not only the diagonal ones.

Thanks! That's what I needed :P Then it should be enough to just multiply it with the incoming vector.

Quote from: "Laurent"
And I think your API is not clear, you should either:
1. always combine transformations in the same order, regardless the order the user sets them (like I do in SFML)
2. combine transformations on the fly (respecting the order the user calls them), but rename your functions to make it clear what happens

Hmm how do you mean? Don't I do number one? When the matrix is requested I update the matrix by first creating the rotation matrix and then the position and last the scale.

NOTE: Sweet it worked now :D Thanks! My cube is now SUPER SMALL :D Would my wrapper be interesting to have in the wiki? So far it includes common utilities, threading and graphics. My common utilities might not be that great as you noticed. Most of it is written for my own uses. The threading on the other hand helps out a lot when it comes to lock-less synchronization between the threads. The graphics part is what I'm working on currently which would be like I said, a 3D version of the already in place sf::Renderer. Though thinking of it, it might be too big to have in the Wiki
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Getting a hold of the rotation from the 3x3 section of a 4x4
« Reply #14 on: April 03, 2011, 10:22:10 pm »
Quote
Hmm how do you mean? Don't I do number one? When the matrix is requested I update the matrix by first creating the rotation matrix and then the position and last the scale.

I was talking about the Orientation class, not the higher-level one.
Laurent Gomila - SFML developer

 

anything