### maths: allow the usual numeric conversions between Vec3<T> and Vec3<U>

```This makes Vec3<T> perform more like the usual arithmetic types, in
order to avoid having to explicitly perform element wise conversions
when two Vec3<>s have different numeric types.

For instance:
_i = int16_t() + int()                // typeof(_i) == int
vi = Vec3<int16_t>() + Vec3<int>()    // typeof(vi) == Vec3<int>

_d = 1 + 2.0                          // typeof(_d) == double
vd = Vec3<int>(1) + Vec3<double>(2.0) // typeof(vd) == Vec3<double>

vi = Vec3<int>(Vec3<double>())        // typeof(vi) == Vec3<int>
vd = Vec3<double>(Vec3<int>())        // typeof(vd) == Vec3<double>

Be aware, however, that the usual implicit conversions can result
in a loss of precision:

int _i = 1 + 1.5                          // _i == 2;
Vec3<int> vi = Vec3<int>(1) + Vec3<double>(1.5) // vi == Vec3<int>(2)```
parent 6dcd6f29
 ... ... @@ -42,6 +42,7 @@ #include #include #include #include #include "PCCMisc.h" #include "tables.h" ... ... @@ -89,34 +90,43 @@ public: memcpy(data, rhs.data, sizeof(data)); return *this; } Vec3& operator+=(const Vec3& rhs) template Vec3& operator+=(const typename pcc::Vec3& rhs) { data += rhs; data += rhs; data += rhs; return *this; } Vec3& operator-=(const Vec3& rhs) template Vec3& operator-=(const typename pcc::Vec3& rhs) { data -= rhs; data -= rhs; data -= rhs; return *this; } Vec3& operator-=(const T a) template Vec3& operator-=(U a) { data -= a; data -= a; data -= a; return *this; } Vec3& operator+=(const T a) template Vec3& operator+=(U a) { data += a; data += a; data += a; return *this; } Vec3& operator<<=(int val) { data <<= val; ... ... @@ -124,6 +134,7 @@ public: data <<= val; return *this; } Vec3& operator>>=(int val) { data >>= val; ... ... @@ -131,7 +142,9 @@ public: data >>= val; return *this; } Vec3& operator/=(const T a) template Vec3& operator/=(U a) { assert(a != 0); data /= a; ... ... @@ -139,77 +152,141 @@ public: data /= a; return *this; } Vec3& operator*=(const T a) template Vec3& operator*=(U a) { data *= a; data *= a; data *= a; return *this; } Vec3& operator=(const T a) template Vec3& operator=(const U a) { data = a; data = a; data = a; return *this; } Vec3& operator=(const T* const rhs) template Vec3& operator=(const U* rhs) { data = rhs; data = rhs; data = rhs; return *this; } T operator*(const Vec3& rhs) const Vec3 operator-() const { return Vec3(-data, -data, -data); } template friend Vec3::type> operator+(const Vec3& lhs, const typename pcc::Vec3& rhs) { return (data * rhs + data * rhs + data * rhs); return Vec3::type>( lhs + rhs, lhs + rhs, lhs + rhs); } Vec3 operator-() const { return Vec3(-data, -data, -data); } friend Vec3 operator+(const Vec3& lhs, const Vec3& rhs) template friend Vec3::value, typename std::common_type::type>::type> operator+(const U lhs, const Vec3& rhs) { return Vec3(lhs + rhs, lhs + rhs, lhs + rhs); return Vec3::type>( lhs + rhs, lhs + rhs, lhs + rhs); } friend Vec3 operator+(const T lhs, const Vec3& rhs) template friend Vec3::value, typename std::common_type::type>::type> operator+(const Vec3& lhs, const U rhs) { return Vec3(lhs + rhs, lhs + rhs, lhs + rhs); return Vec3::type>( lhs + rhs, lhs + rhs, lhs + rhs); } friend Vec3 operator+(const Vec3& lhs, const T rhs) template friend Vec3::type> operator-(const Vec3& lhs, const typename pcc::Vec3& rhs) { return Vec3(lhs + rhs, lhs + rhs, lhs + rhs); return Vec3::type>( lhs - rhs, lhs - rhs, lhs - rhs); } friend Vec3 operator-(const Vec3& lhs, const Vec3& rhs) template friend Vec3::value, typename std::common_type::type>::type> operator-(const U lhs, const Vec3& rhs) { return Vec3(lhs - rhs, lhs - rhs, lhs - rhs); return Vec3::type>( lhs - rhs, lhs - rhs, lhs - rhs); } friend Vec3 operator-(const T lhs, const Vec3& rhs) template friend Vec3::value, typename std::common_type::type>::type> operator-(const Vec3& lhs, const U rhs) { return Vec3(lhs - rhs, lhs - rhs, lhs - rhs); return Vec3::type>( lhs - rhs, lhs - rhs, lhs - rhs); } friend Vec3 operator-(const Vec3& lhs, const T rhs) template friend Vec3::value, typename std::common_type::type>::type> operator*(const U lhs, const Vec3& rhs) { return Vec3(lhs - rhs, lhs - rhs, lhs - rhs); return Vec3::type>( lhs * rhs, lhs * rhs, lhs * rhs); } friend Vec3 operator*(const T lhs, const Vec3& rhs) // todo(df): make this elementwise? template friend typename std::common_type::type operator*(pcc::Vec3 lhs, const pcc::Vec3& rhs) { return Vec3(lhs * rhs, lhs * rhs, lhs * rhs); return (lhs * rhs + lhs * rhs + lhs * rhs); } friend Vec3 operator*(const Vec3& lhs, const T rhs) template friend Vec3::value, typename std::common_type::type>::type> operator*(const Vec3& lhs, const U rhs) { return Vec3(lhs * rhs, lhs * rhs, lhs * rhs); return Vec3::type>( lhs * rhs, lhs * rhs, lhs * rhs); } friend Vec3 operator/(const Vec3& lhs, const T rhs) template friend Vec3::value, typename std::common_type::type>::type> operator/(const Vec3& lhs, const U rhs) { assert(rhs != 0); return Vec3(lhs / rhs, lhs / rhs, lhs / rhs); return Vec3::type>( lhs / rhs, lhs / rhs, lhs / rhs); } friend Vec3 operator<<(const Vec3& lhs, int val) { return Vec3(lhs << val, lhs << val, lhs << val); } friend Vec3 operator>>(const Vec3& lhs, int val) { return Vec3(lhs >> val, lhs >> val, lhs >> val); } bool operator<(const Vec3& rhs) const { if (data == rhs) { ... ... @@ -220,6 +297,7 @@ public: } return (data < rhs); } bool operator>(const Vec3& rhs) const { if (data == rhs) { ... ... @@ -230,42 +308,61 @@ public: } return (data > rhs); } bool operator==(const Vec3& rhs) const { return (data == rhs && data == rhs && data == rhs); } bool operator!=(const Vec3& rhs) const { return (data != rhs || data != rhs || data != rhs); } friend std::ostream& operator<<(std::ostream& os, const Vec3& vec) { os << vec << " " << vec << " " << vec << std::endl; return os; } friend std::istream& operator>>(std::istream& is, Vec3& vec) { is >> vec >> vec >> vec; return is; } Vec3(const T a) { data = data = data = a; } Vec3(const T x, const T y, const T z) { data = x; data = y; data = z; } Vec3(const Vec3& vec) { data = vec.data; data = vec.data; data = vec.data; } template Vec3(const typename pcc::Vec3& vec) { data = vec.data; data = vec.data; data = vec.data; } Vec3() = default; ~Vec3(void) = default; private: T data; template friend class pcc::Vec3; }; template ... ... @@ -299,9 +396,9 @@ struct Box3 { T getDist2(const Vec3& point) const { const T dx = std::max(std::max(min - point, 0.0), point - max); const T dy = std::max(std::max(min - point, 0.0), point - max); const T dz = std::max(std::max(min - point, 0.0), point - max); const T dx = std::max(std::max(min - point, T()), point - max); const T dy = std::max(std::max(min - point, T()), point - max); const T dz = std::max(std::max(min - point, T()), point - max); return dx * dx + dy * dy + dz * dz; } ... ... @@ -322,11 +419,12 @@ struct Box3 { //--------------------------------------------------------------------------- // element-wise multiplication of two vectors template Vec3 times(Vec3 lhs, const Vec3& rhs) template Vec3::type> times(Vec3 lhs, const Vec3& rhs) { return Vec3{lhs * rhs, lhs * rhs, lhs * rhs}; return Vec3::type>( lhs * rhs, lhs * rhs, lhs * rhs); } //--------------------------------------------------------------------------- ... ...
 ... ... @@ -438,8 +438,7 @@ decodeTrisoupCommon( Vec3 SS = 0; for (int j = 0; j < leafVertices.size(); j++) { Vec3 S = leafVertices[j].pos - blockCentroid; SS += {(S * S) >> kTrisoupFpBits, (S * S) >> kTrisoupFpBits, (S * S) >> kTrisoupFpBits}; SS += times(S, S) >> kTrisoupFpBits; } // Dominant axis is the coordinate minimizing the variance. ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!