#ifndef _Orientation_h_
#define _Orientation_h_
class Orientation {
private:
float m_r[3][3];
static const Orientation s_orientIdentity;
friend class Matrix;
public:
Orientation();
Orientation(float r00, float r01, float r02,
float r10, float r11, float r12,
float r20, float r21, float r22)
{
m_r[0][0] = r00;
m_r[0][1] = r01;
m_r[0][2] = r02;
m_r[1][0] = r10;
m_r[1][1] = r11;
m_r[1][2] = r12;
m_r[2][0] = r20;
m_r[2][1] = r21;
m_r[2][2] = r22;
}
Orientation(const Orientation& o);
Orientation(const float m[3][3]);
Orientation& operator=(const float r[3][3]);
Orientation(const Vector& vecForward);
Orientation(const Vector& vecForward, const Vector& vecUp);
Orientation(const Vector& axis, float angle);
static const Orientation& GetIdentity()
{
return s_orientIdentity;
}
~Orientation();
Orientation& operator=(const Orientation& o);
Orientation& operator*=(const Orientation& o);
Orientation operator*(const Orientation& o) const;
bool operator==(const Orientation& o) const; void TurnTo(const Vector& target);
float TurnTo(const Vector& target, float maxTurn); Orientation& Invert();
Vector TimesInverse(const Vector& vec) const;
Orientation TimesInverse(const Orientation& o) const;
void Reset();
bool Set(const Vector& vecForward);
bool Set(const Vector& vecForward, const Vector& vecUp);
Vector GetForward() const
{
return Vector(-m_r[2][0], -m_r[2][1],-m_r[2][2]);
}
const Vector& GetBackward() const
{
assert (&(((Vector*)&m_r[2][0])->z) == &m_r[2][2]);
return *((Vector*)&m_r[2][0]);
}
const Vector& GetUp() const
{
assert (&(((Vector*)&m_r[1][0])->z) == &m_r[1][2]);
return *((Vector*)&m_r[1][0]);
}
const Vector& GetRight() const
{
assert (&(((Vector*)&m_r[0][0])->z) == &m_r[0][2]);
return *((Vector*)&m_r[0][0]);
}
void SetForward(const Vector& vec)
{
ZAssert(vec.LengthSquared() != 0);
m_r[2][0] = -vec.x;
m_r[2][1] = -vec.y;
m_r[2][2] = -vec.z;
}
void SetUp(const Vector& vec)
{
ZAssert(vec.LengthSquared() != 0);
m_r[1][0] = vec.x;
m_r[1][1] = vec.y;
m_r[1][2] = vec.z;
}
void SetRight(const Vector& vec)
{
ZAssert(vec.LengthSquared() != 0);
m_r[0][0] = vec.x;
m_r[0][1] = vec.y;
m_r[0][2] = vec.z;
}
float CosForward(const Vector& vec) const;
float CosUp(const Vector& vec) const;
float CosRight(const Vector& vec) const;
float CosForward2(const Vector& vec) const;
float CosUp2(const Vector& vec) const;
float CosRight2(const Vector& vec) const;
Orientation& PostRoll(float theta);
Orientation& PostPitch(float theta);
Orientation& PostYaw(float theta);
Orientation& Roll(float theta);
Orientation& Pitch(float theta);
Orientation& Yaw(float theta);
void Renormalize(void)
{
Vector forward = GetForward();
Vector up = GetUp();
Set(forward, up);
}
Orientation& PreRotate(const Vector& axis, float theta);
Orientation& PostRotate(const Vector& axis, float theta);
void Scale(const Vector& xyz)
{
m_r[0][0] *= xyz.x; m_r[0][1] *= xyz.y; m_r[0][2] *= xyz.z;
m_r[1][0] *= xyz.x; m_r[1][1] *= xyz.y; m_r[1][2] *= xyz.z;
m_r[2][0] *= xyz.x; m_r[2][1] *= xyz.y; m_r[2][2] *= xyz.z;
}
const float* operator[](int index) const
{
return m_r[index];
}
friend Vector operator * (const Vector& v, const Orientation& o);
};
inline Vector operator * (const Vector& v, const Orientation& o)
{
return
Vector(
v.x * o.m_r[0][0] + v.y * o.m_r[1][0] + v.z * o.m_r[2][0],
v.x * o.m_r[0][1] + v.y * o.m_r[1][1] + v.z * o.m_r[2][1],
v.x * o.m_r[0][2] + v.y * o.m_r[1][2] + v.z * o.m_r[2][2]
);
}
#endif