Commit 52848dbf by David Flynn

### 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[0] += rhs[0]; data[1] += rhs[1]; data[2] += rhs[2]; return *this; } Vec3& operator-=(const Vec3& rhs) template Vec3& operator-=(const typename pcc::Vec3& rhs) { data[0] -= rhs[0]; data[1] -= rhs[1]; data[2] -= rhs[2]; return *this; } Vec3& operator-=(const T a) template Vec3& operator-=(U a) { data[0] -= a; data[1] -= a; data[2] -= a; return *this; } Vec3& operator+=(const T a) template Vec3& operator+=(U a) { data[0] += a; data[1] += a; data[2] += a; return *this; } Vec3& operator<<=(int val) { data[0] <<= val; ... ... @@ -124,6 +134,7 @@ public: data[2] <<= val; return *this; } Vec3& operator>>=(int val) { data[0] >>= val; ... ... @@ -131,7 +142,9 @@ public: data[2] >>= val; return *this; } Vec3& operator/=(const T a) template Vec3& operator/=(U a) { assert(a != 0); data[0] /= a; ... ... @@ -139,77 +152,141 @@ public: data[2] /= a; return *this; } Vec3& operator*=(const T a) template Vec3& operator*=(U a) { data[0] *= a; data[1] *= a; data[2] *= a; return *this; } Vec3& operator=(const T a) template Vec3& operator=(const U a) { data[0] = a; data[1] = a; data[2] = a; return *this; } Vec3& operator=(const T* const rhs) template Vec3& operator=(const U* rhs) { data[0] = rhs[0]; data[1] = rhs[1]; data[2] = rhs[2]; return *this; } T operator*(const Vec3& rhs) const Vec3 operator-() const { return Vec3(-data[0], -data[1], -data[2]); } template friend Vec3::type> operator+(const Vec3& lhs, const typename pcc::Vec3& rhs) { return (data[0] * rhs[0] + data[1] * rhs[1] + data[2] * rhs[2]); return Vec3::type>( lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2]); } Vec3 operator-() const { return Vec3(-data[0], -data[1], -data[2]); } 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[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2]); return Vec3::type>( lhs + rhs[0], lhs + rhs[1], lhs + rhs[2]); } 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[0], lhs + rhs[1], lhs + rhs[2]); return Vec3::type>( lhs[0] + rhs, lhs[1] + rhs, lhs[2] + 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[0] + rhs, lhs[1] + rhs, lhs[2] + rhs); return Vec3::type>( lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2]); } 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[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2]); return Vec3::type>( lhs - rhs[0], lhs - rhs[1], lhs - rhs[2]); } 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[0], lhs - rhs[1], lhs - rhs[2]); return Vec3::type>( lhs[0] - rhs, lhs[1] - rhs, lhs[2] - 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[0] - rhs, lhs[1] - rhs, lhs[2] - rhs); return Vec3::type>( lhs * rhs[0], lhs * rhs[1], lhs * rhs[2]); } 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[0], lhs * rhs[1], lhs * rhs[2]); return (lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2]); } 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[0] * rhs, lhs[1] * rhs, lhs[2] * rhs); return Vec3::type>( lhs[0] * rhs, lhs[1] * rhs, lhs[2] * 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[0] / rhs, lhs[1] / rhs, lhs[2] / rhs); return Vec3::type>( lhs[0] / rhs, lhs[1] / rhs, lhs[2] / rhs); } friend Vec3 operator<<(const Vec3& lhs, int val) { return Vec3(lhs[0] << val, lhs[1] << val, lhs[2] << val); } friend Vec3 operator>>(const Vec3& lhs, int val) { return Vec3(lhs[0] >> val, lhs[1] >> val, lhs[2] >> val); } bool operator<(const Vec3& rhs) const { if (data[0] == rhs[0]) { ... ... @@ -220,6 +297,7 @@ public: } return (data[0] < rhs[0]); } bool operator>(const Vec3& rhs) const { if (data[0] == rhs[0]) { ... ... @@ -230,42 +308,61 @@ public: } return (data[0] > rhs[0]); } bool operator==(const Vec3& rhs) const { return (data[0] == rhs[0] && data[1] == rhs[1] && data[2] == rhs[2]); } bool operator!=(const Vec3& rhs) const { return (data[0] != rhs[0] || data[1] != rhs[1] || data[2] != rhs[2]); } friend std::ostream& operator<<(std::ostream& os, const Vec3& vec) { os << vec[0] << " " << vec[1] << " " << vec[2] << std::endl; return os; } friend std::istream& operator>>(std::istream& is, Vec3& vec) { is >> vec[0] >> vec[1] >> vec[2]; return is; } Vec3(const T a) { data[0] = data[1] = data[2] = a; } Vec3(const T x, const T y, const T z) { data[0] = x; data[1] = y; data[2] = z; } Vec3(const Vec3& vec) { data[0] = vec.data[0]; data[1] = vec.data[1]; data[2] = vec.data[2]; } template Vec3(const typename pcc::Vec3& vec) { data[0] = vec.data[0]; data[1] = vec.data[1]; data[2] = vec.data[2]; } Vec3() = default; ~Vec3(void) = default; private: T data[3]; 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[0] - point[0], 0.0), point[0] - max[0]); const T dy = std::max(std::max(min[1] - point[1], 0.0), point[1] - max[1]); const T dz = std::max(std::max(min[2] - point[2], 0.0), point[2] - max[2]); const T dx = std::max(std::max(min[0] - point[0], T()), point[0] - max[0]); const T dy = std::max(std::max(min[1] - point[1], T()), point[1] - max[1]); const T dz = std::max(std::max(min[2] - point[2], T()), point[2] - max[2]); 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[0] * rhs[0], lhs[1] * rhs[1], lhs[2] * rhs[2]}; return Vec3::type>( lhs[0] * rhs[0], lhs[1] * rhs[1], lhs[2] * rhs[2]); } //--------------------------------------------------------------------------- ... ...
 ... ... @@ -438,8 +438,7 @@ decodeTrisoupCommon( Vec3 SS = 0; for (int j = 0; j < leafVertices.size(); j++) { Vec3 S = leafVertices[j].pos - blockCentroid; SS += {(S[0] * S[0]) >> kTrisoupFpBits, (S[1] * S[1]) >> kTrisoupFpBits, (S[2] * S[2]) >> 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!