Skip to content

Commit

Permalink
Multiple updates, fixes and unit tests for Vector<N, T>
Browse files Browse the repository at this point in the history
  • Loading branch information
DDuarte committed Mar 14, 2013
1 parent 9f817d3 commit 2411bfb
Show file tree
Hide file tree
Showing 12 changed files with 29,709 additions and 57 deletions.
7 changes: 0 additions & 7 deletions src/LeClient/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@

int main(int argc, char* argv[])
{
mat4 t = translate(1.0f, 1.0f, 1.0f);
mat4 s = scale(2.0f, 2.0f, 2.0f);
mat4 rx = rotate(45.0f, vec3(1,0,0));
mat4 ry = rotate(45.0f, vec3(0,1,0));
mat4 rz = rotate(45.0f, vec3(0,0,1));
mat4 r = rotate(45.0f, vec3(1,1,1));

new Application();
Application::Get().Run(argc, argv);
delete Application::GetPtr();
Expand Down
4 changes: 2 additions & 2 deletions src/LeEngine/DMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class Math
static Real ModF(Real val, Real* intPart) { return modf(val, intPart); }

// Power
static Real Pow(Real base, int exponent) { return pow(base, exponent); }
static Real Powr(Real base, Real exponent) { return pow(base, exponent); }
template<typename T>
static Real Pow(Real base, T exponent) { return pow(base, exponent); }
static Real Sqrt(Real val) { return sqrt(val); }
static Real InvSqrt(Real val) { return 1/Sqrt(val); }
static Real Sqr(Real val) { return val*val; }
Expand Down
5 changes: 2 additions & 3 deletions src/LeEngine/Matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <cstdarg>
#include <vector>


#include <boost/shared_array.hpp>
using boost::shared_array;

Expand Down Expand Up @@ -368,15 +367,15 @@ inline mat4 scale(float x, float y, float z)
return mat4(m);
}

inline mat4 rotate(float rotation, vec3 axis)
inline mat4 rotate(float rotation, Vector3f axis)
{
float a = rotation * Math<float>::ACos(-1.0f) / 180.0f;
float c = Math<float>::Cos(a);
float s = Math<float>::Sin(a);

axis.Normalize();

vec3 temp = axis * (1-c);
Vector3f temp = axis * (1-c);

float m[] = { axis[0] * temp[0] + c,
axis[1] * temp[0] - axis[2]*s,
Expand Down
108 changes: 75 additions & 33 deletions src/LeEngine/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,91 @@
#include "DMath.h"
#include "MathDefines.h"

#include <type_traits>
//#include <initializer_list>

template<int Size, typename T = float>
class Vector
{
static_assert(std::is_scalar<T>::value, "Vector should use a scalar type.");
private:
T V[Size];

public:
typedef typename std::conditional<std::is_floating_point<T>::value, T, double>::type Real;
typedef T Type;
static const int Size = Size;
static const Vector<Size, T> ZERO;

Vector() { memset(V, 0, Size * sizeof(T)); }

Vector(T x, T y)
{
assert(Size == 2);
static_assert(Size == 2, "T x, T y constructor requires Size == 2");
V[0] = x;
V[1] = y;
}

Vector(T x, T y, T z)
{
assert(Size == 3);
static_assert(Size == 3, "T x, T y, T z constructor requires Size == 3");
V[0] = x;
V[1] = y;
V[2] = z;
}

Vector(T x, T y, T z, T w)
{
assert(Size == 4);
static_assert(Size == 4, "T x, T y, T z, T w constructor requires Size == 4");
V[0] = x;
V[1] = y;
V[2] = z;
V[3] = w;
}

// One day this will be properly supported by compilers...
//template< typename... Arguments>
//Vector(Arguments... parameters)
//{
// static const unsigned short int size = sizeof...(Arguments);
// static_assert(size == Size, "The number of arguments of Vector should be the same of the templated Size");
//
// int i = 0;
// auto args = { parameters... };
// for (auto arg : args)
// V[i++] = static_cast<T>(arg);
//}

Vector(const Vector<Size, T>& other) { memcpy(V, other.V, Size * sizeof(T)); }
Vector(const T arr[Size]) { memcpy(V, arr, Size * sizeof(T)); }
Vector(T val) { for (int i = 0; i < Size; ++i) V[i] = val; }

T X() const { assert(Size >= 1); return V[0]; }
T Y() const { assert(Size >= 2); return V[1]; }
T Z() const { assert(Size >= 3); return V[2]; }
T W() const { assert(Size >= 4); return V[3]; }
const T& X() const { static_assert(Size >= 1, "const X() requires at least size 1"); return V[0]; }
const T& Y() const { static_assert(Size >= 2, "const Y() requires at least size 2"); return V[1]; }
const T& Z() const { static_assert(Size >= 3, "const Z() requires at least size 3"); return V[2]; }
const T& W() const { static_assert(Size >= 4, "const W() requires at least size 4"); return V[3]; }

T& X() { assert(Size >= 1); return V[0]; }
T& Y() { assert(Size >= 2); return V[1]; }
T& Z() { assert(Size >= 3); return V[2]; }
T& W() { assert(Size >= 4); return V[3]; }
T& X() { static_assert(Size >= 1, "X() requires at least size 1"); return V[0]; }
T& Y() { static_assert(Size >= 2, "Y() requires at least size 2"); return V[1]; }
T& Z() { static_assert(Size >= 3, "Z() requires at least size 3"); return V[2]; }
T& W() { static_assert(Size >= 4, "W() requires at least size 4"); return V[3]; }

T operator [](int index) const { assert(index < Size); return V[index]; }
const T& operator [](int index) const { assert(index < Size); return V[index]; }
T& operator [](int index) { assert(index < Size); return V[index]; }

operator const T* () const { return V; }
operator T* () { return V; }

void SetX(T x) { assert(Size >= 1); V[0] = x; }
void SetY(T y) { assert(Size >= 2); V[1] = y; }
void SetZ(T z) { assert(Size >= 3); V[2] = z; }
void SetW(T w) { assert(Size >= 4); V[3] = w; }
void Set(T x, T y) { assert(Size >= 2); V[0] = x; V[1] = y; }
void Set(T x, T y, T z) { assert(Size >= 3); V[0] = x; V[1] = y; V[2] = z; }
void Set(T x, T y, T z, T w) { assert(Size >= 4); V[0] = x; V[1] = y; V[2] = z; V[3] = w; }
void SetX(T x) { static_assert(Size >= 1, "SetX() requires at least size 1"); V[0] = x; }
void SetY(T y) { static_assert(Size >= 2, "SetY() requires at least size 2"); V[1] = y; }
void SetZ(T z) { static_assert(Size >= 3, "SetZ() requires at least size 3"); V[2] = z; }
void SetW(T w) { static_assert(Size >= 4, "SetW() requires at least size 4"); V[3] = w; }
void Set(T x) { static_assert(Size >= 2, "Set(T) requires at least size 1"); V[0] = x; }
void Set(T x, T y) { static_assert(Size >= 2, "Set(T, T) requires at least size 2"); V[0] = x; V[1] = y; }
void Set(T x, T y, T z) { static_assert(Size >= 3, "Set(T, T, T) requires at least size 3"); V[0] = x; V[1] = y; V[2] = z; }
void Set(T x, T y, T z, T w) { static_assert(Size >= 4, , "Set(T, T, T, T) requires at least size 4"); V[0] = x; V[1] = y; V[2] = z; V[3] = w; }

bool operator ==(const Vector<Size, T>& other) const { return memcmp(V, other.V, Size * sizeof(T)) != 0; }
bool operator ==(const Vector<Size, T>& other) const { return memcmp(V, other.V, Size * sizeof(T)) == 0; }
bool operator !=(const Vector<Size, T>& other) const { return !operator ==(other); }

Vector<Size, T> operator +(const Vector<Size, T>& other) const
Expand All @@ -80,15 +107,15 @@ class Vector
return result;
}

Vector<Size, T> operator *(const T scalar) const
Vector<Size, T> operator *(const T& scalar) const
{
Vector<Size, T> result;
for (int i = 0; i < Size; ++i)
result[i] = V[i] * scalar;
return result;
}

Vector<Size, T> operator /(const T scalar) const
Vector<Size, T> operator /(const T& scalar) const
{
assert(!IsZero(scalar));

Expand Down Expand Up @@ -162,7 +189,7 @@ class Vector
}

//! The magnitude or length of this vector
T Magnitude() const { return Mathf::Sqrt(MagnitudeSqr()); }
Real Magnitude() const { return Math<Real>::Sqrt(MagnitudeSqr()); }
//! The squared magnitude or length of this vector (more efficient)
T MagnitudeSqr() const
{
Expand Down Expand Up @@ -209,28 +236,25 @@ class Vector
//! Returns the cross product (a vector) between this vector and some other
Vector<Size, T> CrossProduct(const Vector<Size, T>& other) const
{
static_assert(Size == 2 || Size == 3, "Cross product not defined for more than 3 dimensions");

if (Size == 2) // this needs some sort of split
return V[0] * other.V[1] - V[1] * other.V[0];
else if (Size == 3)
return Vector<Size, T>(V[1] * other.V[2] - V[2] * other.V[1],
V[2] * other.V[0] - V[0] * other.V[2],
V[0] * other.V[1] - V[1] * other.V[0]);
else
{
assert(false && "Cross product not defined for more than 3 dimensions");
return Vector<Size, T>();
}
}

//! Returns the angle in radians of this vector and other
float AngleBetween(const Vector<Size, T>& other) const
Real AngleBetween(const Vector<Size, T>& other) const
{
T dotP = DotProduct(other);
T lengthP = Magnitude() * other.Magnitude();
Real lengthP = Magnitude() * other.Magnitude();

assert(!IsZero(lengthP));

return acos((float)dotP / lengthP);
return Math<Real>::ACos(dotP / lengthP);
}

//! Returns a vector that is perpendicular to this vector
Expand All @@ -250,12 +274,30 @@ class Vector
}
else
{
assert(false && "Perpendicular vector is not defined for more than 3 dimensions");
static_assert(false && "Perpendicular vector is not defined for more than 3 dimensions");
return Vector<Size, T>();
}
}

//! Also named box product. Signed volume of a parallelepiped formed by u, v and w.
static T ScalarTripleProduct(const Vector<Size, T>& u, const Vector<Size, T>& v, const Vector<Size, T>& w)
{
return u.CrossProduct(v).DotProduct(w);
}
};

typedef Vector<3, float> vec3;
template<int Size, typename T>
const Vector<Size, T> Vector<Size, T>::ZERO;

typedef Vector<2, float> Vector2f;
typedef Vector<2, double> Vector2d;
typedef Vector<2, int> Vector2i;
typedef Vector<3, float> Vector3f;
typedef Vector<3, double> Vector3d;
typedef Vector<3, int> Vector3i;

// Helpers for scalar multiplications
template <int Size, typename T> Vector<Size, T> operator *(const T& scalar, const Vector<Size, T>& rhs) { return rhs * scalar; }
template <int Size, typename T> Vector<Size, T> operator /(const T& scalar, const Vector<Size, T>& rhs) { return rhs / scalar; }

#endif // VECTOR_H
12 changes: 6 additions & 6 deletions src/LeEngine/Vertex.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
class Vertex : public IRenderable
{
public:
vec3 Position;
Vector3f Position;

Vertex() : Position(vec3()) { }
Vertex(vec3 pos) : Position(pos) { }
Vertex() : Position(Vector3f()) { }
Vertex(const Vector3f& pos) : Position(pos) { }

void Render() const
{
Expand All @@ -28,7 +28,7 @@ class RGBVertex : public Vertex
ColorRGB Color;

RGBVertex() : Vertex(), Color(ColorRGB::WHITE) { }
RGBVertex(vec3 pos, ColorRGB color = ColorRGB::WHITE) : Vertex(pos), Color(color) { }
RGBVertex(const Vector3f& pos, ColorRGB color = ColorRGB::WHITE) : Vertex(pos), Color(color) { }

void Render() const
{
Expand All @@ -43,7 +43,7 @@ class RGBAVertex : public Vertex
ColorRGBA Color;

RGBAVertex() : Vertex(), Color(ColorRGB::WHITE) { }
RGBAVertex(vec3 pos, ColorRGB color = ColorRGB::WHITE) : Vertex(pos), Color(color) { }
RGBAVertex(Vector3f pos, ColorRGB color = ColorRGB::WHITE) : Vertex(pos), Color(color) { }

void Render() const
{
Expand All @@ -58,7 +58,7 @@ class UVVertex : public Vertex
Vector<2,float> UV;

UVVertex() : Vertex(), UV(Vector<2,float>()) { }
UVVertex(vec3 pos, Vector<2,float> uv = Vector<2,float>()) : Vertex(pos), UV(uv) { }
UVVertex(Vector3f pos, Vector<2,float> uv = Vector<2,float>()) : Vertex(pos), UV(uv) { }

void Render() const
{
Expand Down
18 changes: 12 additions & 6 deletions src/LeLab.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LeClient", "LeClient\LeClient.vcxproj", "{DC5D23A3-53BB-45E5-B841-6E902CB3832D}"
ProjectSection(ProjectDependencies) = postProject
{29A79727-C3C8-49B2-AC86-1DAD9EFAEF3A} = {29A79727-C3C8-49B2-AC86-1DAD9EFAEF3A}
Expand Down Expand Up @@ -28,6 +28,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glew_static", "..\libs\glew
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SOIL", "..\libs\soil\SOIL.vcxproj", "{C32FB2B4-500C-43CD-A099-EECCE079D3F1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LeTests", "LeTests\LeTests.vcxproj", "{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Expand Down Expand Up @@ -57,11 +59,9 @@ Global
{5691E159-2D9B-407F-971F-EA5C592DC524}.Debug|Win32.ActiveCfg = debug|Win32
{5691E159-2D9B-407F-971F-EA5C592DC524}.Debug|Win32.Build.0 = debug|Win32
{5691E159-2D9B-407F-971F-EA5C592DC524}.Debug|x64.ActiveCfg = debug|x64
{5691E159-2D9B-407F-971F-EA5C592DC524}.Debug|x64.Build.0 = debug|x64
{5691E159-2D9B-407F-971F-EA5C592DC524}.Release|Win32.ActiveCfg = release|Win32
{5691E159-2D9B-407F-971F-EA5C592DC524}.Release|Win32.Build.0 = release|Win32
{5691E159-2D9B-407F-971F-EA5C592DC524}.Release|x64.ActiveCfg = release|x64
{5691E159-2D9B-407F-971F-EA5C592DC524}.Release|x64.Build.0 = release|x64
{4DA03747-F505-4A98-9124-03B3B73B9B3B}.Debug|Win32.ActiveCfg = Debug|Win32
{4DA03747-F505-4A98-9124-03B3B73B9B3B}.Debug|Win32.Build.0 = Debug|Win32
{4DA03747-F505-4A98-9124-03B3B73B9B3B}.Debug|x64.ActiveCfg = Debug|Win32
Expand All @@ -77,11 +77,17 @@ Global
{C32FB2B4-500C-43CD-A099-EECCE079D3F1}.Debug|Win32.ActiveCfg = Debug|Win32
{C32FB2B4-500C-43CD-A099-EECCE079D3F1}.Debug|Win32.Build.0 = Debug|Win32
{C32FB2B4-500C-43CD-A099-EECCE079D3F1}.Debug|x64.ActiveCfg = Debug|x64
{C32FB2B4-500C-43CD-A099-EECCE079D3F1}.Debug|x64.Build.0 = Debug|x64
{C32FB2B4-500C-43CD-A099-EECCE079D3F1}.Release|Win32.ActiveCfg = Release|Win32
{C32FB2B4-500C-43CD-A099-EECCE079D3F1}.Release|Win32.Build.0 = Release|Win32
{C32FB2B4-500C-43CD-A099-EECCE079D3F1}.Release|x64.ActiveCfg = Release|x64
{C32FB2B4-500C-43CD-A099-EECCE079D3F1}.Release|x64.Build.0 = Release|x64
{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}.Debug|Win32.ActiveCfg = Debug|x64
{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}.Debug|Win32.Build.0 = Debug|x64
{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}.Debug|x64.ActiveCfg = Debug|x64
{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}.Debug|x64.Build.0 = Debug|x64
{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}.Release|Win32.ActiveCfg = Release|Win32
{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}.Release|Win32.Build.0 = Release|Win32
{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}.Release|x64.ActiveCfg = Release|x64
{4D8AC200-B945-4A18-8FD5-3AD1D4E3B05E}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit 2411bfb

Please sign in to comment.