1
0
forked from 0ad/0ad

Make decals only rotate around the Y axis, to avoid buggy stretched appearance when rotated non-horizontally

This was SVN commit r9298.
This commit is contained in:
Ykkrosh 2011-04-22 13:19:23 +00:00
parent d9cbf6c9a8
commit c82d619cc4
4 changed files with 44 additions and 3 deletions

View File

@ -98,9 +98,11 @@ void CModelDecal::ValidatePosition()
void CModelDecal::SetTransform(const CMatrix3D& transform)
{
CMatrix3D newTransform = transform;
newTransform.SetYRotation(m_Decal.m_Angle);
newTransform.Concatenate(transform);
// Since decals are assumed to be horizontal and projected downwards
// onto the terrain, use just the Y-axis rotation and the translation
CMatrix3D newTransform;
newTransform.SetYRotation(transform.GetYRotation() + m_Decal.m_Angle);
newTransform.Translate(transform.GetTranslation());
CRenderableObject::SetTransform(newTransform);
InvalidatePosition();

View File

@ -503,3 +503,20 @@ void CMatrix3D::SetRotation(const CQuaternion& quat)
{
quat.ToMatrix(*this);
}
float CMatrix3D::GetYRotation() const
{
// Project the X axis vector onto the XZ plane
CVector3D axis = -GetLeft();
axis.Y = 0;
// Normalise projected vector
float len = axis.Length();
if (len < 0.0001f)
return 0.f;
axis *= 1.0f/len;
// Negate the return angle to match the SetYRotation convention
return -atan2(axis.Z, axis.X);
}

View File

@ -139,6 +139,9 @@ public:
CVector3D GetIn() const;
// return a quaternion representing the matrix's rotation
CQuaternion GetRotation() const;
// return the angle of rotation around the Y axis in range [-pi,pi]
// (based on projecting the X axis onto the XZ plane)
float GetYRotation() const;
// transform a 3D vector by this matrix
CVector3D Transform (const CVector3D &vector) const

View File

@ -122,6 +122,25 @@ public:
TS_ASSERT_DELTA(a(x,y), b(x,y), 0.0002f);
}
void test_getRotation()
{
CMatrix3D m;
srand(0);
m.SetZero();
TS_ASSERT_EQUALS(m.GetYRotation(), 0.f);
m.SetIdentity();
TS_ASSERT_EQUALS(m.GetYRotation(), 0.f);
for (int j = 0; j < 16; ++j)
{
float a = 2*M_PI*rand()/(float)RAND_MAX - M_PI;
m.SetYRotation(a);
TS_ASSERT_DELTA(m.GetYRotation(), a, 0.001f);
}
}
void test_scale()
{
CMatrix3D m;