| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- //
- // Copyright (c) 2008-2017 the Urho3D project.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- #pragma once
- #include "../Math/Vector3.h"
- namespace Atomic
- {
- /// 3x3 matrix for rotation and scaling.
- class ATOMIC_API Matrix3
- {
- public:
- /// Construct an identity matrix.
- Matrix3() :
- m00_(1.0f),
- m01_(0.0f),
- m02_(0.0f),
- m10_(0.0f),
- m11_(1.0f),
- m12_(0.0f),
- m20_(0.0f),
- m21_(0.0f),
- m22_(1.0f)
- {
- }
- /// Copy-construct from another matrix.
- Matrix3(const Matrix3& matrix) :
- m00_(matrix.m00_),
- m01_(matrix.m01_),
- m02_(matrix.m02_),
- m10_(matrix.m10_),
- m11_(matrix.m11_),
- m12_(matrix.m12_),
- m20_(matrix.m20_),
- m21_(matrix.m21_),
- m22_(matrix.m22_)
- {
- }
- /// Construct from values.
- Matrix3(float v00, float v01, float v02,
- float v10, float v11, float v12,
- float v20, float v21, float v22) :
- m00_(v00),
- m01_(v01),
- m02_(v02),
- m10_(v10),
- m11_(v11),
- m12_(v12),
- m20_(v20),
- m21_(v21),
- m22_(v22)
- {
- }
- /// Construct from a float array.
- explicit Matrix3(const float* data) :
- m00_(data[0]),
- m01_(data[1]),
- m02_(data[2]),
- m10_(data[3]),
- m11_(data[4]),
- m12_(data[5]),
- m20_(data[6]),
- m21_(data[7]),
- m22_(data[8])
- {
- }
- /// Assign from another matrix.
- Matrix3& operator =(const Matrix3& rhs)
- {
- m00_ = rhs.m00_;
- m01_ = rhs.m01_;
- m02_ = rhs.m02_;
- m10_ = rhs.m10_;
- m11_ = rhs.m11_;
- m12_ = rhs.m12_;
- m20_ = rhs.m20_;
- m21_ = rhs.m21_;
- m22_ = rhs.m22_;
- return *this;
- }
- /// Test for equality with another matrix without epsilon.
- bool operator ==(const Matrix3& rhs) const
- {
- const float* leftData = Data();
- const float* rightData = rhs.Data();
- for (unsigned i = 0; i < 9; ++i)
- {
- if (leftData[i] != rightData[i])
- return false;
- }
- return true;
- }
- /// Test for inequality with another matrix without epsilon.
- bool operator !=(const Matrix3& rhs) const { return !(*this == rhs); }
- /// Multiply a Vector3.
- Vector3 operator *(const Vector3& rhs) const
- {
- return Vector3(
- m00_ * rhs.x_ + m01_ * rhs.y_ + m02_ * rhs.z_,
- m10_ * rhs.x_ + m11_ * rhs.y_ + m12_ * rhs.z_,
- m20_ * rhs.x_ + m21_ * rhs.y_ + m22_ * rhs.z_
- );
- }
- /// Add a matrix.
- Matrix3 operator +(const Matrix3& rhs) const
- {
- return Matrix3(
- m00_ + rhs.m00_,
- m01_ + rhs.m01_,
- m02_ + rhs.m02_,
- m10_ + rhs.m10_,
- m11_ + rhs.m11_,
- m12_ + rhs.m12_,
- m20_ + rhs.m20_,
- m21_ + rhs.m21_,
- m22_ + rhs.m22_
- );
- }
- /// Subtract a matrix.
- Matrix3 operator -(const Matrix3& rhs) const
- {
- return Matrix3(
- m00_ - rhs.m00_,
- m01_ - rhs.m01_,
- m02_ - rhs.m02_,
- m10_ - rhs.m10_,
- m11_ - rhs.m11_,
- m12_ - rhs.m12_,
- m20_ - rhs.m20_,
- m21_ - rhs.m21_,
- m22_ - rhs.m22_
- );
- }
- /// Multiply with a scalar.
- Matrix3 operator *(float rhs) const
- {
- return Matrix3(
- m00_ * rhs,
- m01_ * rhs,
- m02_ * rhs,
- m10_ * rhs,
- m11_ * rhs,
- m12_ * rhs,
- m20_ * rhs,
- m21_ * rhs,
- m22_ * rhs
- );
- }
- /// Multiply a matrix.
- Matrix3 operator *(const Matrix3& rhs) const
- {
- return Matrix3(
- m00_ * rhs.m00_ + m01_ * rhs.m10_ + m02_ * rhs.m20_,
- m00_ * rhs.m01_ + m01_ * rhs.m11_ + m02_ * rhs.m21_,
- m00_ * rhs.m02_ + m01_ * rhs.m12_ + m02_ * rhs.m22_,
- m10_ * rhs.m00_ + m11_ * rhs.m10_ + m12_ * rhs.m20_,
- m10_ * rhs.m01_ + m11_ * rhs.m11_ + m12_ * rhs.m21_,
- m10_ * rhs.m02_ + m11_ * rhs.m12_ + m12_ * rhs.m22_,
- m20_ * rhs.m00_ + m21_ * rhs.m10_ + m22_ * rhs.m20_,
- m20_ * rhs.m01_ + m21_ * rhs.m11_ + m22_ * rhs.m21_,
- m20_ * rhs.m02_ + m21_ * rhs.m12_ + m22_ * rhs.m22_
- );
- }
- /// Set scaling elements.
- void SetScale(const Vector3& scale)
- {
- m00_ = scale.x_;
- m11_ = scale.y_;
- m22_ = scale.z_;
- }
- /// Set uniform scaling elements.
- void SetScale(float scale)
- {
- m00_ = scale;
- m11_ = scale;
- m22_ = scale;
- }
- /// Return the scaling part.
- Vector3 Scale() const
- {
- return Vector3(
- sqrtf(m00_ * m00_ + m10_ * m10_ + m20_ * m20_),
- sqrtf(m01_ * m01_ + m11_ * m11_ + m21_ * m21_),
- sqrtf(m02_ * m02_ + m12_ * m12_ + m22_ * m22_)
- );
- }
- /// Return the scaling part with the sign. Reference rotation matrix is required to avoid ambiguity.
- Vector3 SignedScale(const Matrix3& rotation) const
- {
- return Vector3(
- rotation.m00_ * m00_ + rotation.m10_ * m10_ + rotation.m20_ * m20_,
- rotation.m01_ * m01_ + rotation.m11_ * m11_ + rotation.m21_ * m21_,
- rotation.m02_ * m02_ + rotation.m12_ * m12_ + rotation.m22_ * m22_
- );
- }
- /// Return transposed.
- Matrix3 Transpose() const
- {
- return Matrix3(
- m00_,
- m10_,
- m20_,
- m01_,
- m11_,
- m21_,
- m02_,
- m12_,
- m22_
- );
- }
- /// Return scaled by a vector.
- Matrix3 Scaled(const Vector3& scale) const
- {
- return Matrix3(
- m00_ * scale.x_,
- m01_ * scale.y_,
- m02_ * scale.z_,
- m10_ * scale.x_,
- m11_ * scale.y_,
- m12_ * scale.z_,
- m20_ * scale.x_,
- m21_ * scale.y_,
- m22_ * scale.z_
- );
- }
- /// Test for equality with another matrix with epsilon.
- bool Equals(const Matrix3& rhs) const
- {
- const float* leftData = Data();
- const float* rightData = rhs.Data();
- for (unsigned i = 0; i < 9; ++i)
- {
- if (!Atomic::Equals(leftData[i], rightData[i]))
- return false;
- }
- return true;
- }
- /// Return inverse.
- Matrix3 Inverse() const;
- /// Return float data.
- const float* Data() const { return &m00_; }
- /// Return matrix element.
- float Element(unsigned i, unsigned j) const { return Data()[i * 3 + j]; }
- /// Return matrix row.
- Vector3 Row(unsigned i) const { return Vector3(Element(i, 0), Element(i, 1), Element(i, 2)); }
- /// Return matrix column.
- Vector3 Column(unsigned j) const { return Vector3(Element(0, j), Element(1, j), Element(2, j)); }
- /// Return as string.
- String ToString() const;
- float m00_;
- float m01_;
- float m02_;
- float m10_;
- float m11_;
- float m12_;
- float m20_;
- float m21_;
- float m22_;
- /// Bulk transpose matrices.
- static void BulkTranspose(float* dest, const float* src, unsigned count)
- {
- for (unsigned i = 0; i < count; ++i)
- {
- dest[0] = src[0];
- dest[1] = src[3];
- dest[2] = src[6];
- dest[3] = src[1];
- dest[4] = src[4];
- dest[5] = src[7];
- dest[6] = src[2];
- dest[7] = src[5];
- dest[8] = src[8];
- dest += 9;
- src += 9;
- }
- }
- /// Zero matrix.
- static const Matrix3 ZERO;
- /// Identity matrix.
- static const Matrix3 IDENTITY;
- };
- /// Multiply a 3x3 matrix with a scalar.
- inline Matrix3 operator *(float lhs, const Matrix3& rhs) { return rhs * lhs; }
- }
|