Initial checkin.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b45a037
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+Build
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..75c78a6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,44 @@
+# Specify extensions of files to delete when cleaning
+CPP_COMPILER	= clang++
+CPP_FLAGS		= -Wall -Werror -g -std=c++11 -I./
+DEFINES			=
+# Wildcard selector.
+rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
+# Specify the target file and the install directory
+OUTPUTFILE 		= libnima-math.a
+BUILD_DIR 		= Build
+LIB_DIR			= $(BUILD_DIR)/lib
+OBJ_DIR			= $(BUILD_DIR)/obj
+INCLUDE_DIR		= $(BUILD_DIR)/include/nima
+CPP_SOURCES		= $(call rwildcard,Source/,*.cpp)
+CPP_OBJECTS		= $(CPP_SOURCES:%.cpp=$(OBJ_DIR)/%.o)
+CPP_FOLDERS		= $(sort $(dir $(CPP_OBJECTS)))
+HEADERS			= $(call rwildcard,Source/,*.hpp)
+# Default target
+#all: dirs $(OUTPUTFILE)
+#	cd Example && make
+
+all: dirs $(OUTPUTFILE)
+# Copy header files to include dir.
+	$(foreach header,$(HEADERS),$(shell mkdir -p $(INCLUDE_DIR)/$(dir $(subst Source/,,$(header))) && cp $(header) $(INCLUDE_DIR)/$(subst Source/,,$(header))))
+
+clean:
+	$(RM) -fR $(BUILD_DIR)
+
+dirs:
+	mkdir -p $(OBJ_DIR)
+	mkdir -p $(LIB_DIR)
+	mkdir -p $(INCLUDE_DIR)
+	$(foreach folder,$(CPP_FOLDERS),$(shell mkdir -p $(folder)))
+	
+install:
+	cp -r Build/include/ /usr/local/include
+	cp -r Build/lib/ /usr/local/lib
+
+# Build sources
+$(OUTPUTFILE): $(CPP_OBJECTS)
+	ar ru $(LIB_DIR)/$@ $^
+	ranlib $(LIB_DIR)/$@
+
+$(OBJ_DIR)/%.o: %.cpp
+	$(CPP_COMPILER) $(CPP_FLAGS) $(DEFINES) -c $< -o $@
\ No newline at end of file
diff --git a/Source/Mat2D.cpp b/Source/Mat2D.cpp
new file mode 100644
index 0000000..a9b34a1
--- /dev/null
+++ b/Source/Mat2D.cpp
@@ -0,0 +1,69 @@
+#include "Mat2D.hpp"
+#include "Vec2D.hpp"
+#include <cmath>
+
+using namespace nima;
+
+Mat2D::Mat2D() : m_Buffer{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}
+{
+}
+
+Mat2D::Mat2D(const Mat2D& copy) : m_Buffer{copy[0], copy[1], copy[2], copy[3], copy[4], copy[5]}
+{
+	
+}
+
+void Mat2D::fromRotation(Mat2D& result, float rad)
+{
+	float s = sin(rad);
+	float c = cos(rad);
+	result[0] = c;
+	result[1] = s;
+	result[2] = -s;
+	result[3] = c;
+	result[4] = 0;
+	result[5] = 0;
+}
+
+void Mat2D::scale(Mat2D& result, const Mat2D& mat, const Vec2D& vec)
+{
+	float v0 = vec[0], v1 = vec[1];
+	result[0] = mat[0] * v0;
+	result[1] = mat[1] * v0;
+	result[2] = mat[2] * v1;
+	result[3] = mat[3] * v1;
+	result[4] = mat[4];
+	result[5] = mat[5];
+}
+
+void Mat2D::multiply(Mat2D& result, const Mat2D& a, const Mat2D& b)
+{
+	float a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
+			b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5];
+	result[0] = a0 * b0 + a2 * b1;
+	result[1] = a1 * b0 + a3 * b1;
+	result[2] = a0 * b2 + a2 * b3;
+	result[3] = a1 * b2 + a3 * b3;
+	result[4] = a0 * b4 + a2 * b5 + a4;
+	result[5] = a1 * b4 + a3 * b5 + a5;
+}
+
+bool Mat2D::invert(Mat2D& result, const Mat2D& a)
+{
+	float aa = a[0], ab = a[1], ac = a[2], ad = a[3], atx = a[4], aty = a[5];
+
+	float det = aa * ad - ab * ac;
+	if(det == 0.0f)
+	{
+		return false;
+	}
+	det = 1.0f / det;
+
+	result[0] = ad * det;
+	result[1] = -ab * det;
+	result[2] = -ac * det;
+	result[3] = aa * det;
+	result[4] = (ac * aty - ad * atx) * det;
+	result[5] = (ab * atx - aa * aty) * det;
+	return true;
+}
\ No newline at end of file
diff --git a/Source/Mat2D.hpp b/Source/Mat2D.hpp
new file mode 100644
index 0000000..dbd62ec
--- /dev/null
+++ b/Source/Mat2D.hpp
@@ -0,0 +1,27 @@
+#ifndef _NIMA_MAT2D_HPP_
+#define _NIMA_MAT2D_HPP_
+
+#include <cstddef>
+
+namespace nima
+{
+	class Vec2D;
+	class Mat2D
+	{
+		private:
+			float m_Buffer[6];
+
+		public:
+			Mat2D();
+			Mat2D(const Mat2D& copy);
+
+			float& operator[](std::size_t idx) { return m_Buffer[idx]; }
+			const float& operator[](std::size_t idx) const { return m_Buffer[idx]; }
+
+			static void fromRotation(Mat2D& result, float rad);
+			static void scale(Mat2D& result, const Mat2D& mat, const Vec2D& vec);
+			static void multiply(Mat2D& result, const Mat2D& a, const Mat2D& b);
+			static bool invert(Mat2D& result, const Mat2D& a);
+	};
+}
+#endif
\ No newline at end of file
diff --git a/Source/Vec2D.cpp b/Source/Vec2D.cpp
new file mode 100644
index 0000000..dfb25c9
--- /dev/null
+++ b/Source/Vec2D.cpp
@@ -0,0 +1,36 @@
+#include "Vec2D.hpp"
+#include "Mat2D.hpp"
+#include <cmath>
+
+using namespace nima;
+
+Vec2D::Vec2D() : m_Buffer{0.0f,0.0f}
+{
+
+}
+
+Vec2D::Vec2D(const Vec2D& copy) : m_Buffer{copy.m_Buffer[0], copy.m_Buffer[1]}
+{
+
+}
+
+void Vec2D::transform(Vec2D& result, const Vec2D& a, const Mat2D& m)
+{
+	float x = a[0];
+	float y = a[1];
+	result[0] = m[0] * x + m[2] * y + m[4];
+	result[1] = m[1] * x + m[3] * y + m[5];
+}
+
+void Vec2D::subtract(Vec2D& result, const Vec2D& a, const Vec2D& b)
+{
+	result[0] = a[0] - b[0];
+	result[1] = a[1] - b[1];
+}
+
+float Vec2D::length(const Vec2D& a)
+{
+	float x = a[0];
+	float y = a[1];
+	return sqrt(x*x + y*y);
+}
\ No newline at end of file
diff --git a/Source/Vec2D.hpp b/Source/Vec2D.hpp
new file mode 100644
index 0000000..2c9824f
--- /dev/null
+++ b/Source/Vec2D.hpp
@@ -0,0 +1,25 @@
+#ifndef _NIMA_VEC2D_HPP_
+#define _NIMA_VEC2D_HPP_
+
+#include <cstddef>
+
+namespace nima
+{
+	class Mat2D;
+	class Vec2D
+	{
+		private:
+			float m_Buffer[2];
+		public:
+			Vec2D();
+			Vec2D(const Vec2D& copy);
+
+			float& operator[](std::size_t idx) { return m_Buffer[idx]; }
+			const float& operator[](std::size_t idx) const { return m_Buffer[idx]; }
+
+			static void transform(Vec2D& result, const Vec2D& a, const Mat2D& m);
+			static void subtract(Vec2D& result, const Vec2D& a, const Vec2D& b);
+			static float length(const Vec2D& a);
+	};
+}
+#endif
\ No newline at end of file
diff --git a/Test/Main.cpp b/Test/Main.cpp
new file mode 100644
index 0000000..d0f530c
--- /dev/null
+++ b/Test/Main.cpp
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+#include <nima/Mat2D.hpp>
+#include <nima/Vec2D.hpp>
+
+using namespace nima;
+
+int main(int argc, char** argv)
+{
+	printf("OK\n");
+	Mat2D matA;
+	matA[0] = 1.0f; matA[1] = 2.0f; matA[2] = 3.0f; matA[3] = 4.0f; matA[4] = 5.0f; matA[5] = 6.0f;
+	Mat2D matB;
+	matB[0] = 7.0f; matB[1] = 8.0f; matB[2] = 9.0f; matB[3] = 10.0f; matB[4] = 11.0f; matB[5] = 12.0f;
+
+	Mat2D result;
+	Mat2D::invert(result, matA);
+	if(result[0] == -2.0f && result[1] == 1.0f && result[2] == 1.5f && result[3] == -0.5f && result[4] == 1.0f && result[5] == -2.0f)
+	{
+		printf("Invert ok\n");
+	}
+
+	Mat2D::multiply(result, matA, matB);
+	if(result[0] == 31.0f && result[1] == 46.0f && result[2] == 39.0f && result[3] == 58.0f && result[4] == 52.0f && result[5] == 76.0f)
+	{
+		printf("Multiply ok\n");
+	}
+
+	return 0;
+}
\ No newline at end of file
diff --git a/Test/Makefile b/Test/Makefile
new file mode 100644
index 0000000..f6ed396
--- /dev/null
+++ b/Test/Makefile
@@ -0,0 +1,28 @@
+# Specify extensions of files to delete when cleaning
+CPP_COMPILER	= clang++
+CPP_FLAGS		= -Wall -g -std=c++11
+# Specify the target file and the install directory
+OUTPUTFILE 		= Nima-Cpp-MathTest
+BUILD_DIR 		= Build
+OBJ_DIR			= $(BUILD_DIR)/obj
+CPP_SOURCES		= Main.cpp
+CPP_OBJECTS		= $(CPP_SOURCES:%.cpp=$(OBJ_DIR)/%.o)
+CPP_INCLUDES	= -I/usr/local/include -I../Build/include 
+LFLAGS			= -Wl,-rpath,./ -L/usr/local/lib -L../Build/lib
+LIBS			= -lnima-math
+
+# Default target
+all: dirs $(OUTPUTFILE)
+
+clean:
+	$(RM) -fR $(OBJ_DIR)/Main.o
+
+dirs:
+	mkdir -p $(OBJ_DIR)
+
+# Build sources
+$(OUTPUTFILE): $(CPP_OBJECTS)
+	$(CPP_COMPILER) $(CPP_FLAGS) $(CPP_INCLUDES) -o $(BUILD_DIR)/$(OUTPUTFILE) $(CPP_OBJECTS) $(LFLAGS) $(LIBS)
+
+$(OBJ_DIR)/%.o: %.cpp
+	$(CPP_COMPILER) $(CPP_FLAGS) $(CPP_INCLUDES) -c $< -o $@
\ No newline at end of file