worldspawn/libs/generic/vector.h

213 lines
4.0 KiB
C++

#if !defined( INCLUDED_VECTOR_H )
#define INCLUDED_VECTOR_H
#include <cstddef>
template <typename Element>
class BasicVector2
{
Element m_elements[2];
public:
BasicVector2(){
}
BasicVector2( const Element& x_, const Element& y_ ){
x() = x_;
y() = y_;
}
Element& x(){
return m_elements[0];
}
const Element& x() const {
return m_elements[0];
}
Element& y(){
return m_elements[1];
}
const Element& y() const {
return m_elements[1];
}
const Element& operator[]( std::size_t i ) const {
return m_elements[i];
}
Element& operator[]( std::size_t i ){
return m_elements[i];
}
Element* data(){
return m_elements;
}
const Element* data() const {
return m_elements;
}
};
/// \brief A 3-element vector.
template<typename Element>
class BasicVector3
{
Element m_elements[3];
public:
BasicVector3(){
}
template<typename OtherElement>
BasicVector3( const BasicVector3<OtherElement>& other ){
x() = static_cast<Element>( other.x() );
y() = static_cast<Element>( other.y() );
z() = static_cast<Element>( other.z() );
}
BasicVector3( const Element& x_, const Element& y_, const Element& z_ ){
x() = x_;
y() = y_;
z() = z_;
}
Element& x(){
return m_elements[0];
}
const Element& x() const {
return m_elements[0];
}
Element& y(){
return m_elements[1];
}
const Element& y() const {
return m_elements[1];
}
Element& z(){
return m_elements[2];
}
const Element& z() const {
return m_elements[2];
}
const Element& operator[]( std::size_t i ) const {
return m_elements[i];
}
Element& operator[]( std::size_t i ){
return m_elements[i];
}
Element* data(){
return m_elements;
}
const Element* data() const {
return m_elements;
}
};
/// \brief A 4-element vector.
template<typename Element>
class BasicVector4
{
Element m_elements[4];
public:
BasicVector4(){
}
BasicVector4( Element x_, Element y_, Element z_, Element w_ ){
x() = x_;
y() = y_;
z() = z_;
w() = w_;
}
BasicVector4( const BasicVector3<Element>& self, Element w_ ){
x() = self.x();
y() = self.y();
z() = self.z();
w() = w_;
}
Element& x(){
return m_elements[0];
}
const Element& x() const {
return m_elements[0];
}
Element& y(){
return m_elements[1];
}
const Element& y() const {
return m_elements[1];
}
Element& z(){
return m_elements[2];
}
const Element& z() const {
return m_elements[2];
}
Element& w(){
return m_elements[3];
}
const Element& w() const {
return m_elements[3];
}
Element index( std::size_t i ) const {
return m_elements[i];
}
Element& index( std::size_t i ){
return m_elements[i];
}
Element operator[]( std::size_t i ) const {
return m_elements[i];
}
Element& operator[]( std::size_t i ){
return m_elements[i];
}
Element* data(){
return m_elements;
}
const Element* data() const {
return m_elements;
}
};
template<typename Element>
inline BasicVector3<Element> vector3_from_array( const Element* array ){
return BasicVector3<Element>( array[0], array[1], array[2] );
}
template<typename Element>
inline Element* vector3_to_array( BasicVector3<Element>& self ){
return self.data();
}
template<typename Element>
inline const Element* vector3_to_array( const BasicVector3<Element>& self ){
return self.data();
}
template<typename Element>
inline Element* vector4_to_array( BasicVector4<Element>& self ){
return self.data();
}
template<typename Element>
inline const Element* vector4_to_array( const BasicVector4<Element>& self ){
return self.data();
}
template<typename Element>
inline BasicVector3<Element>& vector4_to_vector3( BasicVector4<Element>& self ){
return *reinterpret_cast<BasicVector3<Element>*>( vector4_to_array( self ) );
}
template<typename Element>
inline const BasicVector3<Element>& vector4_to_vector3( const BasicVector4<Element>& self ){
return *reinterpret_cast<const BasicVector3<Element>*>( vector4_to_array( self ) );
}
/// \brief A 2-element vector stored in single-precision floating-point.
typedef BasicVector2<float> Vector2;
/// \brief A 3-element vector stored in single-precision floating-point.
typedef BasicVector3<float> Vector3;
/// \brief A 4-element vector stored in single-precision floating-point.
typedef BasicVector4<float> Vector4;
#endif