diff --git a/Base/include/Color.h b/Base/include/Color.h index d7dd778..0ca5846 100644 --- a/Base/include/Color.h +++ b/Base/include/Color.h @@ -94,6 +94,7 @@ class Color : public Vec4f { // Tests for equality by comparing the values and the bit depths. bool operator==(const Color &) const; }; +REGISTER_VECTOR_TYPE(Color); } // namespace FasTC diff --git a/Base/include/Pixel.h b/Base/include/Pixel.h index bee3134..1d2e6fe 100644 --- a/Base/include/Pixel.h +++ b/Base/include/Pixel.h @@ -135,6 +135,7 @@ class Pixel : public Vector4 { // Tests for equality by comparing the values and the bit depths. bool operator==(const Pixel &) const; }; +REGISTER_VECTOR_TYPE(Pixel); } // namespace FasTC diff --git a/Base/include/Vector2.h b/Base/include/Vector2.h index 2c0edcd..52bce4b 100644 --- a/Base/include/Vector2.h +++ b/Base/include/Vector2.h @@ -71,6 +71,7 @@ namespace FasTC { _VEX_VEC2_SWIZZLE_DEF(Y, Y) #endif //_VEX_ENABLE_SWIZZLE_ }; + REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector2); typedef Vector2 Vec2f; typedef Vector2 Vec2d; diff --git a/Base/include/Vector3.h b/Base/include/Vector3.h index 3c32b46..02de606 100644 --- a/Base/include/Vector3.h +++ b/Base/include/Vector3.h @@ -115,6 +115,7 @@ namespace FasTC { _VEX_VEC3_SWIZZLE_DEF(Z, Z, Z) #endif // _VEX_ENABLE_SWIZZLE_ }; + REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector3); typedef Vector3 Vec3f; typedef Vector3 Vec3d; diff --git a/Base/include/Vector4.h b/Base/include/Vector4.h index 55f06ae..bf5311d 100644 --- a/Base/include/Vector4.h +++ b/Base/include/Vector4.h @@ -411,6 +411,7 @@ namespace FasTC { _VEX_VEC4_SWIZZLE_DEF(W, W, W, W) #endif // _VEX_ENABLE_SWIZZLE_ }; + REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector4); typedef Vector4 Vec4f; typedef Vector4 Vec4d; diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index f27664f..e7962bb 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -122,49 +122,112 @@ namespace FasTC { return v1; } + template + class VectorTraits { + public: + static const bool IsVector = false; + }; + + template + class VectorTraits > { + public: + static const bool IsVector = true; + }; + + #define REGISTER_VECTOR_TYPE(TYPE) \ + template<> \ + class VectorTraits< TYPE > { \ + public: \ + static const bool IsVector = true; \ + } + + #define REGISTER_ONE_TEMPLATE_VECTOR_TYPE(TYPE) \ + template \ + class VectorTraits< TYPE > { \ + public: \ + static const bool IsVector = true; \ + } + + template + class VectorSwitch { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + public: + typedef TypeOne VectorType; + typedef TypeTwo ScalarType; + + VectorSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + const TypeOne &GetVector() { return m_A; } + const TypeTwo &GetScalar() { return m_B; } + }; + + template + class VectorSwitch { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef TypeTwo VectorType; + typedef TypeOne ScalarType; + + VectorSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + const TypeOne &GetVector() { return m_B; } + const TypeTwo &GetScalar() { return m_A; } + }; + template - static inline VectorType operator*(const VectorType &v, const ScalarType &s) { + static inline VectorType ScalarMultiply(const VectorType &v, const ScalarType &s) { VectorType a; for(int i = 0; i < VectorType::Size; i++) a(i) = v(i) * s; return a; } - template - static inline VectorType operator*(const ScalarType &s, const VectorType &v) { - VectorType a; - for(int i = 0; i < VectorType::Size; i++) - a(i) = v(i) * s; - return a; + template + static inline + typename VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo >::VectorType + operator*(const TypeOne &v1, const TypeTwo &v2) { + typedef VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo > VSwitch; + VSwitch s(v1, v2); + return ScalarMultiply(s.GetVector(), s.GetScalar()); } template - static inline VectorType operator/(const VectorType &v, const ScalarType &s) { + static inline VectorType ScalarDivide(const VectorType &v, const ScalarType &s) { VectorType a; for(int i = 0; i < VectorType::Size; i++) a(i) = v(i) / s; return a; } - template - static inline operator/(const ScalarType &s, const VectorType &v) { - VectorType a; - for(int i = 0; i < VectorType::Size; i++) - a(i) = v(i) / s; - return a; + template + static inline + typename VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo >::VectorType + operator/(const TypeOne &v1, const TypeTwo &v2) { + typedef VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo > VSwitch; + VSwitch s(v1, v2); + return ScalarDivide(s.GetVector(), s.GetScalar()); } template static inline VectorType &operator*=(VectorType &v, const ScalarType &s) { - for(int i = 0; i < VectorType::Size; i++) + for(int i = 0; i < VectorType::Size; i++) { v(i) *= s; + } return v; } template static inline VectorType &operator/=(VectorType &v, const ScalarType &s) { - for(int i = 0; i < VectorType::Size; i++) + for(int i = 0; i < VectorType::Size; i++) { v(i) /= s; + } return v; } };