EntityGetMatrix(), EntitySetMatrix()

Everything related to 3D programming
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

EntityGetMatrix(), EntitySetMatrix()

Post by Psychophanta »

Please answer this questions because no doubt it is essential for deep operations for 3D stuff.
Is there any workaround or something to obtain (and to set up) the 4x4 matrix of an entity? .
And also, the same question for physic matrix for the entities bodies.
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
User avatar
Comtois
Addict
Addict
Posts: 1429
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: EntityGetMatrix(), EntitySetMatrix()

Post by Comtois »

Ogre use quaternion. Use FetchOrientation() to get it.

If you need matrix, you can use this code :

Code: Select all

   void Quaternion::ToRotationMatrix (Matrix3& kRot) const
    {
        Real fTx  = x+x;
        Real fTy  = y+y;
        Real fTz  = z+z;
        Real fTwx = fTx*w;
        Real fTwy = fTy*w;
        Real fTwz = fTz*w;
        Real fTxx = fTx*x;
        Real fTxy = fTy*x;
        Real fTxz = fTz*x;
        Real fTyy = fTy*y;
        Real fTyz = fTz*y;
        Real fTzz = fTz*z;

        kRot[0][0] = 1.0f-(fTyy+fTzz);
        kRot[0][1] = fTxy-fTwz;
        kRot[0][2] = fTxz+fTwy;
        kRot[1][0] = fTxy+fTwz;
        kRot[1][1] = 1.0f-(fTxx+fTzz);
        kRot[1][2] = fTyz-fTwx;
        kRot[2][0] = fTxz-fTwy;
        kRot[2][1] = fTyz+fTwx;
        kRot[2][2] = 1.0f-(fTxx+fTyy);
    }
And convert matrix to quaternion

Code: Select all

    void Quaternion::FromRotationMatrix (const Matrix3& kRot)
    {
        // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
        // article "Quaternion Calculus and Fast Animation".

        Real fTrace = kRot[0][0]+kRot[1][1]+kRot[2][2];
        Real fRoot;

        if ( fTrace > 0.0 )
        {
            // |w| > 1/2, may as well choose w > 1/2
            fRoot = Math::Sqrt(fTrace + 1.0f);  // 2w
            w = 0.5f*fRoot;
            fRoot = 0.5f/fRoot;  // 1/(4w)
            x = (kRot[2][1]-kRot[1][2])*fRoot;
            y = (kRot[0][2]-kRot[2][0])*fRoot;
            z = (kRot[1][0]-kRot[0][1])*fRoot;
        }
        else
        {
            // |w| <= 1/2
            static size_t s_iNext[3] = { 1, 2, 0 };
            size_t i = 0;
            if ( kRot[1][1] > kRot[0][0] )
                i = 1;
            if ( kRot[2][2] > kRot[i][i] )
                i = 2;
            size_t j = s_iNext[i];
            size_t k = s_iNext[j];

            fRoot = Math::Sqrt(kRot[i][i]-kRot[j][j]-kRot[k][k] + 1.0f);
            Real* apkQuat[3] = { &x, &y, &z };
            *apkQuat[i] = 0.5f*fRoot;
            fRoot = 0.5f/fRoot;
            w = (kRot[k][j]-kRot[j][k])*fRoot;
            *apkQuat[j] = (kRot[j][i]+kRot[i][j])*fRoot;
            *apkQuat[k] = (kRot[k][i]+kRot[i][k])*fRoot;
        }
    }
Please correct my english
http://purebasic.developpez.com/
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: EntityGetMatrix(), EntitySetMatrix()

Post by Psychophanta »

Thanks Comtois, if the entities are internally represented with quaternions , then it changes a lot the way i am used in for the 3D stuff.
However, at the moment, i think the common functions from PB are enough for my sources.

Anyway, rotation matrix is not enough to work with the entities, but its homogeneous transformation matrix, which is the common 4x4 matrix used in D3D or in robotics.
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: EntityGetMatrix(), EntitySetMatrix()

Post by Psychophanta »

Hello Comtois.

I translated those tips to PB as procedures.
I am using it because I already had my old funtions in MP3D to rotate entities around an arbitrary axis, this is, not over global nither local 'x', 'y', or 'z' axis.
In other words, I just replaced old MP_EntitySetMatrix() and MP_EntityGetMatrix() to those new procedures. But transformation between cuaternions to rotation matrix everytime is a loose of time.

So, the simple question is:
Someone here does know how to rotate in a clean a fast way an entity over any arbitrary given axis?

Thanks in advance.

EDIT: found this:
http://www.opengl-tutorial.org/intermed ... aternions/
Will try.
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
User avatar
Comtois
Addict
Addict
Posts: 1429
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: EntityGetMatrix(), EntitySetMatrix()

Post by Comtois »

May be this

[w, x, y, z] = [cos(a/2), sin(a/2) * nx, sin(a/2)* ny, sin(a/2) * nz]

Where a is the angle of rotation and {nx,ny,nz} is the axis of rotation and [w, x, y, z] the quaternion.


http://www.euclideanspace.com/maths/geo ... /index.htm
Please correct my english
http://purebasic.developpez.com/
User avatar
Comtois
Addict
Addict
Posts: 1429
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: EntityGetMatrix(), EntitySetMatrix()

Post by Comtois »

This one can be useful

Code: Select all

 /** Gets the shortest arc quaternion to rotate this vector to the destination
            vector.
        @remarks
            If you call this with a dest vector that is close to the inverse
            of this vector, we will rotate 180 degrees around the 'fallbackAxis'
			(if specified, or a generated axis if not) since in this case
			ANY axis of rotation is valid.
        */
        Quaternion getRotationTo(const Vector3& dest,
			const Vector3& fallbackAxis = Vector3::ZERO) const
        {
            // Based on Stan Melax's article in Game Programming Gems
            Quaternion q;
            // Copy, since cannot modify local
            Vector3 v0 = *this;
            Vector3 v1 = dest;
            v0.normalise();
            v1.normalise();

            Real d = v0.dotProduct(v1);
            // If dot == 1, vectors are the same
            if (d >= 1.0f)
            {
                return Quaternion::IDENTITY;
            }
			if (d < (1e-6f - 1.0f))
			{
				if (fallbackAxis != Vector3::ZERO)
				{
					// rotate 180 degrees about the fallback axis
					q.FromAngleAxis(Radian(Math::PI), fallbackAxis);
				}
				else
				{
					// Generate an axis
					Vector3 axis = Vector3::UNIT_X.crossProduct(*this);
					if (axis.isZeroLength()) // pick another if colinear
						axis = Vector3::UNIT_Y.crossProduct(*this);
					axis.normalise();
					q.FromAngleAxis(Radian(Math::PI), axis);
				}
			}
			else
			{
                Real s = Math::Sqrt( (1+d)*2 );
	            Real invs = 1 / s;

				Vector3 c = v0.crossProduct(v1);

    	        q.x = c.x * invs;
        	    q.y = c.y * invs;
            	q.z = c.z * invs;
            	q.w = s * 0.5f;
				q.normalise();
			}
            return q;
        }
Please correct my english
http://purebasic.developpez.com/
User avatar
Psychophanta
Addict
Addict
Posts: 4996
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: EntityGetMatrix(), EntitySetMatrix()

Post by Psychophanta »

At the moment no success.
Will try.
In a few days i think I will get it.

EDIT:
I hope this executeable tip works there, it is a normal windows 32bit executeable.
Moving the mouse can rotate the object. With left CTRL + mouse moving orbitates the eye over the object.
The issue is to get this effect (object rotation) ALWAYS over the eye view plane, this is, with the rotation axis contained inside de front view plane.
https://mega.nz/#!QpgSVKDB!HNlntXQCuwNF ... cjAwvEzlhE

Just replaced conversion functions (quaternion--->rotation matrix) and viceversa in the original code from this tip, made with MP3D library and using homogeneous transformation matrixes, implemented in Direct3D, OpenGL and others:
No success.

Now trying to obtain the same behaviour via another strategy...
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
Post Reply