Переглянути джерело

Add matrix determinant and inverse methods.

legacy
Sam Hocevar sam 14 роки тому
джерело
коміт
7015943141
10 змінених файлів з 179 додано та 27 видалено
  1. +8
    -7
      src/Makefile.am
  2. +64
    -0
      src/matrix.cpp
  3. +24
    -12
      src/matrix.h
  4. +70
    -7
      test/matrix.cpp
  5. +1
    -0
      win32/deushax.vcxproj
  6. +3
    -0
      win32/deushax.vcxproj.filters
  7. +1
    -0
      win32/editor.vcxproj
  8. +4
    -1
      win32/editor.vcxproj.filters
  9. +1
    -0
      win32/monsterz.vcxproj
  10. +3
    -0
      win32/monsterz.vcxproj.filters

+ 8
- 7
src/Makefile.am Переглянути файл

@@ -2,13 +2,14 @@
noinst_LIBRARIES = liblol.a

liblol_a_SOURCES = \
core.h matrix.h tiler.cpp tiler.h dict.cpp dict.h audio.cpp audio.h \
scene.cpp scene.h font.cpp font.h layer.cpp layer.h map.cpp map.h \
entity.cpp entity.h ticker.cpp ticker.h tileset.cpp tileset.h \
forge.cpp forge.h video.cpp video.h timer.cpp timer.h bitfield.h \
profiler.cpp profiler.h input.h input.cpp world.cpp world.h \
sample.cpp sample.h sampler.cpp sampler.h text.cpp text.h \
emitter.cpp emitter.h numeric.h worldentity.cpp worldentity.h \
core.h matrix.cpp matrix.h tiler.cpp tiler.h dict.cpp dict.h \
audio.cpp audio.h scene.cpp scene.h font.cpp font.h layer.cpp layer.h \
map.cpp map.h entity.cpp entity.h ticker.cpp ticker.h \
tileset.cpp tileset.h forge.cpp forge.h video.cpp video.h \
timer.cpp timer.h bitfield.h profiler.cpp profiler.h input.h input.cpp \
world.cpp world.h sample.cpp sample.h sampler.cpp sampler.h \
text.cpp text.h emitter.cpp emitter.h numeric.h \
worldentity.cpp worldentity.h \
\
sdlinput.cpp sdlinput.h \
\


+ 64
- 0
src/matrix.cpp Переглянути файл

@@ -0,0 +1,64 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://sam.zoy.org/projects/COPYING.WTFPL for more details.
//

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include <cstdio>
#include <cstdlib> /* free() */
#include <cstring> /* strdup() */

#include "core.h"

static inline float det3(float a, float b, float c,
float d, float e, float f,
float g, float h, float i)
{
return a * (e * i - h * f)
+ b * (f * g - i * d)
+ c * (d * h - g * e);
}

static inline float cofact3(float4x4 const &mat, int i, int j)
{
return det3(mat[(i + 1) & 3][(j + 1) & 3],
mat[(i + 2) & 3][(j + 1) & 3],
mat[(i + 3) & 3][(j + 1) & 3],
mat[(i + 1) & 3][(j + 2) & 3],
mat[(i + 2) & 3][(j + 2) & 3],
mat[(i + 3) & 3][(j + 2) & 3],
mat[(i + 1) & 3][(j + 3) & 3],
mat[(i + 2) & 3][(j + 3) & 3],
mat[(i + 3) & 3][(j + 3) & 3]) * (((i + j) & 1) ? -1.0f : 1.0f);
}

template<> float float4x4::det() const
{
float ret = 0;
for (int n = 0; n < 4; n++)
ret += (*this)[n][0] * cofact3(*this, n, 0);
return ret;
}

template<> float4x4 float4x4::invert() const
{
float4x4 ret;
float d = det();
if (d)
{
d = 1.0f / d;
for (int j = 0; j < 4; j++)
for (int i = 0; i < 4; i++)
ret[j][i] = cofact3(*this, i, j) * d;
}
return ret;
}


+ 24
- 12
src/matrix.h Переглянути файл

@@ -175,37 +175,49 @@ GLOBALS(2)
GLOBALS(3)
GLOBALS(4)

template <typename T> struct Vec4x4
template <typename T> struct Mat4
{
inline Vec4x4() { }
inline Vec4x4(T val) { v[0] = v[1] = v[2] = v[3] = val; }
inline Vec4x4(Vec4<T> v0, Vec4<T> v1, Vec4<T> v2, Vec4<T> v3)
inline Mat4() { }
inline Mat4(T val) { for (int i = 0; i < 4; i++) v[i] = val; }
inline Mat4(Vec4<T> v0, Vec4<T> v1, Vec4<T> v2, Vec4<T> v3)
{ v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3; }

inline Vec4<T>& operator[](int n) { return v[n]; }
inline Vec4<T> const& operator[](int n) const { return v[n]; }

inline Vec4x4<T> operator +(Vec4x4<T> const val) const
static inline Mat4<T> identity()
{
Vec4x4<T> ret;
Mat4<T> ret;
for (int j = 0; j < 4; j++)
for (int i = 0; i < 4; i++)
ret[i][j] = i == j;
return ret;
}

T det() const;
Mat4<T> invert() const;

inline Mat4<T> operator +(Mat4<T> const val) const
{
Mat4<T> ret;
for (int j = 0; j < 4; j++)
for (int i = 0; i < 4; i++)
ret[i][j] = v[i][j] + val[i][j];
return ret;
}

inline Vec4x4<T> operator -(Vec4x4<T> const val) const
inline Mat4<T> operator -(Mat4<T> const val) const
{
Vec4x4<T> ret;
Mat4<T> ret;
for (int j = 0; j < 4; j++)
for (int i = 0; i < 4; i++)
ret[i][j] = v[i][j] - val[i][j];
return ret;
}

inline Vec4x4<T> operator *(Vec4x4<T> const val) const
inline Mat4<T> operator *(Mat4<T> const val) const
{
Vec4x4<T> ret;
Mat4<T> ret;
for (int j = 0; j < 4; j++)
for (int i = 0; i < 4; i++)
{
@@ -233,8 +245,8 @@ template <typename T> struct Vec4x4
Vec4<T> v[4];
};

typedef Vec4x4<float> float4x4;
typedef Vec4x4<int> int4x4;
typedef Mat4<float> float4x4;
typedef Mat4<int> int4x4;

#endif // __DH_MATRIX_H__


+ 70
- 7
test/matrix.cpp Переглянути файл

@@ -22,31 +22,94 @@
class MatrixTest : public CppUnit::TestCase
{
CPPUNIT_TEST_SUITE(MatrixTest);
CPPUNIT_TEST(test_mat_det);
CPPUNIT_TEST(test_mat_mul);
CPPUNIT_TEST(test_mat_inv);
CPPUNIT_TEST_SUITE_END();

public:
MatrixTest() : CppUnit::TestCase("Matrix Test") {}

void setUp() {}
void setUp()
{
identity = float4x4::identity();
triangular = float4x4(float4(1.0f, 0.0f, 0.0f, 0.0f),
float4(7.0f, 2.0f, 0.0f, 0.0f),
float4(1.0f, 5.0f, 3.0f, 0.0f),
float4(8.0f, 9.0f, 2.0f, 4.0f));
invertible = float4x4(float4( 1.0f, 1.0f, 2.0f, -1.0f),
float4(-2.0f, -1.0f, -2.0f, 2.0f),
float4( 4.0f, 2.0f, 5.0f, -4.0f),
float4( 5.0f, -3.0f, -7.0f, -6.0f));
}

void tearDown() {}

void test_mat_det()
{
float d1 = triangular.det();
CPPUNIT_ASSERT(d1 == 24.0f);
float d2 = invertible.det();
CPPUNIT_ASSERT(d2 == -1.0f);
}

void test_mat_mul()
{
float4 v0(1.0f, 0.0f, 0.0f, 0.0f);
float4 v1(0.0f, 1.0f, 0.0f, 0.0f);
float4 v2(0.0f, 0.0f, 1.0f, 0.0f);
float4 v3(0.0f, 0.0f, 0.0f, 1.0f);
float4x4 m0(v0, v1, v2, v3);
float4x4 m1(v0, v1, v2, v3);
float4x4 m0 = identity;
float4x4 m1 = identity;
float4x4 m2 = m0 * m1;

CPPUNIT_ASSERT(m2[0][0] == 1.0f);
CPPUNIT_ASSERT(m2[1][0] == 0.0f);
CPPUNIT_ASSERT(m2[2][0] == 0.0f);
CPPUNIT_ASSERT(m2[3][0] == 0.0f);

CPPUNIT_ASSERT(m2[0][1] == 0.0f);
CPPUNIT_ASSERT(m2[1][1] == 1.0f);
CPPUNIT_ASSERT(m2[2][1] == 0.0f);
CPPUNIT_ASSERT(m2[3][1] == 0.0f);

CPPUNIT_ASSERT(m2[0][2] == 0.0f);
CPPUNIT_ASSERT(m2[1][2] == 0.0f);
CPPUNIT_ASSERT(m2[2][2] == 1.0f);
CPPUNIT_ASSERT(m2[3][2] == 0.0f);

CPPUNIT_ASSERT(m2[0][3] == 0.0f);
CPPUNIT_ASSERT(m2[1][3] == 0.0f);
CPPUNIT_ASSERT(m2[2][3] == 0.0f);
CPPUNIT_ASSERT(m2[3][3] == 1.0f);
}

void test_mat_inv()
{
float4x4 m0 = invertible;
float4x4 m1 = m0.invert();

float4x4 m2 = m0 * m1;

CPPUNIT_ASSERT(m2[0][0] == 1.0f);
CPPUNIT_ASSERT(m2[1][0] == 0.0f);
CPPUNIT_ASSERT(m2[2][0] == 0.0f);
CPPUNIT_ASSERT(m2[3][0] == 0.0f);

CPPUNIT_ASSERT(m2[0][1] == 0.0f);
CPPUNIT_ASSERT(m2[1][1] == 1.0f);
CPPUNIT_ASSERT(m2[2][1] == 0.0f);
CPPUNIT_ASSERT(m2[3][1] == 0.0f);

CPPUNIT_ASSERT(m2[0][2] == 0.0f);
CPPUNIT_ASSERT(m2[1][2] == 0.0f);
CPPUNIT_ASSERT(m2[2][2] == 1.0f);
CPPUNIT_ASSERT(m2[3][2] == 0.0f);

CPPUNIT_ASSERT(m2[0][3] == 0.0f);
CPPUNIT_ASSERT(m2[1][3] == 0.0f);
CPPUNIT_ASSERT(m2[2][3] == 0.0f);
CPPUNIT_ASSERT(m2[3][3] == 1.0f);
}

private:
float4x4 triangular, identity, invertible;
};

CPPUNIT_TEST_SUITE_REGISTRATION(MatrixTest);


+ 1
- 0
win32/deushax.vcxproj Переглянути файл

@@ -61,6 +61,7 @@
<ClCompile Include="..\src\input.cpp" />
<ClCompile Include="..\src\layer.cpp" />
<ClCompile Include="..\src\map.cpp" />
<ClCompile Include="..\src\matrix.cpp" />
<ClCompile Include="..\src\profiler.cpp" />
<ClCompile Include="..\src\sample.cpp" />
<ClCompile Include="..\src\sampler.cpp" />


+ 3
- 0
win32/deushax.vcxproj.filters Переглянути файл

@@ -136,6 +136,9 @@
<ClCompile Include="..\src\map.cpp">
<Filter>lolengine</Filter>
</ClCompile>
<ClCompile Include="..\src\matrix.cpp">
<Filter>lolengine</Filter>
</ClCompile>
<ClCompile Include="..\src\profiler.cpp">
<Filter>lolengine</Filter>
</ClCompile>


+ 1
- 0
win32/editor.vcxproj Переглянути файл

@@ -61,6 +61,7 @@
<ClCompile Include="..\src\input.cpp" />
<ClCompile Include="..\src\layer.cpp" />
<ClCompile Include="..\src\map.cpp" />
<ClCompile Include="..\src\matrix.cpp" />
<ClCompile Include="..\src\profiler.cpp" />
<ClCompile Include="..\src\sample.cpp" />
<ClCompile Include="..\src\sampler.cpp" />


+ 4
- 1
win32/editor.vcxproj.filters Переглянути файл

@@ -136,6 +136,9 @@
<ClCompile Include="..\src\map.cpp">
<Filter>lolengine</Filter>
</ClCompile>
<ClCompile Include="..\src\matrix.cpp">
<Filter>lolengine</Filter>
</ClCompile>
<ClCompile Include="..\src\profiler.cpp">
<Filter>lolengine</Filter>
</ClCompile>
@@ -182,4 +185,4 @@
<ClCompile Include="..\deushax\gtk\glmapview.cpp" />
<ClCompile Include="..\deushax\mapviewer.cpp" />
</ItemGroup>
</Project>
</Project>

+ 1
- 0
win32/monsterz.vcxproj Переглянути файл

@@ -70,6 +70,7 @@
<ClCompile Include="..\src\input.cpp" />
<ClCompile Include="..\src\layer.cpp" />
<ClCompile Include="..\src\map.cpp" />
<ClCompile Include="..\src\matrix.cpp" />
<ClCompile Include="..\src\profiler.cpp" />
<ClCompile Include="..\src\sample.cpp" />
<ClCompile Include="..\src\sampler.cpp" />


+ 3
- 0
win32/monsterz.vcxproj.filters Переглянути файл

@@ -141,6 +141,9 @@
<ClCompile Include="..\src\map.cpp">
<Filter>lolengine</Filter>
</ClCompile>
<ClCompile Include="..\src\matrix.cpp">
<Filter>lolengine</Filter>
</ClCompile>
<ClCompile Include="..\src\profiler.cpp">
<Filter>lolengine</Filter>
</ClCompile>


Завантаження…
Відмінити
Зберегти