Add more generic structures for performing scalar multiplication with vectors (i.e. ones that actually compile)

This commit is contained in:
Pavel Krajcevski 2013-10-08 18:39:32 -04:00
parent 0add6a5ee9
commit 01a38dc76b
6 changed files with 84 additions and 16 deletions

View file

@ -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

View file

@ -135,6 +135,7 @@ class Pixel : public Vector4<uint16> {
// Tests for equality by comparing the values and the bit depths.
bool operator==(const Pixel &) const;
};
REGISTER_VECTOR_TYPE(Pixel);
} // namespace FasTC

View file

@ -71,6 +71,7 @@ namespace FasTC {
_VEX_VEC2_SWIZZLE_DEF(Y, Y)
#endif //_VEX_ENABLE_SWIZZLE_
};
REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector2);
typedef Vector2<float> Vec2f;
typedef Vector2<double> Vec2d;

View file

@ -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<float> Vec3f;
typedef Vector3<double> Vec3d;

View file

@ -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<float> Vec4f;
typedef Vector4<double> Vec4d;

View file

@ -122,49 +122,112 @@ namespace FasTC {
return v1;
}
template<typename T>
class VectorTraits {
public:
static const bool IsVector = false;
};
template<typename T, const int N>
class VectorTraits<VectorBase<T, N> > {
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<typename T> \
class VectorTraits< TYPE <T> > { \
public: \
static const bool IsVector = true; \
}
template<bool condition, typename TypeOne, typename TypeTwo>
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<typename TypeOne, typename TypeTwo>
class VectorSwitch<false, TypeOne, TypeTwo> {
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<typename VectorType, typename ScalarType>
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<typename VectorType, typename ScalarType>
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<typename TypeOne, typename TypeTwo>
static inline
typename VectorSwitch< VectorTraits<TypeOne>::IsVector, TypeOne, TypeTwo >::VectorType
operator*(const TypeOne &v1, const TypeTwo &v2) {
typedef VectorSwitch< VectorTraits<TypeOne>::IsVector, TypeOne, TypeTwo > VSwitch;
VSwitch s(v1, v2);
return ScalarMultiply(s.GetVector(), s.GetScalar());
}
template<typename VectorType, typename ScalarType>
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<typename VectorType, typename ScalarType>
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<typename TypeOne, typename TypeTwo>
static inline
typename VectorSwitch< VectorTraits<TypeOne>::IsVector, TypeOne, TypeTwo >::VectorType
operator/(const TypeOne &v1, const TypeTwo &v2) {
typedef VectorSwitch< VectorTraits<TypeOne>::IsVector, TypeOne, TypeTwo > VSwitch;
VSwitch s(v1, v2);
return ScalarDivide(s.GetVector(), s.GetScalar());
}
template<typename VectorType, typename ScalarType>
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<typename VectorType, typename ScalarType>
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;
}
};