| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /*
- FinalSun/FinalAlert 2 Mission Editor
- Copyright (C) 1999-2024 Electronic Arts, Inc.
- Authored by Matthias Wagner
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- #pragma once
- #include <cassert>
- template<class T>
- class Vec3
- {
- public:
- Vec3() = default;
- Vec3(T x, T y, T z) : v{ x, y, z }
- {
- }
- Vec3(T v_[3]) : v{ v_[0], v_[1], v_[2] }
- {
- }
- T& operator[](unsigned int i) {
- assert(i < 3);
- return v[i];
- }
- const T& operator[](unsigned int i) const {
- assert(i < 3);
- return v[i];
- }
- inline T dot(const Vec3& other) const {
- return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2];
- }
- inline T length() const
- {
- return sqrt(squaredLength());
- }
- inline T squaredLength() const
- {
- return dot(*this);
- }
- inline Vec3& normalize()
- {
- T invL = T(1) / length();
- v[0] *= invL;
- v[1] *= invL;
- v[2] *= invL;
- return *this;
- }
- inline Vec3& negate()
- {
- v[0] = -v[0];
- v[1] = -v[1];
- v[2] = -v[2];
- return *this;
- }
- inline Vec3& inverse()
- {
- v[0] = T(1) / v[0];
- v[1] = T(1) / v[1];
- v[2] = T(1) / v[2];
- return *this;
- }
- inline Vec3& minimum(const Vec3& v2)
- {
- v[0] = min(v[0], v2[0]);
- v[1] = min(v[1], v2[1]);
- v[2] = min(v[2], v2[2]);
- return *this;
- }
- inline Vec3& maximum(const Vec3& v2)
- {
- v[0] = max(v[0], v2[0]);
- v[1] = max(v[1], v2[1]);
- v[2] = max(v[2], v2[2]);
- return *this;
- }
- inline Vec3& operator *=(const Vec3& v2) {
- v[0] *= v2[0];
- v[1] *= v2[1];
- v[2] *= v2[2];
- return *this;
- }
- inline Vec3& operator *=(const T scale) {
- v[0] *= scale;
- v[1] *= scale;
- v[2] *= scale;
- return *this;
- }
- inline Vec3& operator /=(const Vec3& v2) {
- v[0] /= v2[0];
- v[1] /= v2[1];
- v[2] /= v2[2];
- return *this;
- }
- inline Vec3& operator /=(const T scale) {
- v[0] /= scale;
- v[1] /= scale;
- v[2] /= scale;
- return *this;
- }
- inline Vec3& operator +=(const Vec3& other) {
- v[0] += other.v[0];
- v[1] += other.v[1];
- v[2] += other.v[2];
- return *this;
- }
- inline Vec3& operator -=(const Vec3& other) {
- v[0] -= other.v[0];
- v[1] -= other.v[1];
- v[2] -= other.v[2];
- return *this;
- }
- inline bool equals(const Vec3& other, T epsilon=T(0.001))
- {
- return fabs(v[0] - other.v[0]) <= epsilon && fabs(v[1] - other.v[1]) <= epsilon && fabs(v[2] - other.v[2]) <= epsilon;
- }
- T x() const { return v[0]; }
- T y() const { return v[1]; }
- T z() const { return v[2]; }
- T v[3] = { 0, 0, 0 };
- };
- template< class T>
- inline Vec3<T> operator+(const Vec3<T>& l, const Vec3<T>& r)
- {
- auto res = l;
- res += r;
- return res;
- }
- template< class T>
- inline Vec3<T> operator-(const Vec3<T>& l, const Vec3<T>& r)
- {
- auto res = l;
- res -= r;
- return res;
- }
- template< class T>
- inline Vec3<T> normalize(Vec3<T> v)
- {
- return v.normalize();
- }
- template< class T>
- inline Vec3<T> negate(Vec3<T> v)
- {
- return v.negate();
- }
- template< class T>
- inline Vec3<T> inverse(Vec3<T> v)
- {
- return v.inverse();
- }
- template< class T>
- inline Vec3<T> minimum(Vec3<T> v, const Vec3<T>& v2)
- {
- v.minimum(v2);
- return v;
- }
- template< class T>
- inline Vec3<T> maximum(Vec3<T> v, const Vec3<T>& v2)
- {
- v.maximum(v2);
- return v;
- }
- template< class T>
- inline Vec3<T> operator /(Vec3<T> v, T scale)
- {
- v /= scale;
- return v;
- }
- template< class T>
- inline Vec3<T> operator *(Vec3<T> v, Vec3<T> v2)
- {
- v *= v2;
- return v;
- }
- template< class T>
- inline Vec3<T> operator /(Vec3<T> v, Vec3<T> v2)
- {
- v /= v2;
- return v;
- }
- template< class T>
- inline Vec3<T> operator *(Vec3<T> v, T scale)
- {
- v *= scale;
- return v;
- }
- typedef Vec3<float> Vec3f;
- template<class T>
- class Matrix3_4
- {
- public:
- Matrix3_4(const T (&m_)[3][4])
- {
- for (int row = 0; row < 3; ++row)
- {
- for (int col = 0; col < 4; ++col)
- {
- m[row][col] = m_[row][col];
- }
- }
- }
- Matrix3_4(const T* m_)
- {
- for (int row = 0; row < 3; ++row)
- {
- for (int col = 0; col < 4; ++col)
- {
- m[row][col] = m_[row * 4 + col];
- }
- }
- }
-
- Vec3<T> operator *(const Vec3<T> v) const
- {
- auto x = v[0];
- auto y = v[1];
- auto z = v[2];
- return Vec3<T>(
- x * m[0][0] + y * m[0][1] + z * m[0][2] + m[0][3],
- x * m[1][0] + y * m[1][1] + z * m[1][2] + m[1][3],
- x * m[2][0] + y * m[2][1] + z * m[2][2] + m[2][3]
- );
- }
- Matrix3_4& scaledColumn(unsigned int iColumn, T scale)
- {
- assert(iColumn < 4);
- m[0][iColumn] *= scale;
- m[1][iColumn] *= scale;
- m[2][iColumn] *= scale;
- return *this;
- }
- Matrix3_4 scaleColumn(unsigned int iColumn, T scale) const
- {
- assert(iColumn < 4);
- Matrix3_4 copy(*this);
- copy.m[0][iColumn] *= scale;
- copy.m[1][iColumn] *= scale;
- copy.m[2][iColumn] *= scale;
- return copy;
- }
- Matrix3_4& setColumn(unsigned int iColumn, const Vec3<T>& v)
- {
- assert(iColumn < 4);
- m[0][iColumn] = v[0];
- m[1][iColumn] = v[1];
- m[2][iColumn] = v[2];
- return *this;
- }
- Vec3f getColumn(unsigned int iColumn) const
- {
- assert(iColumn < 4);
- return Vec3f(m[0][iColumn], m[1][iColumn], m[2][iColumn]);
- }
- static Matrix3_4 translation(const Vec3<T> v)
- {
- return Matrix3_4({ {1, 0, 0, v.x()}, {0, 1, 0, v.y()}, {0, 0, 1, v.z()}});
- }
- static Matrix3_4 scale(const Vec3<T> v)
- {
- return Matrix3_4({ {v.x(), 0, 0, 0}, {0, v.y(), 0, 0}, {0, 0, v.z(), 0}});
- }
- public:
- T m[3][4] = { {1, 0, 0, 1}, {0, 1, 0, 1}, {0, 0, 1, 1}};
- };
- typedef Matrix3_4<float> Matrix3_4f;
|