A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by Xycaleth » Fri Jul 03, 2009 4:58 pm
Okay, thanks

Hopefully the last problem. I tried extracting the angles myself from the matrix given to the SetTransform callback and most of it seems alright but sometimes there are some weird glitches. Here's some screenshots:


As you can see 2 of the boxes are tilted into the ground, but the rest are resting on the ground just fine.
Here's the code I use to get the angles:
- Code: Select all
static void PhysicsEntitySetTransform ( const NewtonBody* body, const dFloat* matrix, int threadIndex )
{
gentity_t *ent = (gentity_t*)NewtonBodyGetUserData (body);
vec3_t newPosition;
vec3_t oldPosition;
vec3_t angles, velocity;
VectorCopy (ent->r.currentOrigin, oldPosition);
newPosition[0] = matrix[12];
newPosition[1] = matrix[13];
newPosition[2] = matrix[14];
angles[ROLL] = RAD2DEG (atan2 (-matrix[6], matrix[5]));
angles[YAW] = RAD2DEG (-asin (matrix[4]));
angles[PITCH] = RAD2DEG (atan2 (-matrix[8], matrix[0]));
trap_UnlinkEntity (ent);
// Set position code is here - removed it in this example to make code easier to read.
// Set the orientation here using the angles calculated
ent->s.apos.trType = TR_STATIONARY;
VectorCopy (angles, ent->s.apos.trBase);
VectorCopy (angles, ent->r.currentAngles);
VectorCopy (angles, ent->s.angles);
trap_LinkEntity (ent);
}
Am I extracting the angles correctly? Or is it Newton glitching and not me (unlikely I'd say

)?
-
Xycaleth
-
- Posts: 13
- Joined: Mon Jun 29, 2009 6:41 am
by JernejL » Fri Jul 03, 2009 5:35 pm
Well obviously you have yaw & roll messed up in this case, tried swapping them?
in worst case, the angles might not be adequate enough to reprisent full body rotations, this is why quarternions and matrixes are normally used, if angles dont work you will have to rework the entity rendering routines to handle matrixes (shouldn't be hard at all to do this, just change the way entity is transformed in graphics engine to use matrix instead of glrotatef or whatever it uses now)
-

JernejL
-
- Posts: 1587
- Joined: Mon Dec 06, 2004 2:00 pm
- Location: Slovenia
-
by Julio Jerez » Fri Jul 03, 2009 6:08 pm
I think you mist teh case whe teh Gibal Lock happens.
If you matrin ix like this
m = = rot(Y) * rot(z) * rot (x)
the Gimbal lock will happens when teh rot(z) is a multiple of +- 90 dress
when this si thr case you must derive the comversion for +90 and for -90
that is
m = rot(Y) * rot(90) * rot (x)
m = rot(Y) * rot(-90) * rot (x)
I adde the modification to your code, but you must check it out as I did not tested
- Code: Select all
static void PhysicsEntitySetTransform ( const NewtonBody* body, const dFloat* matrix, int threadIndex )
{
gentity_t *ent = (gentity_t*)NewtonBodyGetUserData (body);
vec3_t newPosition;
vec3_t oldPosition;
vec3_t angles, velocity;
VectorCopy (ent->r.currentOrigin, oldPosition);
newPosition[0] = matrix[12];
newPosition[1] = matrix[13];
newPosition[2] = matrix[14];
if (absf (matrix[4]) > 0.9999f) {
angles[ROLL] = RAD2DEG (atan2 (-matrix[6], matrix[5]));
angles[YAW] = RAD2DEG (-asin (matrix[4]));
angles[PITCH] = RAD2DEG (atan2 (-matrix[8], matrix[0]));
} else if (matrix[4] > 0)
angles[ROLL] = 0.0f;
angles[YAW] = RAD2DEG (-3.1416 * 0.5f));
angles[PITCH] = RAD2DEG (atan2 (matrix[1], matrix[2]));
} else {
angles[ROLL] = 0.0f;
angles[YAW] = RAD2DEG (3.1416 * 0.5f));
angles[PITCH] = -RAD2DEG (atan2 (matrix[1], matrix[2]));
}
trap_UnlinkEntity (ent);
// Set position code is here - removed it in this example to make code easier to read.
// Set the orientation here using the angles calculated
ent->s.apos.trType = TR_STATIONARY;
VectorCopy (angles, ent->s.apos.trBase);
VectorCopy (angles, ent->r.currentAngles);
VectorCopy (angles, ent->s.angles);
trap_LinkEntity (ent);
}
a thing that can help you is to add the debug display, they are lines in global space, you can just render then to check that the collision shape is correct.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Xycaleth » Sat Jul 04, 2009 10:26 am
I found a function which does Euler angles to rotation matrix in the mod SDK:
- Code: Select all
void AnglesToAxis( const vec3_t angles, vec3_t axis[3] ) {
vec3_t right;
// angle vectors returns "right" instead of "y axis"
AngleVectors( angles, axis[0], right, axis[2] );
VectorSubtract( vec3_origin, right, axis[1] );
}
void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) {
float angle;
static float sr, sp, sy, cr, cp, cy;
// static to help MS compiler fp bugs
angle = angles[YAW] * (M_PI*2 / 360);
sy = sin(angle);
cy = cos(angle);
angle = angles[PITCH] * (M_PI*2 / 360);
sp = sin(angle);
cp = cos(angle);
angle = angles[ROLL] * (M_PI*2 / 360);
sr = sin(angle);
cr = cos(angle);
if (forward)
{
forward[0] = cp*cy;
forward[1] = cp*sy;
forward[2] = -sp;
}
if (right)
{
right[0] = (-1*sr*sp*cy+-1*cr*-sy);
right[1] = (-1*sr*sp*sy+-1*cr*cy);
right[2] = -1*sr*cp;
}
if (up)
{
up[0] = (cr*sp*cy+-sr*-sy);
up[1] = (cr*sp*sy+-sr*cy);
up[2] = cr*cp;
}
}
And I've basically written a function which does the reverse of the above functions:
- Code: Select all
void AxisToAngles ( const vec3_t axis[3], vec3_t angles )
{
vec3_t right;
// vec3_origin is the origin (0, 0, 0).
VectorSubtract (vec3_origin, axis[1], right);
if ( axis[0][2] > 0.999f )
{
angles[PITCH] = -90.0f;
angles[YAW] = RAD2DEG (atan2f (-right[0], right[1]));
angles[ROLL] = 0.0f;
}
else if ( axis[0][2] < -0.999f )
{
angles[PITCH] = 90.0f;
angles[YAW] = RAD2DEG (atan2f (-right[0], right[1]));
angles[ROLL] = 0.0f;
}
else
{
angles[PITCH] = RAD2DEG (asinf (-axis[0][2]));
angles[YAW] = RAD2DEG (atan2f (axis[0][1], axis[0][0]));
angles[ROLL] = RAD2DEG (atan2f (-right[2], axis[2][2]));
}
}
The axis parameter is the rotation matrix. Here's the code to copy the rotation matrix out of the 4x4 matrix:
- Code: Select all
vec3_t axis[3];
axis[0][0] = matrix[0];
axis[0][1] = matrix[1];
axis[0][2] = matrix[2];
axis[1][0] = matrix[4];
axis[1][1] = matrix[5];
axis[1][2] = matrix[6];
axis[2][0] = matrix[8];
axis[2][1] = matrix[9];
axis[2][2] = matrix[10];
Nothing too complicated as you can see

I'm not sure if I've done the Gimbal lock correction correctly but it looks okay in-game - I just wanted to double-check I'd done it right

EDIT: I've found I've not done the gimbal lock correction properly

Looks like I'll have to do more thinking...
-
Xycaleth
-
- Posts: 13
- Joined: Mon Jun 29, 2009 6:41 am
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 1 guest