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:
parent
d9cbf6c9a8
commit
c82d619cc4
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user