Page 1 of 1
EntityGetMatrix(), EntitySetMatrix()
Posted: Sun Sep 30, 2018 2:34 pm
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.
Re: EntityGetMatrix(), EntitySetMatrix()
Posted: Sun Sep 30, 2018 6:08 pm
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;
}
}
Re: EntityGetMatrix(), EntitySetMatrix()
Posted: Sun Sep 30, 2018 6:37 pm
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.
Re: EntityGetMatrix(), EntitySetMatrix()
Posted: Tue Feb 05, 2019 11:09 am
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.
Re: EntityGetMatrix(), EntitySetMatrix()
Posted: Tue Feb 05, 2019 7:52 pm
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
Re: EntityGetMatrix(), EntitySetMatrix()
Posted: Tue Feb 05, 2019 10:34 pm
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;
}
Re: EntityGetMatrix(), EntitySetMatrix()
Posted: Wed Feb 06, 2019 3:24 pm
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...