Vec3.h
上传用户:chinafayin
上传日期:2022-04-05
资源大小:153k
文件大小:11k
源码类别:

并行计算

开发平台:

Visual C++

  1. /*
  2.     Linear Algebra / Math library
  3.     Copyright (C) 2003-2009, Marek Olsak (maraeo@gmail.com), All Rights Reserved.
  4.     Copyright (C) 2003-2005, Tomas Pastorek (tomas@tomaspastorek.cz), All Rights Reserved.
  5.     This program is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU General Public License
  7.     as published by the Free Software Foundation; either version 2
  8.     of the License, or (at your option) any later version.
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.     You should have received a copy of the GNU General Public License
  14.     along with this program; if not, write to the Free Software
  15.     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  16. */
  17. #pragma once
  18. namespace Rune
  19. {
  20.     /**
  21.         Trirozmerny vektor
  22.     **************************************************************************************************/
  23.     template<typename T>
  24.     class Vec3
  25.     {
  26.     public:
  27.         T x, y, z;
  28.         template<typename U>
  29.         explicit Vec3(const Vec3<U> &v) { x = T(v.x); y = T(v.y); z = T(v.z); }
  30.         typedef Rune::Vec2<T> Vec2;
  31.         Vec3() {}
  32.         Vec3(T f)                                       { x = f; y = f; z = f; }
  33.         Vec3(const Vec2 &v, T Z)                        { x = v.x; y = v.y; z = Z; }
  34.         Vec3(T X, const Vec2 &v)                        { x = X; y = v.x; z = v.y; }
  35.         Vec3(T X, T Y, T Z)                             { x = X; y = Y; z = Z; }
  36.         bool operator ==(const Vec3 &v) const           { return x == v.x && y == v.y && z == v.z; }
  37.         bool operator !=(const Vec3 &v) const           { return x != v.x && y != v.y && z != v.z; }
  38.         bool operator <(const Vec3 &v) const            { return x < v.x && y < v.y && z < v.z; }
  39.         bool operator >(const Vec3 &v) const            { return x > v.x && y > v.y && z > v.z; }
  40.         bool operator <=(const Vec3 &v) const           { return x <= v.x && y <= v.y && z <= v.z; }
  41.         bool operator >=(const Vec3 &v) const           { return x >= v.x && y >= v.y && z >= v.z; }
  42.         bool operator ==(T f) const                     { return x == f && y == f && z == f; }
  43.         bool operator !=(T f) const                     { return x != f && y != f && z != f; }
  44.         bool operator <(T f) const                      { return x < f && y < f && z < f; }
  45.         bool operator >(T f) const                      { return x > f && y > f && z > f; }
  46.         bool operator <=(T f) const                     { return x <= f && y <= f && z <= f; }
  47.         bool operator >=(T f) const                     { return x >= f && y >= f && z >= f; }
  48.         void operator =(const Vec3 &v)                  { x = v.x; y = v.y; z = v.z; }
  49.         void operator +=(const Vec3 &v)                 { x += v.x; y += v.y; z += v.z; }
  50.         void operator +=(T f)                           { x += f; y += f; z += f; }
  51.         void operator -=(const Vec3 &v)                 { x -= v.x; y -= v.y; z -= v.z; }
  52.         void operator -=(T f)                           { x -= f; y -= f; z -= f; }
  53.         void operator *=(T f)                           { x *= f; y *= f; z *= f; }
  54.         void operator /=(T f)                           { x /= f; y /= f; z /= f; }
  55.         Vec3 operator +(const Vec3 &v) const            { return Vec3(x+v.x, y+v.y, z+v.z); }
  56.         Vec3 operator +(T f) const                      { return Vec3(x+f, y+f, z+f); }
  57.         Vec3 operator -(const Vec3 &v) const            { return Vec3(x-v.x, y-v.y, z-v.z); }
  58.         Vec3 operator -(T f) const                      { return Vec3(x-f, y-f, z-f); }
  59.         Vec3 operator *(const Vec3 &v) const            { return Vec3(x*v.x, y*v.y, z*v.z); }
  60.         Vec3 operator *(T f) const                      { return Vec3(x*f, y*f, z*f); }
  61.         Vec3 operator /(const Vec3 &v) const            { return Vec3(x/v.x, y/v.y, z/v.z); }
  62.         Vec3 operator /(T f) const                      { return Vec3(x/f, y/f, z/f); }
  63.         Vec3 operator -() const                         { return Vec3(-x, -y, -z); }
  64.         T& operator [](int i)                           { return (&x)[i]; }
  65.         T operator [](int i) const                      { return (&x)[i]; }
  66.         T Cube() const                                  { return x*y*z; }
  67.         T GetMax() const                                { return Math<T>::Max(Math<T>::Max(x, y), z); }
  68.         Vec3 GetAbs() const                             { return Vec3(Math<T>::Abs(x), Math<T>::Abs(y), Math<T>::Abs(z)); }
  69.         Vec3 GetNormalized() const                      { T f = MagnitudeInv(); return Vec3(x*f, y*f, z*f); }
  70.         T Magnitude() const                             { return Math<T>::Sqrt(MagnitudeSqr()); }
  71.         T MagnitudeInv() const                          { return Math<T>::Rsqrt(MagnitudeSqr()); }
  72.         T MagnitudeSqr() const                          { return x*x + y*y + z*z; }
  73.         Vec3 Reflect(const Vec3 &normal) const          { return *this - 2*Dot(normal, *this)*normal; }
  74.         Vec3 Project(const Vec3 &v) const               { return *this * Dot(v, *this)/MagnitudeSqr(); }
  75.         Vec3 Orthogonalize(const Vec3 &v) const         { return v - Project(v); }
  76.         void Normalize()                                { operator *=(MagnitudeInv()); }
  77.         void PackTo01()                                 { operator *=(T(0.5)); operator +=(T(0.5)); }
  78.         void PackBack()                                 { operator *=(2); operator -=(1); }
  79.         void Set(T X, T Y, T Z)                         { x = X; y = Y; z = Z; }
  80.         void Rotate(const Vec3 &v, const T angle)       { Rotate(v.x, v.y, v.z, angle); }
  81.         void Inverse()                                  { x = 1/x; y = 1/y; z = 1/z; }
  82.         Vec3 Frac() const                               { return Vec3(Math<T>::Frac(x), Math<T>::Frac(y), Math<T>::Frac(z)); }
  83.         bool SafeIsEqual(const Vec3 &v) const
  84.         {
  85.             return Math<T>::SafeIsEqual(x, v.x) && Math<T>::SafeIsEqual(y, v.y) && Math<T>::SafeIsEqual(z, v.z);
  86.         }
  87.         /**
  88.             Rotuje vektor kolem rotacni osy (x,y,z) uhlem angle
  89.         **************************************************************************************************/
  90.         void Rotate(T x, T y, T z, T angle)
  91.         {
  92.             T s = Math<T>::SinDeg(angle), c = Math<T>::CosDeg(angle);
  93.             T cr = 1-c, xx = x*x, xy = x*y, xz = x*z, yy = y*y, yz = y*z, zz = z*z, sx = s*x, sy = s*y, sz = s*z;
  94.             Vec3<T> r1(xx+c*(1-xx), xy*cr-sz,    xz*cr+sy);
  95.             Vec3<T> r2(xy*cr+sz,    yy+c*(1-yy), yz*cr-sx);
  96.             Vec3<T> r3(xz*cr-sy,    yz*cr+sx,    zz+c*(1-zz));
  97.             Set(Dot(*this, r1), Dot(*this, r2), Dot(*this, r3));
  98.         }
  99.         /**
  100.             Rotuje vektor kolem osy X uhlem angle
  101.         **************************************************************************************************/
  102.         void RotateX(T angle)
  103.         {
  104.             T s = Math<T>::SinDeg(angle), c = Math<T>::CosDeg(angle);
  105.             Set(x, y*c-z*s, y*s+z*c);
  106.         }
  107.         /**
  108.             Rotuje vektor kolem osy Y uhlem angle
  109.         **************************************************************************************************/
  110.         void RotateY(T angle)
  111.         {
  112.             T s = Math<T>::SinDeg(angle), c = Math<T>::CosDeg(angle);
  113.             Set(x*c+z*s, y, -x*s+z*c);
  114.         }
  115.         /**
  116.             Rotuje vektor kolem osy Z uhlem angle
  117.         **************************************************************************************************/
  118.         void RotateZ(T angle)
  119.         {
  120.             T s = Math<T>::SinDeg(angle), c = Math<T>::CosDeg(angle);
  121.             Set(x*c-y*s, x*s+y*c, z);
  122.         }
  123.         static T Dot(const Vec3 &v1, const Vec3 &v2)
  124.         {
  125.             return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
  126.         }
  127.         static Vec3 Cross(const Vec3 &v1, const Vec3 &v2)
  128.         {
  129.             return Vec3(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
  130.         }
  131.         template<typename Operator>
  132.         static Vec3 ScalarOperator(const Vec3 &v1, const Vec3 &v2, Operator &op)
  133.         {
  134.             return Vec3(op(v1.x, v2.x), op(v1.y, v2.y), op(v1.z, v2.z));
  135.         }
  136.         static T DistanceSqr(const Vec3 &v1, const Vec3 &v2)
  137.         {
  138.             return (v1 - v2).MagnitudeSqr();
  139.         }
  140.         static T Distance(const Vec3 &v1, const Vec3 &v2)
  141.         {
  142.             return Math<T>::Sqrt(DistanceSqr(v1, v2));
  143.         }
  144.         static Vec3 CalculateNormal(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2)
  145.         {
  146.             return CalculateNormalUnnorm(v0, v1, v2).GetNormalized();
  147.         }
  148.         static Vec3 CalculateNormalUnnorm(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2)
  149.         {
  150.             return Cross(v2-v1, v0-v2);
  151.         }
  152.         static Vec3 Center(const Vec3 &min, const Vec3 &max)
  153.         {
  154.             return (min + max) * T(0.5);
  155.         }
  156.         static T Angle(const Vec3 &a, const Vec3 &b)
  157.         {
  158.             return Math<T>::Acos(Dot(a, b)*a.MagnitudeInv()*b.MagnitudeInv());
  159.         }
  160.         static T AngleUnnorm(const Vec3 &a, const Vec3 &b)
  161.         {
  162.             return Math<T>::Acos(Dot(a, b));
  163.         }
  164.         /**
  165.             Vraci tangent vektor (vektor mapovani textury pro normalmapping), vstupem jsou vertexy
  166.             trojuhelniku a jeho texturove koordinaty
  167.         **************************************************************************************************/
  168.         static Vec3 CalculateTangent(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec2 &t0, const Vec2 &t1, const Vec2 &t2)
  169.         {
  170.             return ((v1 - v0) * (t2.y - t0.y) + (v2 - v0) * (t0.y - t1.y)).GetNormalized();
  171.         }
  172.         /**
  173.             Vraci bitangent vektor (vektor mapovani textury pro normalmapping), vstupem jsou vertexy
  174.             trojuhelniku a jeho texturove koordinaty
  175.         **************************************************************************************************/
  176.         static Vec3 CalculateBitangent(const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, const Vec2 &t0, const Vec2 &t1, const Vec2 &t2)
  177.         {
  178.             return ((v1 - v0) * (t2.x - t0.x) + (v2 - v0) * (t0.x - t1.x)).GetNormalized();
  179.         }
  180.         /**
  181.             Vraci obsah trojuhelniku
  182.         **************************************************************************************************/
  183.         static T CalculateAreaOfTriangle(const Vec3 &a, const Vec3 &b, const Vec3 &c)
  184.         {
  185.             return Cross(b - a, c - a).Magnitude() * T(0.5);
  186.         }
  187.     };
  188.     template<typename T>
  189.     std::ostream& operator <<(std::ostream &stream, const Vec3<T> &v)
  190.     {
  191.         return stream << ("(" + tostrf(v.x) + ", " + tostrf(v.y) + ", " + tostrf(v.z) + ")");
  192.     }
  193.     template<typename T>
  194.     std::istream& operator >>(std::istream &stream, Vec3<T> &v)
  195.     {
  196.         char tmp;
  197.         return stream >> tmp >> v.x >> tmp >> v.y >> tmp >> v.z >> tmp;
  198.     }
  199.     typedef Vec3<float> Vec3f;
  200.     typedef Vec3<double> Vec3d;
  201.     typedef Vec3<int32> Vec3i;
  202.     typedef Vec3<uint32> Vec3ui;
  203.     typedef Vec3<bool> Vec3b;
  204. }