251 lines
11 KiB
C++
251 lines
11 KiB
C++
/*******************************************************************************
|
|
Copyright (c) 2005-2009 David Williams
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source
|
|
distribution.
|
|
*******************************************************************************/
|
|
|
|
#ifndef __PolyVox_Vector_H__
|
|
#define __PolyVox_Vector_H__
|
|
|
|
#include "Impl/ErrorHandling.h"
|
|
#include "Impl/TypeDef.h"
|
|
|
|
#include "PolyVoxForwardDeclarations.h"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <cstring>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <memory>
|
|
|
|
namespace PolyVox
|
|
{
|
|
/**
|
|
* Represents a vector in space.
|
|
*
|
|
* This is a generl purpose vector class designed to represent both positions and directions. It is templatised
|
|
* on both size and data type but note that some of the operations do not make sense with integer types. For
|
|
* example it does not make conceptual sense to try and normalise an integer Vector.
|
|
*
|
|
* Every Vector must have at at least two elements, and the first four elements of any vector are known as the
|
|
* X, Y, Z and W elements. Note that W is last even though it comes before X in the alphabet. These elements can
|
|
* be accessed through getX(), setX(), getY(), setY(), getZ(), setZ(), getW() and setW(), while other elements
|
|
* can be accessed through getElemen() and setElement().
|
|
*
|
|
* This class includes a number of common mathematical operations (addition, subtraction, etc) as well as vector
|
|
* specific operations such as the dot and cross products. Note that this class is also templatised on an
|
|
* OperationType which is used for many internal calculations and some results. For example, the square of a
|
|
* vector's length will always be an integer if all the elements are integers, but the value might be outside
|
|
* that which can be represented by the StorageType. You don't need to worry about this as long as you are using
|
|
* the built in typedefs for common configurations.
|
|
*
|
|
* Typedefs are provided for 2, 3 and 4 dimensional vector with int8_t, uint8_t, int16_t, uint6_t, int32_t,
|
|
* uint32_t, float and double types. These typedefs are used as follows:
|
|
*
|
|
* \code
|
|
* Vector2DInt32 test(1,2); //Declares a 2 dimensional Vector of type int32_t.
|
|
* \endcode
|
|
*/
|
|
template <uint32_t Size, typename StorageType, typename OperationType>
|
|
class Vector
|
|
{
|
|
public:
|
|
/// 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<Size,StorageType,OperationType>& vector);
|
|
/// Copy Constructor which performs casting.
|
|
template <typename CastType> explicit Vector(const Vector<Size,CastType>& vector);
|
|
/// Destructor.
|
|
~Vector(void);
|
|
|
|
/// Assignment Operator.
|
|
Vector<Size,StorageType,OperationType>& operator=(const Vector<Size,StorageType,OperationType>& rhs);
|
|
/// Equality Operator.
|
|
bool operator==(const Vector<Size,StorageType,OperationType>& rhs) const;
|
|
/// Inequality Operator.
|
|
bool operator!=(const Vector<Size,StorageType,OperationType>& rhs) const;
|
|
/// Comparison Operator.
|
|
POLYVOX_DEPRECATED bool operator<(const Vector<Size,StorageType,OperationType>& rhs) const;
|
|
/// Addition and Assignment Operator.
|
|
Vector<Size,StorageType,OperationType>& operator+=(const Vector<Size,StorageType,OperationType> &rhs);
|
|
/// Subtraction and Assignment Operator.
|
|
Vector<Size,StorageType,OperationType>& operator-=(const Vector<Size,StorageType,OperationType> &rhs);
|
|
/// Multiplication and Assignment Operator.
|
|
Vector<Size,StorageType,OperationType>& operator*=(const Vector<Size,StorageType,OperationType> &rhs);
|
|
/// Division and Assignment Operator.
|
|
Vector<Size,StorageType,OperationType>& operator/=(const Vector<Size,StorageType,OperationType> &rhs);
|
|
/// Multiplication and Assignment Operator.
|
|
Vector<Size,StorageType,OperationType>& operator*=(const StorageType& rhs);
|
|
/// Division and Assignment Operator.
|
|
Vector<Size,StorageType,OperationType>& operator/=(const StorageType& rhs);
|
|
|
|
/// Element Access.
|
|
StorageType getElement(uint32_t index) const;
|
|
/// Get the x component of the vector.
|
|
StorageType getX(void) const;
|
|
/// Get the y component of the vector.
|
|
StorageType getY(void) const;
|
|
/// Get the z component of the vector.
|
|
StorageType getZ(void) const;
|
|
/// Get the w component of the vector.
|
|
StorageType getW(void) const;
|
|
|
|
/// Element Access.
|
|
void setElement(uint32_t index, StorageType tValue);
|
|
/// Element Access.
|
|
void setElements(StorageType x, StorageType y);
|
|
/// Element Access.
|
|
void setElements(StorageType x, StorageType y, StorageType z);
|
|
/// Element Access.
|
|
void setElements(StorageType x, StorageType y, StorageType z, StorageType w);
|
|
/// Set the x component of the vector.
|
|
void setX(StorageType tX);
|
|
/// Set the y component of the vector.
|
|
void setY(StorageType tY);
|
|
/// Set the z component of the vector.
|
|
void setZ(StorageType tZ);
|
|
/// Set the w component of the vector.
|
|
void setW(StorageType tW);
|
|
|
|
/// Get the length of the vector.
|
|
float length(void) const;
|
|
/// Get the squared length of the vector.
|
|
OperationType lengthSquared(void) const;
|
|
/// Find the angle between this vector and that which is passed as a parameter.
|
|
float angleTo(const Vector<Size,StorageType,OperationType>& vector) const;
|
|
/// Find the cross product between this vector and the vector passed as a parameter.
|
|
Vector<Size,StorageType,OperationType> cross(const Vector<Size,StorageType,OperationType>& vector) const;
|
|
/// Find the dot product between this vector and the vector passed as a parameter.
|
|
OperationType dot(const Vector<Size,StorageType,OperationType>& rhs) const;
|
|
/// Normalise the vector.
|
|
void normalise(void);
|
|
|
|
private:
|
|
// Values for the vector
|
|
StorageType m_tElements[Size];
|
|
};
|
|
|
|
// Non-member overloaded operators.
|
|
/// Addition operator.
|
|
template <uint32_t Size,typename StorageType,typename OperationType>
|
|
Vector<Size,StorageType,OperationType> operator+(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs);
|
|
/// Subtraction operator.
|
|
template <uint32_t Size,typename StorageType,typename OperationType>
|
|
Vector<Size,StorageType,OperationType> operator-(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs);
|
|
/// Multiplication operator.
|
|
template <uint32_t Size,typename StorageType,typename OperationType>
|
|
Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs);
|
|
/// Division operator.
|
|
template <uint32_t Size,typename StorageType,typename OperationType>
|
|
Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const Vector<Size,StorageType,OperationType>& rhs);
|
|
/// Multiplication operator.
|
|
template <uint32_t Size,typename StorageType,typename OperationType>
|
|
Vector<Size,StorageType,OperationType> operator*(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs);
|
|
/// Division operator.
|
|
template <uint32_t Size,typename StorageType,typename OperationType>
|
|
Vector<Size,StorageType,OperationType> operator/(const Vector<Size,StorageType,OperationType>& lhs, const StorageType& rhs);
|
|
/// Stream insertion operator.
|
|
template <uint32_t Size, typename StorageType,typename OperationType>
|
|
std::ostream& operator<<(std::ostream& os, const Vector<Size,StorageType,OperationType>& vector);
|
|
|
|
//Some handy typedefs
|
|
|
|
/// 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
|
|
|
|
namespace std
|
|
{
|
|
template <>
|
|
struct hash<PolyVox::Vector3DInt32>
|
|
{
|
|
std::size_t operator()(const PolyVox::Vector3DInt32& vec) const
|
|
{
|
|
return ((vec.getX() & 0xFF)) | ((vec.getY() & 0xFF) << 8) | ((vec.getZ() & 0xFF) << 16);
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
#include "PolyVox/Vector.inl"
|
|
|
|
#endif
|
|
|