Fix T47015: BGE, objects vanish aligning to vector

1811 by @mangostaniko

Fixes regression since moving to floats.
This commit is contained in:
Campbell Barton 2016-02-26 09:12:13 +11:00
parent f1b5b97bed
commit d53132d200

@ -1187,6 +1187,7 @@ const MT_Vector4& KX_GameObject::GetObjectColor()
void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
{ {
const MT_Scalar eps = 3.0f * MT_EPSILON;
MT_Matrix3x3 orimat; MT_Matrix3x3 orimat;
MT_Vector3 vect,ori,z,x,y; MT_Vector3 vect,ori,z,x,y;
MT_Scalar len; MT_Scalar len;
@ -1212,10 +1213,12 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
orimat = GetSGNode()->GetWorldOrientation(); orimat = GetSGNode()->GetWorldOrientation();
switch (axis) switch (axis)
{ {
case 0: //x axis case 0: // align x axis of new coord system to vect
ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]); // pivot axis
if (MT_abs(vect.dot(ori)) > 1.0f-3.0f*MT_EPSILON) //is the vector parallel to the pivot? if (1.0f - MT_abs(vect.dot(ori)) < eps) { // vect parallel to pivot?
ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot! ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]); // change the pivot!
}
if (fac == 1.0f) { if (fac == 1.0f) {
x = vect; x = vect;
} else { } else {
@ -1227,10 +1230,12 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
y = ori.cross(x); y = ori.cross(x);
z = x.cross(y); z = x.cross(y);
break; break;
case 1: //y axis case 1: // y axis
ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]); ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]);
if (MT_abs(vect.dot(ori)) > 1.0f-3.0f*MT_EPSILON) if (1.0f - MT_abs(vect.dot(ori)) < eps) {
ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]); ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]);
}
if (fac == 1.0f) { if (fac == 1.0f) {
y = vect; y = vect;
} else { } else {
@ -1242,10 +1247,12 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
z = ori.cross(y); z = ori.cross(y);
x = y.cross(z); x = y.cross(z);
break; break;
case 2: //z axis case 2: // z axis
ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]); ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]);
if (MT_abs(vect.dot(ori)) > 1.0f-3.0f*MT_EPSILON) if (1.0f - MT_abs(vect.dot(ori)) < eps) {
ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]); ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]);
}
if (fac == 1.0f) { if (fac == 1.0f) {
z = vect; z = vect;
} else { } else {
@ -1257,25 +1264,27 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
x = ori.cross(z); x = ori.cross(z);
y = z.cross(x); y = z.cross(x);
break; break;
default: //wrong input? default: // invalid axis specified
cout << "alignAxisToVect(): Wrong axis '" << axis <<"'\n"; cout << "alignAxisToVect(): Invalid axis '" << axis <<"'\n";
return; return;
} }
x.normalize(); //normalize the vectors x.normalize(); // normalize the new base vectors
y.normalize(); y.normalize();
z.normalize(); z.normalize();
orimat.setValue( x[0],y[0],z[0], orimat.setValue(x[0], y[0], z[0],
x[1],y[1],z[1], x[1], y[1], z[1],
x[2],y[2],z[2]); x[2], y[2], z[2]);
if (GetSGNode()->GetSGParent() != NULL) if (GetSGNode()->GetSGParent() != NULL)
{ {
// the object is a child, adapt its local orientation so that // the object is a child, adapt its local orientation so that
// the global orientation is aligned as we want. // the global orientation is aligned as we want (cancelling out the parent orientation)
MT_Matrix3x3 invori = GetSGNode()->GetSGParent()->GetWorldOrientation().inverse(); MT_Matrix3x3 invori = GetSGNode()->GetSGParent()->GetWorldOrientation().inverse();
NodeSetLocalOrientation(invori*orimat); NodeSetLocalOrientation(invori*orimat);
} }
else else {
NodeSetLocalOrientation(orimat); NodeSetLocalOrientation(orimat);
}
} }
MT_Scalar KX_GameObject::GetMass() MT_Scalar KX_GameObject::GetMass()