diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h index ab3f51bd..76f53f89 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h @@ -26,6 +26,8 @@ freely, subject to the following restrictions: #include "Impl/TypeDef.h" +#include "PolyVoxForwardDeclarations.h" + #include "PolyVoxCore/Array.h" #include "PolyVoxCore/DefaultIsQuadNeeded.h" #include "PolyVoxCore/SurfaceMesh.h" @@ -73,7 +75,7 @@ namespace PolyVox /// /// Another scenario which sometimes results in confusion is when you wish to extract a region which corresponds to the whole volume, partcularly when solid voxels extend right to the edge of the volume. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - template > + template class CubicSurfaceExtractor { struct IndexAndMaterial diff --git a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h index debd7b99..5cdf3ef5 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h +++ b/library/PolyVoxCore/include/PolyVoxCore/PolyVoxForwardDeclarations.h @@ -63,7 +63,7 @@ namespace PolyVox //////////////////////////////////////////////////////////////////////////////// // CubicSurfaceExtractor //////////////////////////////////////////////////////////////////////////////// - template< typename VolumeType> class CubicSurfaceExtractor; + template > class CubicSurfaceExtractor; //////////////////////////////////////////////////////////////////////////////// // Density @@ -139,15 +139,34 @@ namespace PolyVox //////////////////////////////////////////////////////////////////////////////// // Vector //////////////////////////////////////////////////////////////////////////////// - template class Vector; - typedef Vector<3,float> Vector3DFloat; - typedef Vector<3,double> Vector3DDouble; - typedef Vector<3,int8_t> Vector3DInt8; - typedef Vector<3,uint8_t> Vector3DUint8; - typedef Vector<3,int16_t> Vector3DInt16; - typedef Vector<3,uint16_t> Vector3DUint16; - typedef Vector<3,int32_t> Vector3DInt32; - typedef Vector<3,uint32_t> Vector3DUint32; + template class Vector; + + typedef Vector<2,float,float> Vector2DFloat; + typedef Vector<2,double,double> Vector2DDouble; + typedef Vector<2,int8_t,int32_t> Vector2DInt8; + typedef Vector<2,uint8_t,int32_t> Vector2DUint8; + typedef Vector<2,int16_t,int32_t> Vector2DInt16; + typedef Vector<2,uint16_t,int32_t> Vector2DUint16; + typedef Vector<2,int32_t,int32_t> Vector2DInt32; + typedef Vector<2,uint32_t,int32_t> Vector2DUint32; + + typedef Vector<3,float,float> Vector3DFloat; + typedef Vector<3,double,double> Vector3DDouble; + typedef Vector<3,int8_t,int32_t> Vector3DInt8; + typedef Vector<3,uint8_t,int32_t> Vector3DUint8; + typedef Vector<3,int16_t,int32_t> Vector3DInt16; + typedef Vector<3,uint16_t,int32_t> Vector3DUint16; + typedef Vector<3,int32_t,int32_t> Vector3DInt32; + typedef Vector<3,uint32_t,int32_t> Vector3DUint32; + + typedef Vector<4,float,float> Vector4DFloat; + typedef Vector<4,double,double> Vector4DDouble; + typedef Vector<4,int8_t,int32_t> Vector4DInt8; + typedef Vector<4,uint8_t,int32_t> Vector4DUint8; + typedef Vector<4,int16_t,int32_t> Vector4DInt16; + typedef Vector<4,uint16_t,int32_t> Vector4DUint16; + typedef Vector<4,int32_t,int32_t> Vector4DInt32; + typedef Vector<4,uint32_t,int32_t> Vector4DUint32; } #endif diff --git a/library/PolyVoxCore/include/PolyVoxCore/Vector.h b/library/PolyVoxCore/include/PolyVoxCore/Vector.h index ea81910c..9f4b51de 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Vector.h +++ b/library/PolyVoxCore/include/PolyVoxCore/Vector.h @@ -26,6 +26,8 @@ freely, subject to the following restrictions: #include "Impl/TypeDef.h" +#include "PolyVoxForwardDeclarations.h" + #include #include #include @@ -58,133 +60,169 @@ namespace PolyVox Vector2DInt4 test(1,2); //Declares a 2 dimensional Vector of type int4. \endcode */ - template + template class Vector { public: - ///Constructor. - Vector(Type x, Type y); - ///Constructor. - Vector(Type x, Type y, Type z); - ///Constructor. - Vector(Type x, Type y, Type z, Type w); ///Constructor Vector(void); + ///Constructor. + Vector(StorageType tFillValue); + ///Constructor. + Vector(StorageType x, StorageType y); + ///Constructor. + Vector(StorageType x, StorageType y, StorageType z); + ///Constructor. + Vector(StorageType x, StorageType y, StorageType z, StorageType w); ///Copy Constructor. - Vector(const Vector& vector); + Vector(const Vector& vector); ///Copy Constructor which performs casting. template explicit Vector(const Vector& vector); ///Destructor. ~Vector(void); ///Assignment Operator. - Vector& operator=(const Vector& rhs); + Vector& operator=(const Vector& rhs); ///Equality Operator. - bool operator==(const Vector& rhs) const; + bool operator==(const Vector& rhs) const; ///Inequality Operator. - bool operator!=(const Vector& rhs) const; + bool operator!=(const Vector& rhs) const; ///Comparison Operator. - bool operator<(const Vector& rhs) const; + bool operator<(const Vector& rhs) const; ///Addition and Assignment Operator. - Vector& operator+=(const Vector &rhs); + Vector& operator+=(const Vector &rhs); ///Subtraction and Assignment Operator. - Vector& operator-=(const Vector &rhs); + Vector& operator-=(const Vector &rhs); ///Multiplication and Assignment Operator. - Vector& operator*=(const Vector &rhs); + Vector& operator*=(const Vector &rhs); ///Division and Assignment Operator. - Vector& operator/=(const Vector &rhs); + Vector& operator/=(const Vector &rhs); ///Multiplication and Assignment Operator. - Vector& operator*=(const Type& rhs); + Vector& operator*=(const StorageType& rhs); ///Division and Assignment Operator. - Vector& operator/=(const Type& rhs); + Vector& operator/=(const StorageType& rhs); ///Element Access. - Type getElement(uint32_t index) const; + StorageType getElement(uint32_t index) const; ///Get the x component of the vector. - Type getX(void) const; + StorageType getX(void) const; ///Get the y component of the vector. - Type getY(void) const; + StorageType getY(void) const; ///Get the z component of the vector. - Type getZ(void) const; + StorageType getZ(void) const; ///Get the w component of the vector. - Type getW(void) const; + StorageType getW(void) const; ///Element Access. - void setElement(uint32_t index, Type tValue); + void setElement(uint32_t index, StorageType tValue); ///Element Access. - void setElements(Type x, Type y); + void setElements(StorageType x, StorageType y); ///Element Access. - void setElements(Type x, Type y, Type z); + void setElements(StorageType x, StorageType y, StorageType z); ///Element Access. - void setElements(Type x, Type y, Type z, Type w); + void setElements(StorageType x, StorageType y, StorageType z, StorageType w); ///Set the x component of the vector. - void setX(Type tX); + void setX(StorageType tX); ///Set the y component of the vector. - void setY(Type tY); + void setY(StorageType tY); ///Set the z component of the vector. - void setZ(Type tZ); + void setZ(StorageType tZ); ///Set the w component of the vector. - void setW(Type tW); + void setW(StorageType tW); ///Get the length of the vector. double length(void) const; ///Get the squared length of the vector. double lengthSquared(void) const; ///Find the angle between this vector and that which is passed as a parameter. - double angleTo(const Vector& vector) const; + double angleTo(const Vector& vector) const; ///Find the cross product between this vector and the vector passed as a parameter. - Vector cross(const Vector& vector) const; + Vector cross(const Vector& vector) const; ///Find the dot product between this vector and the vector passed as a parameter. - Type dot(const Vector& rhs) const; + StorageType dot(const Vector& rhs) const; ///Normalise the vector. void normalise(void); private: //Values for the vector - Type m_tElements[Size]; + StorageType m_tElements[Size]; }; //Non-member overloaded operators. ///Addition operator. - template - Vector operator+(const Vector& lhs, const Vector& rhs); + template + Vector operator+(const Vector& lhs, const Vector& rhs); ///Subtraction operator. - template - Vector operator-(const Vector& lhs, const Vector& rhs); + template + Vector operator-(const Vector& lhs, const Vector& rhs); ///Multiplication operator. - template - Vector operator*(const Vector& lhs, const Vector& rhs); + template + Vector operator*(const Vector& lhs, const Vector& rhs); ///Division operator. - template - Vector operator/(const Vector& lhs, const Vector& rhs); + template + Vector operator/(const Vector& lhs, const Vector& rhs); ///Multiplication operator. - template - Vector operator*(const Vector& lhs, const Type& rhs); + template + Vector operator*(const Vector& lhs, const StorageType& rhs); ///Division operator. - template - Vector operator/(const Vector& lhs, const Type& rhs); + template + Vector operator/(const Vector& lhs, const StorageType& rhs); ///Stream insertion operator. - template - std::ostream& operator<<(std::ostream& os, const Vector& vector); + template + std::ostream& operator<<(std::ostream& os, const Vector& vector); //Some handy typedefs - ///A 3D Vector of floats. - typedef Vector<3,float> Vector3DFloat; - ///A 3D Vector of doubles. - typedef Vector<3,double> Vector3DDouble; - ///A 3D Vector of signed 8-bit values. - typedef Vector<3,int8_t> Vector3DInt8; - ///A 3D Vector of unsigned 8-bit values. - typedef Vector<3,uint8_t> Vector3DUint8; - ///A 3D Vector of signed 16-bit values. - typedef Vector<3,int16_t> Vector3DInt16; - ///A 3D Vector of unsigned 16-bit values. - typedef Vector<3,uint16_t> Vector3DUint16; - ///A 3D Vector of signed 32-bit values. - typedef Vector<3,int32_t> Vector3DInt32; - ///A 3D Vector of unsigned 32-bit values. - typedef Vector<3,uint32_t> Vector3DUint32; + ///A 2D Vector of floats. + typedef Vector<2,float,float> Vector2DFloat; + ///A 2D Vector of doubles. + typedef Vector<2,double,double> Vector2DDouble; + ///A 2D Vector of signed 8-bit values. + typedef Vector<2,int8_t,int32_t> Vector2DInt8; + ///A 2D Vector of unsigned 8-bit values. + typedef Vector<2,uint8_t,int32_t> Vector2DUint8; + ///A 2D Vector of signed 16-bit values. + typedef Vector<2,int16_t,int32_t> Vector2DInt16; + ///A 2D Vector of unsigned 16-bit values. + typedef Vector<2,uint16_t,int32_t> Vector2DUint16; + ///A 2D Vector of signed 32-bit values. + typedef Vector<2,int32_t,int32_t> Vector2DInt32; + ///A 2D Vector of unsigned 32-bit values. + typedef Vector<2,uint32_t,int32_t> Vector2DUint32; + + ///A 3D Vector of floats. + typedef Vector<3,float,float> Vector3DFloat; + ///A 3D Vector of doubles. + typedef Vector<3,double,double> Vector3DDouble; + ///A 3D Vector of signed 8-bit values. + typedef Vector<3,int8_t,int32_t> Vector3DInt8; + ///A 3D Vector of unsigned 8-bit values. + typedef Vector<3,uint8_t,int32_t> Vector3DUint8; + ///A 3D Vector of signed 16-bit values. + typedef Vector<3,int16_t,int32_t> Vector3DInt16; + ///A 3D Vector of unsigned 16-bit values. + typedef Vector<3,uint16_t,int32_t> Vector3DUint16; + ///A 3D Vector of signed 32-bit values. + typedef Vector<3,int32_t,int32_t> Vector3DInt32; + ///A 3D Vector of unsigned 32-bit values. + typedef Vector<3,uint32_t,int32_t> Vector3DUint32; + + ///A 4D Vector of floats. + typedef Vector<4,float,float> Vector4DFloat; + ///A 4D Vector of doubles. + typedef Vector<4,double,double> Vector4DDouble; + ///A 4D Vector of signed 8-bit values. + typedef Vector<4,int8_t,int32_t> Vector4DInt8; + ///A 4D Vector of unsigned 8-bit values. + typedef Vector<4,uint8_t,int32_t> Vector4DUint8; + ///A 4D Vector of signed 16-bit values. + typedef Vector<4,int16_t,int32_t> Vector4DInt16; + ///A 4D Vector of unsigned 16-bit values. + typedef Vector<4,uint16_t,int32_t> Vector4DUint16; + ///A 4D Vector of signed 32-bit values. + typedef Vector<4,int32_t,int32_t> Vector4DInt32; + ///A 4D Vector of unsigned 32-bit values. + typedef Vector<4,uint32_t,int32_t> Vector4DUint32; }//namespace PolyVox diff --git a/library/PolyVoxCore/include/PolyVoxCore/Vector.inl b/library/PolyVoxCore/include/PolyVoxCore/Vector.inl index da8f8648..504c4fbb 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/Vector.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/Vector.inl @@ -24,17 +24,41 @@ freely, subject to the following restrictions: namespace PolyVox { //-------------------------- Constructors, etc --------------------------------- + /** + Creates a Vector object but does not initialise it. + */ + template + Vector::Vector(void) + { + } + + /** + Creates a Vector object and initialises it with given values. + \param x x component to set. + */ + template + Vector::Vector(StorageType tFillValue) + { + for(uint32_t ct = 0; ct < Size; ct++) + { + m_tElements[ct] = tFillValue; + } + } + /** Creates a Vector object and initialises it with given values. \param x x component to set. \param y y component to set. */ - template - Vector::Vector(Type x, Type y) + template + Vector::Vector(StorageType x, StorageType y) { +#ifndef SWIGPYTHON // SWIG instantiates all constructors, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size == 2, "This constructor should only be used for vectors with two elements."); +#endif + m_tElements[0] = x; m_tElements[1] = y; - } /** @@ -43,9 +67,13 @@ namespace PolyVox \param y y component to set. \param z z component to set. */ - template - Vector::Vector(Type x, Type y, Type z) + template + Vector::Vector(StorageType x, StorageType y, StorageType z) { +#ifndef SWIGPYTHON // SWIG instantiates all constructors, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size == 3, "This constructor should only be used for vectors with three elements."); +#endif + m_tElements[0] = x; m_tElements[1] = y; m_tElements[2] = z; @@ -59,31 +87,27 @@ namespace PolyVox \param z z component to set. \param w w component to set. */ - template - Vector::Vector(Type x, Type y, Type z, Type w) + template + Vector::Vector(StorageType x, StorageType y, StorageType z, StorageType w) { +#ifndef SWIGPYTHON // SWIG instantiates all constructors, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size == 4, "This constructor should only be used for vectors with four elements."); +#endif + m_tElements[0] = x; m_tElements[1] = y; m_tElements[2] = z; m_tElements[3] = w; } - /** - Creates a Vector object but does not initialise it. - */ - template - Vector::Vector(void) - { - } - /** Copy constructor builds object based on object passed as parameter. \param vector A reference to the Vector to be copied. */ - template - Vector::Vector(const Vector& vector) + template + Vector::Vector(const Vector& vector) { - std::memcpy(m_tElements, vector.m_tElements, sizeof(Type) * Size); + std::memcpy(m_tElements, vector.m_tElements, sizeof(StorageType) * Size); } /** @@ -95,22 +119,30 @@ namespace PolyVox \param vector A reference to the Vector to be copied. */ - template - template - Vector::Vector(const Vector& vector) + template + template + Vector::Vector(const Vector& vector) { for(uint32_t ct = 0; ct < Size; ++ct) { - m_tElements[ct] = static_cast(vector.getElement(ct)); + m_tElements[ct] = static_cast(vector.getElement(ct)); } } /** Destroys the Vector. */ - template - Vector::~Vector(void) + template + Vector::~Vector(void) { + // We put the static_asserts in the destructor because there is one one of these, + // where as there are multiple constructors. + + // Force a vector to have a length greater than one. There is no need for a + // vector with one element, and supporting this would cause confusion over the + // behaviour of the constructor taking a single value, as this fills all elements + // to that value rather than just the first one. + static_assert(Size > 1, "Vector must have a length greater than one."); } /** @@ -118,14 +150,14 @@ namespace PolyVox \param rhs Vector to assign to. \return A reference to the result to allow chaining. */ - template - Vector& Vector::operator=(const Vector& rhs) + template + Vector& Vector::operator=(const Vector& rhs) { if(this == &rhs) { return *this; } - std::memcpy(m_tElements, rhs.m_tElements, sizeof(Type) * Size); + std::memcpy(m_tElements, rhs.m_tElements, sizeof(StorageType) * Size); return *this; } @@ -135,8 +167,8 @@ namespace PolyVox \return true if the Vectors match. \see operator!= */ - template - inline bool Vector::operator==(const Vector &rhs) const + template + inline bool Vector::operator==(const Vector &rhs) const { bool equal = true; for(uint32_t ct = 0; ct < Size; ++ct) @@ -156,8 +188,8 @@ namespace PolyVox \return true if the Vectors do not match. \see operator== */ - template - inline bool Vector::operator!=(const Vector &rhs) const + template + inline bool Vector::operator!=(const Vector &rhs) const { return !(*this == rhs); //Just call equality operator and invert the result. } @@ -169,8 +201,8 @@ namespace PolyVox \return true if this is less than the parameter \see operator!= */ - template - inline bool Vector::operator<(const Vector &rhs) const + template + inline bool Vector::operator<(const Vector &rhs) const { for(uint32_t ct = 0; ct < Size; ++ct) { @@ -187,8 +219,8 @@ namespace PolyVox \param rhs Vector to add \return The resulting Vector. */ - template - inline Vector& Vector::operator+=(const Vector& rhs) + template + inline Vector& Vector::operator+=(const Vector& rhs) { for(uint32_t ct = 0; ct < Size; ++ct) { @@ -202,8 +234,8 @@ namespace PolyVox \param rhs Vector to subtract \return The resulting Vector. */ - template - inline Vector& Vector::operator-=(const Vector& rhs) + template + inline Vector& Vector::operator-=(const Vector& rhs) { for(uint32_t ct = 0; ct < Size; ++ct) { @@ -217,8 +249,8 @@ namespace PolyVox \param rhs Vector to multiply by \return The resulting Vector. */ - template - inline Vector& Vector::operator*=(const Vector& rhs) + template + inline Vector& Vector::operator*=(const Vector& rhs) { for(uint32_t ct = 0; ct < Size; ++ct) { @@ -232,8 +264,8 @@ namespace PolyVox \param rhs Vector to divide by \return The resulting Vector. */ - template - inline Vector& Vector::operator/=(const Vector& rhs) + template + inline Vector& Vector::operator/=(const Vector& rhs) { for(uint32_t ct = 0; ct < Size; ++ct) { @@ -247,8 +279,8 @@ namespace PolyVox \param rhs the number the Vector is multiplied by. \return The resulting Vector. */ - template - inline Vector& Vector::operator*=(const Type& rhs) + template + inline Vector& Vector::operator*=(const StorageType& rhs) { for(uint32_t ct = 0; ct < Size; ++ct) { @@ -262,8 +294,8 @@ namespace PolyVox \param rhs the number the Vector is divided by. \return The resulting Vector. */ - template - inline Vector& Vector::operator/=(const Type& rhs) + template + inline Vector& Vector::operator/=(const StorageType& rhs) { for(uint32_t ct = 0; ct < Size; ++ct) { @@ -278,10 +310,10 @@ namespace PolyVox \param rhs Vector to add. \return The resulting Vector. */ - template - Vector operator+(const Vector& lhs, const Vector& rhs) + template + Vector operator+(const Vector& lhs, const Vector& rhs) { - Vector result = lhs; + Vector result = lhs; result += rhs; return result; } @@ -292,10 +324,10 @@ namespace PolyVox \param rhs Vector to subtract. \return The resulting Vector. */ - template - Vector operator-(const Vector& lhs, const Vector& rhs) + template + Vector operator-(const Vector& lhs, const Vector& rhs) { - Vector result = lhs; + Vector result = lhs; result -= rhs; return result; } @@ -306,10 +338,10 @@ namespace PolyVox \param rhs Vector to multiply by. \return The resulting Vector. */ - template - Vector operator*(const Vector& lhs, const Vector& rhs) + template + Vector operator*(const Vector& lhs, const Vector& rhs) { - Vector result = lhs; + Vector result = lhs; result *= rhs; return result; } @@ -320,10 +352,10 @@ namespace PolyVox \param rhs Vector to divide by. \return The resulting Vector. */ - template - Vector operator/(const Vector& lhs, const Vector& rhs) + template + Vector operator/(const Vector& lhs, const Vector& rhs) { - Vector result = lhs; + Vector result = lhs; result /= rhs; return result; } @@ -334,10 +366,10 @@ namespace PolyVox \param rhs the number the Vector is multiplied by. \return The resulting Vector. */ - template - Vector operator*(const Vector& lhs, const Type& rhs) + template + Vector operator*(const Vector& lhs, const StorageType& rhs) { - Vector result = lhs; + Vector result = lhs; result *= rhs; return result; } @@ -348,10 +380,10 @@ namespace PolyVox \param rhs the number the Vector is divided by. \return The resulting Vector. */ - template - Vector operator/(const Vector& lhs, const Type& rhs) + template + Vector operator/(const Vector& lhs, const StorageType& rhs) { - Vector result = lhs; + Vector result = lhs; result /= rhs; return result; } @@ -362,8 +394,8 @@ namespace PolyVox \param vector The Vector to write to the stream. \return A reference to the output stream to allow chaining. */ - template - std::ostream& operator<<(std::ostream& os, const Vector& vector) + template + std::ostream& operator<<(std::ostream& os, const Vector& vector) { os << "("; for(uint32_t ct = 0; ct < Size; ++ct) @@ -383,45 +415,54 @@ namespace PolyVox \param index The index of the element to return. \return The element. */ - template - inline Type Vector::getElement(uint32_t index) const + template + inline StorageType Vector::getElement(uint32_t index) const { + assert(index < Size); return m_tElements[index]; } /** \return A const reference to the X component of a 1, 2, 3, or 4 dimensional Vector. */ - template - inline Type Vector::getX(void) const + template + inline StorageType Vector::getX(void) const { - return m_tElements[0]; + return m_tElements[0]; // This is fine, a Vector always contains at least two elements. } /** \return A const reference to the Y component of a 2, 3, or 4 dimensional Vector. */ - template - inline Type Vector::getY(void) const + template + inline StorageType Vector::getY(void) const { - return m_tElements[1]; + return m_tElements[1]; // This is fine, a Vector always contains at least two elements. } /** \return A const reference to the Z component of a 3 or 4 dimensional Vector. */ - template - inline Type Vector::getZ(void) const + template + inline StorageType Vector::getZ(void) const { +#ifndef SWIGPYTHON // SWIG instantiates all getters, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size >= 3, "You can only get the 'z' component from a vector with at least three elements."); +#endif + return m_tElements[2]; } /** \return A const reference to the W component of a 4 dimensional Vector. */ - template - inline Type Vector::getW(void) const + template + inline StorageType Vector::getW(void) const { +#ifndef SWIGPYTHON // SWIG instantiates all getters, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size >= 4, "You can only get the 'w' component from a vector with at least four elements."); +#endif + return m_tElements[3]; } @@ -429,9 +470,10 @@ namespace PolyVox \param index The index of the element to set. \param tValue The new value for the element. */ - template - inline void Vector::setElement(uint32_t index, Type tValue) + template + inline void Vector::setElement(uint32_t index, StorageType tValue) { + assert(index < Size); m_tElements[index] = tValue; } @@ -440,12 +482,12 @@ namespace PolyVox \param x x component to set. \param y y component to set. */ - template - inline void Vector::setElements(Type x, Type y) + template + inline void Vector::setElements(StorageType x, StorageType y) { + // This is fine, a Vector always contains at least two elements. m_tElements[0] = x; m_tElements[1] = y; - } /** @@ -454,13 +496,15 @@ namespace PolyVox \param y y component to set. \param z z component to set. */ - template - inline void Vector::setElements(Type x, Type y, Type z) + template + inline void Vector::setElements(StorageType x, StorageType y, StorageType z) { +#ifndef SWIGPYTHON // SWIG instantiates all setters, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size >= 3, "You can only use this version of setElements() on a vector with at least three elements."); +#endif m_tElements[0] = x; m_tElements[1] = y; m_tElements[2] = z; - } /** @@ -470,9 +514,12 @@ namespace PolyVox \param z z component to set. \param w w component to set. */ - template - inline void Vector::setElements(Type x, Type y, Type z, Type w) + template + inline void Vector::setElements(StorageType x, StorageType y, StorageType z, StorageType w) { +#ifndef SWIGPYTHON // SWIG instantiates all setters, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size >= 4, "You can only use this version of setElements() on a vector with at least four elements."); +#endif m_tElements[0] = x; m_tElements[1] = y; m_tElements[2] = z; @@ -482,36 +529,42 @@ namespace PolyVox /** \param tX The new value for the X component of a 1, 2, 3, or 4 dimensional Vector. */ - template - inline void Vector::setX(Type tX) + template + inline void Vector::setX(StorageType tX) { - m_tElements[0] = tX; + m_tElements[0] = tX; // This is fine, a Vector always contains at least two elements. } /** \param tY The new value for the Y component of a 2, 3, or 4 dimensional Vector. */ - template - inline void Vector::setY(Type tY) + template + inline void Vector::setY(StorageType tY) { - m_tElements[1] = tY; + m_tElements[1] = tY; // This is fine, a Vector always contains at least two elements. } /** \param tZ The new value for the Z component of a 3 or 4 dimensional Vector. */ - template - inline void Vector::setZ(Type tZ) + template + inline void Vector::setZ(StorageType tZ) { +#ifndef SWIGPYTHON // SWIG instantiates all setters, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size >= 3, "You can only set the 'w' component from a vector with at least three elements."); +#endif m_tElements[2] = tZ; } /** \param tW The new value for the W component of a 4 dimensional Vector. */ - template - inline void Vector::setW(Type tW) + template + inline void Vector::setW(StorageType tW) { +#ifndef SWIGPYTHON // SWIG instantiates all setters, unless we can find a way around that. Should we use SWIGIMPORT here, and then %import this file rather then %include it? + static_assert(Size >= 4, "You can only set the 'w' component from a vector with at least four elements."); +#endif m_tElements[3] = tW; } @@ -519,8 +572,8 @@ namespace PolyVox \note This function does not make much sense on integer Vectors. \return Length of the Vector. */ - template - inline double Vector::length(void) const + template + inline double Vector::length(void) const { return sqrt(lengthSquared()); } @@ -528,8 +581,8 @@ namespace PolyVox /** \return Squared length of the Vector. */ - template - inline double Vector::lengthSquared(void) const + template + inline double Vector::lengthSquared(void) const { double result = 0.0f; for(uint32_t ct = 0; ct < Size; ++ct) @@ -548,8 +601,8 @@ namespace PolyVox \param vector The Vector to find the angle to. \return The angle between them in radians. */ - template - inline double Vector::angleTo(const Vector& vector) const + template + inline double Vector::angleTo(const Vector& vector) const { return acos(dot(vector) / (vector.length() * this->length())); } @@ -566,13 +619,13 @@ namespace PolyVox \return The value of the cross product. \see dot() */ - template - inline Vector Vector::cross(const Vector& vector) const + template + inline Vector Vector::cross(const Vector& vector) const { - Type i = vector.getZ() * this->getY() - vector.getY() * this->getZ(); - Type j = vector.getX() * this->getZ() - vector.getZ() * this->getX(); - Type k = vector.getY() * this->getX() - vector.getX() * this->getY(); - return Vector(i,j,k); + StorageType i = vector.getZ() * this->getY() - vector.getY() * this->getZ(); + StorageType j = vector.getX() * this->getZ() - vector.getZ() * this->getX(); + StorageType k = vector.getY() * this->getX() - vector.getX() * this->getY(); + return Vector(i,j,k); } /** @@ -582,10 +635,10 @@ namespace PolyVox \return The value of the dot product. \see cross() */ - template - inline Type Vector::dot(const Vector& rhs) const + template + inline StorageType Vector::dot(const Vector& rhs) const { - Type dotProduct = static_cast(0); + StorageType dotProduct = static_cast(0); for(uint32_t ct = 0; ct < Size; ++ct) { dotProduct += m_tElements[ct] * rhs.m_tElements[ct]; @@ -598,10 +651,10 @@ namespace PolyVox \note This function does not make much sense on integer Vectors. */ - template - inline void Vector::normalise(void) + template + inline void Vector::normalise(void) { - Type tLength = static_cast(this->length()); + StorageType tLength = static_cast(this->length()); //FIXME - throw div by zero exception? if(tLength < 0.0001f) { diff --git a/library/bindings/Vector.i b/library/bindings/Vector.i index 6bc99d1f..15830de6 100644 --- a/library/bindings/Vector.i +++ b/library/bindings/Vector.i @@ -22,25 +22,25 @@ PROPERTY(PolyVox::Vector, z, getZ, setZ) PolyVox::Vector __div__(const PolyVox::Vector& rhs) { return *$self / rhs; } - PolyVox::Vector __div__(const Type& rhs) { + PolyVox::Vector __div__(const StorageType& rhs) { return *$self / rhs; } PolyVox::Vector __mul__(const PolyVox::Vector& rhs) { return *$self * rhs; } - PolyVox::Vector __mul__(const Type& rhs) { + PolyVox::Vector __mul__(const StorageType& rhs) { return *$self * rhs; } STR() }; -%template(Vector3DFloat) PolyVox::Vector<3,float>; -%template(Vector3DDouble) PolyVox::Vector<3,double>; -%template(Vector3DInt8) PolyVox::Vector<3,int8_t>; -%template(Vector3DUint8) PolyVox::Vector<3,uint8_t>; -%template(Vector3DInt16) PolyVox::Vector<3,int16_t>; -%template(Vector3DUint16) PolyVox::Vector<3,uint16_t>; -%template(Vector3DInt32) PolyVox::Vector<3,int32_t>; -%template(Vector3DUint32) PolyVox::Vector<3,uint32_t>; +%template(Vector3DFloat) PolyVox::Vector<3,float,float>; +%template(Vector3DDouble) PolyVox::Vector<3,double,double>; +%template(Vector3DInt8) PolyVox::Vector<3,int8_t,int32_t>; +%template(Vector3DUint8) PolyVox::Vector<3,uint8_t,int32_t>; +%template(Vector3DInt16) PolyVox::Vector<3,int16_t,int32_t>; +%template(Vector3DUint16) PolyVox::Vector<3,uint16_t,int32_t>; +%template(Vector3DInt32) PolyVox::Vector<3,int32_t,int32_t>; +%template(Vector3DUint32) PolyVox::Vector<3,uint32_t,int32_t>; //%rename(assign) Vector3DFloat::operator=;