LCOV - code coverage report
Current view: top level - ezlibs - ezVec3.hpp (source / functions) Coverage Total Hit
Test: Coverage (llvm-cov → lcov → genhtml) Lines: 87.8 % 82 72
Test Date: 2025-09-16 22:55:37 Functions: 97.9 % 146 143
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 66.1 % 112 74

             Branch data     Line data    Source code
       1                 :             : #pragma once
       2                 :             : 
       3                 :             : #ifndef EZ_TOOLS_VEC3
       4                 :             : #define EZ_TOOLS_VEC3
       5                 :             : #endif  // EZ_TOOLS_VEC3
       6                 :             : 
       7                 :             : /*
       8                 :             : MIT License
       9                 :             : 
      10                 :             : Copyright (c) 2014-2024 Stephane Cuillerdier (aka aiekick)
      11                 :             : 
      12                 :             : Permission is hereby granted, free of charge, to any person obtaining a copy
      13                 :             : of this software and associated documentation files (the "Software"), to deal
      14                 :             : in the Software without restriction, including without limitation the rights
      15                 :             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      16                 :             : copies of the Software, and to permit persons to whom the Software is
      17                 :             : furnished to do so, subject to the following conditions:
      18                 :             : 
      19                 :             : The above copyright notice and this permission notice shall be included in all
      20                 :             : copies or substantial portions of the Software.
      21                 :             : 
      22                 :             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      23                 :             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      25                 :             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      27                 :             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      28                 :             : SOFTWARE.
      29                 :             : */
      30                 :             : 
      31                 :             : // ezVec3 is part of the ezLibs project : https://github.com/aiekick/ezLibs.git
      32                 :             : 
      33                 :             : #include <type_traits>
      34                 :             : #include <cmath>
      35                 :             : #include <string>
      36                 :             : #include <vector>
      37                 :             : 
      38                 :             : namespace ez {
      39                 :             : 
      40                 :             : // Restrict the template to relevant types only (e.g., disable bool)
      41                 :             : template <typename T>
      42                 :             : struct vec3 {
      43                 :             :     static_assert(!std::is_same<T, bool>::value, "vec3 cannot be instantiated with bool type");
      44                 :             : 
      45                 :             :     T x = static_cast<T>(0), y = static_cast<T>(0), z = static_cast<T>(0);
      46                 :             : 
      47                 :             :     // Default constructor
      48                 :          11 :     vec3() : x(static_cast<T>(0)), y(static_cast<T>(0)), z(static_cast<T>(0)) {}
      49                 :             : 
      50                 :             :     // Constructor with type conversion
      51                 :             :     template <typename U>
      52                 :             :     vec3(const vec3<U>& a) : x(static_cast<T>(a.x)), y(static_cast<T>(a.y)), z(static_cast<T>(a.z)) {}
      53                 :             : 
      54                 :             :     // Constructor with type conversion
      55                 :             :     template <typename U>
      56                 :             :     vec3(const U& a) : x(static_cast<T>(a.x)), y(static_cast<T>(a.y)), z(static_cast<T>(a.z)) {}
      57                 :             : 
      58                 :             :     // Constructor for uniform initialization
      59                 :          42 :     vec3(T xyz) : x(xyz), y(xyz), z(xyz) {}
      60                 :             : 
      61                 :             :     // Constructor with specific values
      62                 :     6458030 :     vec3(T x, T y, T z) : x(x), y(y), z(z) {}
      63                 :             : 
      64                 :             :     // Constructor using a vec2 and a scalar
      65                 :             :     // Assumption: vec2<T> is defined elsewhere, as it is referenced but not included here.
      66                 :             :     vec3(const vec2<T>& xy, T z) : x(xy.x), y(xy.y), z(z) {}
      67                 :             : 
      68                 :             :     // Constructor from string
      69                 :             :     vec3(const std::string& vec, char c = ';', vec3<T>* def = nullptr) {
      70                 :             :         if (def) {
      71                 :             :             x = def->x;
      72                 :             :             y = def->y;
      73                 :             :             z = def->z;
      74                 :             :         }
      75                 :             :         std::vector<T> result = str::stringToNumberVector<T>(vec, c);
      76                 :             :         const size_t s = result.size();
      77                 :             :         if (s > 0)
      78                 :             :             x = result[0];
      79                 :             :         if (s > 1)
      80                 :             :             y = result[1];
      81                 :             :         if (s > 2)
      82                 :             :             z = result[2];
      83                 :             :     }
      84                 :             : 
      85                 :             :     // Indexing operator
      86                 :             :     T& operator[](size_t i) { return (&x)[i]; }
      87                 :             : 
      88                 :             :     // Offset the vector
      89                 :           6 :     vec3 Offset(T vX, T vY, T vZ) const { return vec3(x + vX, y + vY, z + vZ); }
      90                 :             : 
      91                 :             :     // Set the vector's components
      92                 :           6 :     void Set(T vX, T vY, T vZ) {
      93                 :           6 :         x = vX;
      94                 :           6 :         y = vY;
      95                 :           6 :         z = vZ;
      96                 :           6 :     }
      97                 :             : 
      98                 :             :     operator vec2<T>() const { return vec2<T>(x, y); }
      99                 :             : 
     100                 :             :     // Negation operator
     101                 :           4 :     vec3 operator-() const {
     102                 :           4 :         static_assert(std::is_signed<T>::value, "Negate is only valid for signed types");
     103                 :           4 :         return vec3(-x, -y, -z);
     104                 :           4 :     }
     105                 :             : 
     106                 :             :     // Logical NOT operator, only for integral types
     107                 :           2 :     vec3 operator!() const {
     108                 :           2 :         static_assert(std::is_integral<T>::value, "Logical NOT is only valid for integral types");
     109                 :           2 :         return vec3(!x, !y, !z);
     110                 :           2 :     }
     111                 :             : 
     112                 :             :     // Extract 2D vectors from 3D vector
     113                 :           6 :     vec2<T> xy() const { return vec2<T>(x, y); }
     114                 :             : 
     115                 :           6 :     vec2<T> xz() const { return vec2<T>(x, z); }
     116                 :             : 
     117                 :           6 :     vec2<T> yz() const { return vec2<T>(y, z); }
     118                 :             : 
     119                 :             :     // Cyclic permutation
     120                 :           6 :     vec3 yzx() const { return vec3(y, z, x); }
     121                 :             : 
     122                 :             :     // Pre-increment and pre-decrement operators
     123                 :           6 :     vec3& operator++() {
     124                 :           6 :         ++x;
     125                 :           6 :         ++y;
     126                 :           6 :         ++z;
     127                 :           6 :         return *this;
     128                 :           6 :     }
     129                 :             : 
     130                 :           6 :     vec3& operator--() {
     131                 :           6 :         --x;
     132                 :           6 :         --y;
     133                 :           6 :         --z;
     134                 :           6 :         return *this;
     135                 :           6 :     }
     136                 :             : 
     137                 :             :     // Post-increment and post-decrement operators
     138                 :             :     vec3 operator++(int) {
     139                 :             :         vec3 tmp = *this;
     140                 :             :         ++*this;
     141                 :             :         return tmp;
     142                 :             :     }
     143                 :             : 
     144                 :             :     vec3 operator--(int) {
     145                 :             :         vec3 tmp = *this;
     146                 :             :         --*this;
     147                 :             :         return tmp;
     148                 :             :     }
     149                 :             : 
     150                 :             :     // Compound assignment operators
     151                 :             :     void operator+=(T a) {
     152                 :             :         x += a;
     153                 :             :         y += a;
     154                 :             :         z += a;
     155                 :             :     }
     156                 :             : 
     157                 :             :     void operator+=(const vec3& v) {
     158                 :             :         x += v.x;
     159                 :             :         y += v.y;
     160                 :             :         z += v.z;
     161                 :             :     }
     162                 :             : 
     163                 :             :     void operator-=(T a) {
     164                 :             :         x -= a;
     165                 :             :         y -= a;
     166                 :             :         z -= a;
     167                 :             :     }
     168                 :             : 
     169                 :             :     void operator-=(const vec3& v) {
     170                 :             :         x -= v.x;
     171                 :             :         y -= v.y;
     172                 :             :         z -= v.z;
     173                 :             :     }
     174                 :             : 
     175                 :             :     void operator*=(T a) {
     176                 :             :         x *= a;
     177                 :             :         y *= a;
     178                 :             :         z *= a;
     179                 :             :     }
     180                 :             : 
     181                 :             :     void operator*=(const vec3& v) {
     182                 :             :         x *= v.x;
     183                 :             :         y *= v.y;
     184                 :             :         z *= v.z;
     185                 :             :     }
     186                 :             : 
     187                 :             :     void operator/=(T a) {
     188                 :             :         x /= a;
     189                 :             :         y /= a;
     190                 :             :         z /= a;
     191                 :             :     }
     192                 :             : 
     193                 :             :     void operator/=(const vec3& v) {
     194                 :             :         x /= v.x;
     195                 :             :         y /= v.y;
     196                 :             :         z /= v.z;
     197                 :             :     }
     198                 :             : 
     199                 :             :     // Length of the vector
     200                 :           6 :     T length() const { return static_cast<T>(ez::sqrt(lengthSquared())); }
     201                 :             : 
     202                 :             :     // Squared length of the vector
     203                 :           6 :     T lengthSquared() const { return x * x + y * y + z * z; }
     204                 :             : 
     205                 :             :     // Normalize the vector
     206                 :           2 :     T normalize() {
     207                 :           2 :         T _length = length();
     208 [ -  + ][ -  + ]:           2 :         if (_length < std::numeric_limits<T>::epsilon())
     209                 :           0 :             return static_cast<T>(0);
     210                 :           2 :         T _invLength = static_cast<T>(1) / _length;
     211                 :           2 :         x *= _invLength;
     212                 :           2 :         y *= _invLength;
     213                 :           2 :         z *= _invLength;
     214                 :           2 :         return _length;
     215                 :           2 :     }
     216                 :             : 
     217                 :             :     // Get a normalized copy of the vector
     218                 :             :     vec3 GetNormalized() const {
     219                 :             :         vec3 n(x, y, z);
     220                 :             :         n.normalize();
     221                 :             :         return n;
     222                 :             :     }
     223                 :             : 
     224                 :             :     // Sum of components
     225                 :           6 :     T sum() const { return x + y + z; }
     226                 :             : 
     227                 :             :     // Sum of absolute values of components
     228                 :           4 :     T sumAbs() const { return ez::abs(x) + ez::abs(y) + ez::abs(z); }
     229                 :             : 
     230                 :             :     // Check if all components are zero (AND)
     231 [ +  + ][ +  + ]:          12 :     bool emptyAND() const { return x == static_cast<T>(0) && y == static_cast<T>(0) && z == static_cast<T>(0); }
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     232                 :             : 
     233                 :             :     // Check if any component is zero (OR)
     234 [ +  + ][ +  + ]:          12 :     bool emptyOR() const { return x == static_cast<T>(0) || y == static_cast<T>(0) || z == static_cast<T>(0); }
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
     235                 :             : 
     236                 :             :     // Convert to string
     237                 :           6 :     std::string string(char c = ';') const { return ez::str::toStr(x) + c + ez::str::toStr(y) + c + ez::str::toStr(z); }
     238                 :             : 
     239                 :             :     // Minimum component
     240                 :           6 :     T mini() const { return ez::mini(x, ez::mini(y, z)); }
     241                 :             : 
     242                 :             :     // Maximum component
     243                 :           6 :     T maxi() const { return ez::maxi(x, ez::maxi(y, z)); }
     244                 :             : };
     245                 :             : 
     246                 :             : // Operators for vec3
     247                 :             : template <typename T>
     248                 :             : inline vec3<T> operator+(const vec3<T>& v, T f) {
     249                 :             :     return vec3<T>(v.x + f, v.y + f, v.z + f);
     250                 :             : }
     251                 :             : 
     252                 :             : template <typename T>
     253                 :             : inline vec3<T> operator+(T f, const vec3<T>& v) {
     254                 :             :     return vec3<T>(v.x + f, v.y + f, v.z + f);
     255                 :             : }
     256                 :             : 
     257                 :             : template <typename T>
     258                 :          47 : inline vec3<T> operator+(const vec3<T>& v, const vec3<T>& f) {
     259                 :          47 :     return vec3<T>(v.x + f.x, v.y + f.y, v.z + f.z);
     260                 :          47 : }
     261                 :             : 
     262                 :             : template <typename T>
     263                 :             : inline vec3<T> operator-(const vec3<T>& v, T f) {
     264                 :             :     return vec3<T>(v.x - f, v.y - f, v.z - f);
     265                 :             : }
     266                 :             : 
     267                 :             : template <typename T>
     268                 :             : inline vec3<T> operator-(T f, const vec3<T>& v) {
     269                 :             :     return vec3<T>(f - v.x, f - v.y, f - v.z);
     270                 :             : }
     271                 :             : 
     272                 :             : template <typename T>
     273                 :          49 : inline vec3<T> operator-(const vec3<T>& v, const vec3<T>& f) {
     274                 :          49 :     return vec3<T>(v.x - f.x, v.y - f.y, v.z - f.z);
     275                 :          49 : }
     276                 :             : 
     277                 :             : template <typename T>
     278                 :           6 : inline vec3<T> operator*(const vec3<T>& v, T f) {
     279                 :           6 :     return vec3<T>(v.x * f, v.y * f, v.z * f);
     280                 :           6 : }
     281                 :             : 
     282                 :             : template <typename T>
     283                 :             : inline vec3<T> operator*(T f, const vec3<T>& v) {
     284                 :             :     return vec3<T>(v.x * f, v.y * f, v.z * f);
     285                 :             : }
     286                 :             : 
     287                 :             : template <typename T>
     288                 :             : inline vec3<T> operator*(const vec3<T>& v, const vec3<T>& f) {
     289                 :             :     return vec3<T>(v.x * f.x, v.y * f.y, v.z * f.z);
     290                 :             : }
     291                 :             : 
     292                 :             : template <typename T>
     293                 :          47 : inline vec3<T> operator/(const vec3<T>& v, T f) {
     294                 :          47 :     return vec3<T>(v.x / f, v.y / f, v.z / f);
     295                 :          47 : }
     296                 :             : 
     297                 :             : template <typename T>
     298                 :             : inline vec3<T> operator/(T f, const vec3<T>& v) {
     299                 :             :     return vec3<T>(f / v.x, f / v.y, f / v.z);
     300                 :             : }
     301                 :             : 
     302                 :             : template <typename T>
     303                 :             : inline vec3<T> operator/(const vec3<T>& v, const vec3<T>& f) {
     304                 :             :     return vec3<T>(v.x / f.x, v.y / f.y, v.z / f.z);
     305                 :             : }
     306                 :             : 
     307                 :             : // Comparison operators
     308                 :             : template <typename T>
     309                 :             : inline bool operator<(const vec3<T>& v, const vec3<T>& f) {
     310                 :             :     return v.x < f.x && v.y < f.y && v.z < f.z;
     311                 :             : }
     312                 :             : 
     313                 :             : template <typename T>
     314                 :             : inline bool operator<(const vec3<T>& v, T f) {
     315                 :             :     return v.x < f && v.y < f && v.z < f;
     316                 :             : }
     317                 :             : 
     318                 :             : template <typename T>
     319                 :             : inline bool operator<(T f, const vec3<T>& v) {
     320                 :             :     return f < v.x && f < v.y && f < v.z;
     321                 :             : }
     322                 :             : 
     323                 :             : template <typename T>
     324                 :             : inline bool operator>(const vec3<T>& v, const vec3<T>& f) {
     325                 :             :     return v.x > f.x && v.y > f.y && v.z > f.z;
     326                 :             : }
     327                 :             : 
     328                 :             : template <typename T>
     329                 :             : inline bool operator>(const vec3<T>& v, T f) {
     330                 :             :     return v.x > f && v.y > f && v.z > f;
     331                 :             : }
     332                 :             : 
     333                 :             : template <typename T>
     334                 :             : inline bool operator>(T f, const vec3<T>& v) {
     335                 :             :     return f > v.x && f > v.y && f > v.z;
     336                 :             : }
     337                 :             : 
     338                 :             : template <typename T>
     339                 :             : inline bool operator<=(const vec3<T>& v, const vec3<T>& f) {
     340                 :             :     return v.x <= f.x && v.y <= f.y && v.z <= f.z;
     341                 :             : }
     342                 :             : 
     343                 :             : template <typename T>
     344                 :             : inline bool operator<=(const vec3<T>& v, T f) {
     345                 :             :     return v.x <= f && v.y <= f && v.z <= f;
     346                 :             : }
     347                 :             : 
     348                 :             : template <typename T>
     349                 :             : inline bool operator<=(T f, const vec3<T>& v) {
     350                 :             :     return f <= v.x && f <= v.y && f <= v.z;
     351                 :             : }
     352                 :             : 
     353                 :             : template <typename T>
     354                 :             : inline bool operator>=(const vec3<T>& v, const vec3<T>& f) {
     355                 :             :     return v.x >= f.x && v.y >= f.y && v.z >= f.z;
     356                 :             : }
     357                 :             : 
     358                 :             : template <typename T>
     359                 :             : inline bool operator>=(const vec3<T>& v, T f) {
     360                 :             :     return v.x >= f && v.y >= f && v.z >= f;
     361                 :             : }
     362                 :             : 
     363                 :             : template <typename T>
     364                 :             : inline bool operator>=(T f, const vec3<T>& v) {
     365                 :             :     return f >= v.x && f >= v.y && f >= v.z;
     366                 :             : }
     367                 :             : 
     368                 :             : template <typename T>
     369                 :             : inline bool operator!=(const vec3<T>& v, const vec3<T>& f) {
     370                 :             :     return v.x != f.x || v.y != f.y || v.z != f.z;
     371                 :             : }
     372                 :             : 
     373                 :             : template <>
     374                 :           0 : inline bool operator!=(const vec3<float>& v, const vec3<float>& f) {
     375                 :           0 :     return ez::isDifferent(v.x, f.x) || ez::isDifferent(v.y, f.y) || ez::isDifferent(v.z, f.z);
     376                 :           0 : }
     377                 :             : 
     378                 :             : template <>
     379                 :           0 : inline bool operator!=(const vec3<double>& v, const vec3<double>& f) {
     380                 :           0 :     return ez::isDifferent(v.x, f.x) || ez::isDifferent(v.y, f.y) || ez::isDifferent(v.z, f.z);
     381                 :           0 : }
     382                 :             : 
     383                 :             : template <typename T>
     384                 :             : inline bool operator!=(const vec3<T>& v, T f) {
     385                 :             :     return v.x != f || v.y != f || v.z != f;
     386                 :             : }
     387                 :             : 
     388                 :             : template <typename T>
     389                 :             : inline bool operator!=(T f, const vec3<T>& v) {
     390                 :             :     return f != v.x || f != v.y || f != v.z;
     391                 :             : }
     392                 :             : 
     393                 :             : template <typename T>
     394                 :           8 : inline bool operator==(const vec3<T>& v, const vec3<T>& f) {
     395 [ +  + ][ +  + ]:           8 :     return v.x == f.x && v.y == f.y && v.z == f.z;
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     396                 :           8 : }
     397                 :             : 
     398                 :             : template <>
     399                 :           2 : inline bool operator==(const vec3<float>& v, const vec3<float>& f) {
     400 [ +  + ][ +  - ]:           2 :     return ez::isEqual(v.x, f.x) && ez::isEqual(v.y, f.y) && ez::isEqual(v.z, f.z);
                 [ +  - ]
     401                 :           2 : }
     402                 :             : 
     403                 :             : template <>
     404                 :           2 : inline bool operator==(const vec3<double>& v, const vec3<double>& f) {
     405 [ +  + ][ +  - ]:           2 :     return ez::isEqual(v.x, f.x) && ez::isEqual(v.y, f.y) && ez::isEqual(v.z, f.z);
                 [ +  - ]
     406                 :           2 : }
     407                 :             : 
     408                 :             : template <typename T>
     409                 :             : inline bool operator==(const vec3<T>& v, T f) {
     410                 :             :     return v.x == f && v.y == f && v.z == f;
     411                 :             : }
     412                 :             : 
     413                 :             : template <typename T>
     414                 :             : inline bool operator==(T f, const vec3<T>& v) {
     415                 :             :     return f == v.x && f == v.y && f == v.z;
     416                 :             : }
     417                 :             : 
     418                 :             : // Utility functions
     419                 :             : template <typename T>
     420                 :             : inline vec3<T> mini(const vec3<T>& a, const vec3<T>& b) {
     421                 :             :     return vec3<T>(ez::mini(a.x, b.x), ez::mini(a.y, b.y), ez::mini(a.z, b.z));
     422                 :             : }
     423                 :             : 
     424                 :             : template <typename T>
     425                 :             : inline vec3<T> maxi(const vec3<T>& a, const vec3<T>& b) {
     426                 :             :     return vec3<T>(ez::maxi(a.x, b.x), ez::maxi(a.y, b.y), ez::maxi(a.z, b.z));
     427                 :             : }
     428                 :             : 
     429                 :             : template <typename T>
     430                 :             : inline vec3<T> floor(const vec3<T>& a) {
     431                 :             :     return vec3<T>(ez::floor(a.x), ez::floor(a.y), ez::floor(a.z));
     432                 :             : }
     433                 :             : 
     434                 :             : template <typename T>
     435                 :             : inline vec3<T> ceil(const vec3<T>& a) {
     436                 :             :     return vec3<T>(ez::ceil(a.x), ez::ceil(a.y), ez::ceil(a.z));
     437                 :             : }
     438                 :             : 
     439                 :             : template <typename T>
     440                 :             : inline vec3<T> abs(const vec3<T>& a) {
     441                 :             :     return vec3<T>(ez::abs(a.x), ez::abs(a.y), ez::abs(a.z));
     442                 :             : }
     443                 :             : 
     444                 :             : template <typename T>
     445                 :             : inline T dotS(const vec3<T>& a, const vec3<T>& b) {
     446                 :             :     return a.x * b.x + a.y * b.y + a.z * b.z;
     447                 :             : }
     448                 :             : 
     449                 :             : template <typename T>
     450                 :             : inline vec3<T> cCross(const vec3<T>& a, const vec3<T>& b) {
     451                 :             :     return vec3<T>(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
     452                 :             : }
     453                 :             : 
     454                 :             : template <typename T>
     455                 :             : inline vec3<T> cReflect(const vec3<T>& I, const vec3<T>& N) {
     456                 :             :     return I - static_cast<T>(2) * dotS(N, I) * N;
     457                 :             : }
     458                 :             : 
     459                 :             : // Clamps a value between 0 and 1.
     460                 :             : // Works with both integral and floating-point types.
     461                 :             : template <typename T>
     462                 :             : inline vec3<T> clamp(vec3<T> n) {
     463                 :             :     vec3<T> ret;
     464                 :             :     ret.x = ez::clamp(n.x);
     465                 :             :     ret.y = ez::clamp(n.y);
     466                 :             :     ret.z = ez::clamp(n.z);
     467                 :             :     return ret;
     468                 :             : }
     469                 :             : 
     470                 :             : // Clamps a value between 0 and b.
     471                 :             : // Works with both integral and floating-point types.
     472                 :             : template <typename T>
     473                 :             : inline vec3<T> clamp(vec3<T> n, T b) {
     474                 :             :     vec3<T> ret;
     475                 :             :     ret.x = ez::clamp(n.x, b);
     476                 :             :     ret.y = ez::clamp(n.y, b);
     477                 :             :     ret.z = ez::clamp(n.z, b);
     478                 :             :     return ret;
     479                 :             : }
     480                 :             : 
     481                 :             : // Clamps a value between a and b.
     482                 :             : // Works with both integral and floating-point types.
     483                 :             : template <typename T>
     484                 :             : inline vec3<T> clamp(vec3<T> n, T a, T b) {
     485                 :             :     vec3<T> ret;
     486                 :             :     ret.x = ez::clamp(n.x, a, b);
     487                 :             :     ret.y = ez::clamp(n.y, a, b);
     488                 :             :     ret.z = ez::clamp(n.z, a, b);
     489                 :             :     return ret;
     490                 :             : }
     491                 :             : 
     492                 :             : // Type aliases for common vector types
     493                 :             : using dvec3 = vec3<double>;
     494                 :             : using fvec3 = vec3<float>;
     495                 :             : using f32vec3 = vec3<float>;
     496                 :             : using f64vec3 = vec3<double>;
     497                 :             : using ivec3 = vec3<int>;
     498                 :             : using i8vec3 = vec3<int8_t>;
     499                 :             : using i16vec3 = vec3<int16_t>;
     500                 :             : using i32vec3 = vec3<int32_t>;
     501                 :             : using i64vec3 = vec3<int64_t>;
     502                 :             : using u8vec3 = vec3<uint8_t>;
     503                 :             : using u16vec3 = vec3<uint16_t>;
     504                 :             : using uvec3 = vec3<uint32_t>;
     505                 :             : using u32vec3 = vec3<uint32_t>;
     506                 :             : using u64vec3 = vec3<uint64_t>;
     507                 :             : 
     508                 :             : // Specialization for float32 validation
     509                 :           0 : inline bool valid(const fvec3& a) {
     510                 :           0 :     return floatIsValid(a.x) && floatIsValid(a.y) && floatIsValid(a.z);
     511                 :           0 : }
     512                 :             : 
     513                 :             : template <typename T>
     514                 :             : inline std::istream& operator>>(std::istream& vIn, vec3<T>& vType) {
     515                 :             :     char separator;
     516                 :             :     if (vIn >> vType.x >> separator >> vType.y >> separator >> vType.z) {
     517                 :             :         if (separator != ';') {
     518                 :             :             vIn.setstate(std::ios::failbit);
     519                 :             :         }
     520                 :             :     }
     521                 :             :     return vIn;
     522                 :             : }
     523                 :             : 
     524                 :             : template <typename T>
     525                 :             : inline std::ostream& operator<<(std::ostream& vOut, const vec3<T>& vType) {
     526                 :             :     vOut << vType.x << ";" << vType.y << ";" << vType.z;
     527                 :             :     return vOut;
     528                 :             : }
     529                 :             : 
     530                 :             : }  // namespace ez
        

Generated by: LCOV version 2.0-1