fixes fixpt rendering, make things refs as much as possible
This commit is contained in:
parent
a38f1eeddd
commit
ce51f737b5
|
@ -11,8 +11,6 @@ const unsigned short pal[4] __attribute__((aligned(4))) = {
|
||||||
0x0000, 0xFFFF, 0x3AE2
|
0x0000, 0xFFFF, 0x3AE2
|
||||||
};
|
};
|
||||||
|
|
||||||
const FIXED pointZeroOne = float2fx(0.01);
|
|
||||||
|
|
||||||
std::vector<Mesh*> WireScene::meshes() {
|
std::vector<Mesh*> WireScene::meshes() {
|
||||||
return { cube.get() };
|
return { cube.get() };
|
||||||
}
|
}
|
||||||
|
@ -26,16 +24,31 @@ void WireScene::load() {
|
||||||
backgroundPalette = std::unique_ptr<BackgroundPaletteManager>(new BackgroundPaletteManager(pal, sizeof(pal)));
|
backgroundPalette = std::unique_ptr<BackgroundPaletteManager>(new BackgroundPaletteManager(pal, sizeof(pal)));
|
||||||
|
|
||||||
cube = std::unique_ptr<Mesh>(new Mesh());
|
cube = std::unique_ptr<Mesh>(new Mesh());
|
||||||
cube->add(VectorFx(-1, 1, 1));
|
cube->add(VectorFx::fromInt(-1, 1, 1));
|
||||||
cube->add(VectorFx(1, 1, 1));
|
cube->add(VectorFx::fromInt(1, 1, 1));
|
||||||
cube->add(VectorFx(-1, -1, 1));
|
cube->add(VectorFx::fromInt(-1, -1, 1));
|
||||||
cube->add(VectorFx(-1, -1, -1));
|
cube->add(VectorFx::fromInt(-1, -1, -1));
|
||||||
cube->add(VectorFx(-1, 1, -1));
|
cube->add(VectorFx::fromInt(-1, 1, -1));
|
||||||
cube->add(VectorFx(1, 1, -1));
|
cube->add(VectorFx::fromInt(1, 1, -1));
|
||||||
cube->add(VectorFx(1, -1, 1));
|
cube->add(VectorFx::fromInt(1, -1, 1));
|
||||||
cube->add(VectorFx(-1, -1, -1));
|
cube->add(VectorFx::fromInt(1, -1, -1));
|
||||||
|
/*
|
||||||
|
* should be translated, with camera 0,0,10, and with GBA dimensions, to:
|
||||||
|
SoftEngine.js:50 drawing 163,123
|
||||||
|
SoftEngine.js:50 drawing 155,115
|
||||||
|
SoftEngine.js:50 drawing 155,44
|
||||||
|
SoftEngine.js:50 drawing 84,44
|
||||||
|
SoftEngine.js:50 drawing 76,123
|
||||||
|
SoftEngine.js:50 drawing 84,115
|
||||||
|
SoftEngine.js:50 drawing 163,36
|
||||||
|
SoftEngine.js:50 drawing 76,36
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void WireScene::tick(u16 keys) {
|
void WireScene::tick(u16 keys) {
|
||||||
cube->rotate(pointZeroOne, pointZeroOne);
|
if(keys & KEY_START || keys & KEY_A) {
|
||||||
|
cube->rotate(5, 5);
|
||||||
|
} else if(keys & KEY_B) {
|
||||||
|
cube->resetRotation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ private:
|
||||||
Scene* sceneToTransitionTo;
|
Scene* sceneToTransitionTo;
|
||||||
|
|
||||||
u16* vid_page;
|
u16* vid_page;
|
||||||
|
MatrixFx projectionMatrix;
|
||||||
|
|
||||||
static std::unique_ptr<Timer> timer;
|
static std::unique_ptr<Timer> timer;
|
||||||
static std::unique_ptr<SoundControl> activeChannelA;
|
static std::unique_ptr<SoundControl> activeChannelA;
|
||||||
|
@ -50,7 +51,7 @@ private:
|
||||||
void render();
|
void render();
|
||||||
void renderClear();
|
void renderClear();
|
||||||
inline void plotPixel(int x, int y, u8 clrId);
|
inline void plotPixel(int x, int y, u8 clrId);
|
||||||
inline VectorFx project(VectorFx coord, MatrixFx transMat);
|
inline VectorFx project(const VectorFx &coord, const MatrixFx &transMat);
|
||||||
void flipPage();
|
void flipPage();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
extern FIXED HALF;
|
extern FIXED HALF;
|
||||||
extern FIXED ONE;
|
extern FIXED ONE;
|
||||||
|
extern FIXED TWO;
|
||||||
|
|
||||||
#define FIX12_SHIFT 12
|
#define FIX12_SHIFT 12
|
||||||
#define FIX12_SCALE ( 1<<FIX12_SHIFT )
|
#define FIX12_SCALE ( 1<<FIX12_SHIFT )
|
||||||
|
@ -69,18 +70,21 @@ INLINE FIXED fx12Tofx8(FIXED fx12) {
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE FIXED fxsin(FIXED fxrad) {
|
INLINE FIXED fxsin(FIXED fxrad) {
|
||||||
|
if(fxrad == 0) return 0;
|
||||||
FIXED theta = fxrad2lut(fxrad);
|
FIXED theta = fxrad2lut(fxrad);
|
||||||
FIXED sin = lu_sin(theta);
|
FIXED sin = lu_sin(theta);
|
||||||
return fx12Tofx8(sin);
|
return fx12Tofx8(sin);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE FIXED fxcos(FIXED fxrad) {
|
INLINE FIXED fxcos(FIXED fxrad) {
|
||||||
|
if(fxrad == 0) return ONE;
|
||||||
FIXED theta = fxrad2lut(fxrad);
|
FIXED theta = fxrad2lut(fxrad);
|
||||||
FIXED cos = lu_cos(theta);
|
FIXED cos = lu_cos(theta);
|
||||||
return fx12Tofx8(cos);
|
return fx12Tofx8(cos);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE FIXED fxtan(FIXED fxrad) {
|
INLINE FIXED fxtan(FIXED fxrad) {
|
||||||
|
if(fxrad == 0) return 0;
|
||||||
FIXED theta = fxrad2lut(fxrad);
|
FIXED theta = fxrad2lut(fxrad);
|
||||||
FIXED sin = lu_sin(theta);
|
FIXED sin = lu_sin(theta);
|
||||||
FIXED cos = lu_cos(theta);
|
FIXED cos = lu_cos(theta);
|
||||||
|
|
|
@ -97,7 +97,7 @@ public:
|
||||||
m[15] = m44;
|
m[15] = m44;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static VectorFx transformCoordinates(VectorFx vector, MatrixFx transformation) {
|
inline static VectorFx transformCoordinates(const VectorFx &vector, const MatrixFx &transformation) {
|
||||||
FIXED x = fxmul(vector.x(), transformation.mAt(0)) + fxmul(vector.y(), transformation.mAt(4)) + fxmul(vector.z(), transformation.mAt(8) + transformation.mAt(12));
|
FIXED x = fxmul(vector.x(), transformation.mAt(0)) + fxmul(vector.y(), transformation.mAt(4)) + fxmul(vector.z(), transformation.mAt(8) + transformation.mAt(12));
|
||||||
FIXED y = fxmul(vector.x(), transformation.mAt(1)) + fxmul(vector.y(), transformation.mAt(5)) + fxmul(vector.z(), transformation.mAt(9) + transformation.mAt(13));
|
FIXED y = fxmul(vector.x(), transformation.mAt(1)) + fxmul(vector.y(), transformation.mAt(5)) + fxmul(vector.z(), transformation.mAt(9) + transformation.mAt(13));
|
||||||
FIXED z = fxmul(vector.x(), transformation.mAt(2)) + fxmul(vector.y(), transformation.mAt(6)) + fxmul(vector.z(), transformation.mAt(10) + transformation.mAt(14));
|
FIXED z = fxmul(vector.x(), transformation.mAt(2)) + fxmul(vector.y(), transformation.mAt(6)) + fxmul(vector.z(), transformation.mAt(10) + transformation.mAt(14));
|
||||||
|
@ -126,7 +126,7 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static MatrixFx lookAtLH(VectorFx eye, VectorFx target, VectorFx up) {
|
inline static MatrixFx lookAtLH(const VectorFx &eye, const VectorFx &target, const VectorFx &up) {
|
||||||
auto zAxis = target - eye;
|
auto zAxis = target - eye;
|
||||||
zAxis.normalize();
|
zAxis.normalize();
|
||||||
auto xAxis = VectorFx::cross(up, zAxis);
|
auto xAxis = VectorFx::cross(up, zAxis);
|
||||||
|
@ -144,8 +144,8 @@ public:
|
||||||
auto result = MatrixFx::zero();
|
auto result = MatrixFx::zero();
|
||||||
auto s = fxsin(angle);
|
auto s = fxsin(angle);
|
||||||
auto c = fxcos(angle);
|
auto c = fxcos(angle);
|
||||||
result.m[0] = 1.0;
|
result.m[0] = ONE;
|
||||||
result.m[15] = 1.0;
|
result.m[15] = ONE;
|
||||||
result.m[5] = c;
|
result.m[5] = c;
|
||||||
result.m[10] = c;
|
result.m[10] = c;
|
||||||
result.m[9] = -s;
|
result.m[9] = -s;
|
||||||
|
@ -157,8 +157,8 @@ public:
|
||||||
auto result = MatrixFx::zero();
|
auto result = MatrixFx::zero();
|
||||||
auto s = fxsin(angle);
|
auto s = fxsin(angle);
|
||||||
auto c = fxcos(angle);
|
auto c = fxcos(angle);
|
||||||
result.m[5] = 1.0;
|
result.m[5] = ONE;
|
||||||
result.m[15] = 1.0;
|
result.m[15] = ONE;
|
||||||
result.m[0] = c;
|
result.m[0] = c;
|
||||||
result.m[2] = -s;
|
result.m[2] = -s;
|
||||||
result.m[8] = s;
|
result.m[8] = s;
|
||||||
|
@ -170,8 +170,8 @@ public:
|
||||||
auto result = MatrixFx::zero();
|
auto result = MatrixFx::zero();
|
||||||
auto s = fxsin(angle);
|
auto s = fxsin(angle);
|
||||||
auto c = fxcos(angle);
|
auto c = fxcos(angle);
|
||||||
result.m[10] = 1.0;
|
result.m[10] = ONE;
|
||||||
result.m[15] = 1.0;
|
result.m[15] = ONE;
|
||||||
result.m[0] = c;
|
result.m[0] = c;
|
||||||
result.m[1] = s;
|
result.m[1] = s;
|
||||||
result.m[4] = -s;
|
result.m[4] = -s;
|
||||||
|
@ -179,7 +179,7 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static MatrixFx translation(VectorFx vec) {
|
inline static MatrixFx translation(const VectorFx &vec) {
|
||||||
auto result = MatrixFx::identity();
|
auto result = MatrixFx::identity();
|
||||||
result.m[12] = vec.x();
|
result.m[12] = vec.x();
|
||||||
result.m[13] = vec.y();
|
result.m[13] = vec.y();
|
||||||
|
|
|
@ -26,12 +26,17 @@ public:
|
||||||
inline FIXED rotx() { return rot.x(); }
|
inline FIXED rotx() { return rot.x(); }
|
||||||
inline FIXED roty() { return rot.y(); }
|
inline FIXED roty() { return rot.y(); }
|
||||||
inline FIXED rotz() { return rot.z(); }
|
inline FIXED rotz() { return rot.z(); }
|
||||||
|
|
||||||
|
inline void resetRotation() {
|
||||||
|
rot.setX(0);
|
||||||
|
rot.setY(0);
|
||||||
|
}
|
||||||
inline void rotate(FIXED x, FIXED y) {
|
inline void rotate(FIXED x, FIXED y) {
|
||||||
rot.setX(rot.x() + x);
|
rot.setX(rot.x() + x);
|
||||||
rot.setY(rot.y() + y);
|
rot.setY(rot.y() + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Mesh() {}
|
explicit Mesh() : pos(VectorFx()), rot(VectorFx()) {}
|
||||||
Mesh(const Mesh&) = delete;
|
Mesh(const Mesh&) = delete;
|
||||||
Mesh& operator=(const Mesh&) = delete;
|
Mesh& operator=(const Mesh&) = delete;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::deque<VECTOR> bresenhamLineTo(VECTOR dest);
|
std::deque<VECTOR> bresenhamLineTo(VECTOR dest);
|
||||||
VectorFx rotateAsCenter(VectorFx point, FIXED angle);
|
|
||||||
|
|
||||||
// WHY all these inlines? performance reasons.
|
// WHY all these inlines? performance reasons.
|
||||||
inline static VectorFx up() { return VectorFx::fromInt(0, 1, 0); }
|
inline static VectorFx up() { return VectorFx::fromInt(0, 1, 0); }
|
||||||
|
|
|
@ -118,6 +118,7 @@ GBAEngine::GBAEngine() {
|
||||||
|
|
||||||
REG_SNDDSCNT = 0;
|
REG_SNDDSCNT = 0;
|
||||||
vid_page = vid_mem_back;
|
vid_page = vid_mem_back;
|
||||||
|
projectionMatrix = MatrixFx::perspectiveFovLH(float2fx(0.78), fxdiv(GBA_SCREEN_WIDTH_FX, GBA_SCREEN_HEIGHT_FX), float2fx(0.01), ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAEngine::update() {
|
void GBAEngine::update() {
|
||||||
|
@ -152,22 +153,19 @@ inline void GBAEngine::plotPixel(int x, int y, u8 clrId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VectorFx GBAEngine::project(VectorFx coord, MatrixFx transMat) {
|
inline VectorFx GBAEngine::project(const VectorFx &coord, const MatrixFx &transMat) {
|
||||||
auto point = MatrixFx::transformCoordinates(coord, transMat);
|
auto point = MatrixFx::transformCoordinates(coord, transMat);
|
||||||
|
|
||||||
auto x = fxmul(point.x(), GBA_SCREEN_WIDTH_FX) + fxdiv(GBA_SCREEN_WIDTH_FX, 2.0);
|
auto x = fxmul(point.x(), GBA_SCREEN_WIDTH_FX) + fxdiv(GBA_SCREEN_WIDTH_FX, TWO);
|
||||||
auto y = fxmul(-point.y(), GBA_SCREEN_HEIGHT_FX) + fxdiv(GBA_SCREEN_HEIGHT_FX, 2.0);
|
auto y = fxmul(-point.y(), GBA_SCREEN_HEIGHT_FX) + fxdiv(GBA_SCREEN_HEIGHT_FX, TWO);
|
||||||
return VectorFx(x, y, 0);
|
return VectorFx(x, y, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// does the mesh rendering - to write mem before flipping
|
// does the mesh rendering - to write mem before flipping
|
||||||
void GBAEngine::render() {
|
void GBAEngine::render() {
|
||||||
auto viewMatrix = MatrixFx::lookAtLH(currentCamera.getPosition(), currentCamera.getTarget(), VectorFx::up());
|
auto viewMatrix = MatrixFx::lookAtLH(currentCamera.getPosition(), currentCamera.getTarget(), VectorFx::up());
|
||||||
// TODO float fxes and other stuff out of render loop?
|
|
||||||
auto projectionMatrix = MatrixFx::perspectiveFovLH(float2fx(0.78), fxdiv(GBA_SCREEN_WIDTH_FX, GBA_SCREEN_HEIGHT_FX), float2fx(0.01), ONE);
|
|
||||||
|
|
||||||
for(auto& mesh :currentScene->meshes()) {
|
for(auto& mesh :currentScene->meshes()) {
|
||||||
|
|
||||||
auto worldMatrix = MatrixFx::rotationYawPitchRoll(mesh->roty(), mesh->rotx(), mesh->rotz()) * MatrixFx::translation(mesh->position());
|
auto worldMatrix = MatrixFx::rotationYawPitchRoll(mesh->roty(), mesh->rotx(), mesh->rotz()) * MatrixFx::translation(mesh->position());
|
||||||
auto transformMatrix = worldMatrix * viewMatrix * projectionMatrix;
|
auto transformMatrix = worldMatrix * viewMatrix * projectionMatrix;
|
||||||
|
|
||||||
|
@ -176,6 +174,17 @@ void GBAEngine::render() {
|
||||||
plotPixel(projectedPoint.x(), projectedPoint.y(), 1);
|
plotPixel(projectedPoint.x(), projectedPoint.y(), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
plotPixel(150, 40, 1);
|
||||||
|
plotPixel(60, 40, 1);
|
||||||
|
plotPixel(150, 140, 1);
|
||||||
|
plotPixel(93, 26, 1);
|
||||||
|
plotPixel(93, 115, 1);
|
||||||
|
plotPixel(172, 115, 1);
|
||||||
|
plotPixel(60, 140, 1);
|
||||||
|
plotPixel(93, 26, 1);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAEngine::renderClear() {
|
void GBAEngine::renderClear() {
|
||||||
|
|
|
@ -6,3 +6,4 @@
|
||||||
|
|
||||||
FIXED HALF = float2fx(0.5);
|
FIXED HALF = float2fx(0.5);
|
||||||
FIXED ONE = int2fx(1);
|
FIXED ONE = int2fx(1);
|
||||||
|
FIXED TWO = int2fx(2);
|
||||||
|
|
|
@ -4,26 +4,6 @@
|
||||||
|
|
||||||
#include <libgba-sprite-engine/vectorfx.h>
|
#include <libgba-sprite-engine/vectorfx.h>
|
||||||
|
|
||||||
VectorFx VectorFx::rotateAsCenter(VectorFx point, FIXED angle) {
|
|
||||||
auto center = this->v;
|
|
||||||
s32 centerx = center.x, centery = center.y;
|
|
||||||
s32 defaultx = point.x(), defaulty = point.y();
|
|
||||||
|
|
||||||
s32 cos = lu_cos(angle) >> 4;
|
|
||||||
s32 sin = lu_sin(angle) >> 4;
|
|
||||||
|
|
||||||
// affine matriches are 8.8 fixed point numbers, so shift all input 8 spaces up and forth
|
|
||||||
// possibilities: instead of between [-1.0, 1.0] it's between [-256, +256]
|
|
||||||
// 90° rotation in inversed y-axis needs to flip sin sign
|
|
||||||
/*
|
|
||||||
return VectorFx({
|
|
||||||
( cos * (defaultx - centerx) + sin * (defaulty - centery) + (centerx << 8)) >> 8,
|
|
||||||
(-sin * (defaultx - centerx) + cos * (defaulty - centery) + (centery << 8)) >> 8});
|
|
||||||
*/
|
|
||||||
return VectorFx({
|
|
||||||
(fxmul(cos, (defaultx - centerx)) + fxmul(sin, (defaulty - centery)) + (centerx << 8)) >> 8,
|
|
||||||
(fxmul(-sin, (defaultx - centerx)) + fxmul(cos, (defaulty - centery) + (centery << 8))) >> 8});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::deque<VECTOR> VectorFx::bresenhamLineTo(VECTOR dest) {
|
std::deque<VECTOR> VectorFx::bresenhamLineTo(VECTOR dest) {
|
||||||
// https://www.coranac.com/tonc/text/bitmaps.htm - Bresenham's line algorithm with fixed points
|
// https://www.coranac.com/tonc/text/bitmaps.htm - Bresenham's line algorithm with fixed points
|
||||||
|
|
|
@ -19,6 +19,9 @@ SET(CMAKE_ASM_COMPILER gcc)
|
||||||
SET(CMAKE_C_COMPILER gcc)
|
SET(CMAKE_C_COMPILER gcc)
|
||||||
SET(CMAKE_CXX_COMPILER g++)
|
SET(CMAKE_CXX_COMPILER g++)
|
||||||
|
|
||||||
|
# remove -03 optimization flag otherwise debugging will be annoying as hell
|
||||||
|
SET(CMAKE_CXX_FLAGS "-Wno-narrowing")
|
||||||
|
|
||||||
add_definitions(-DCODE_COMPILED_AS_PART_OF_TEST)
|
add_definitions(-DCODE_COMPILED_AS_PART_OF_TEST)
|
||||||
|
|
||||||
include_directories(${GTEST_LIBRARY}/include)
|
include_directories(${GTEST_LIBRARY}/include)
|
||||||
|
@ -34,6 +37,7 @@ add_executable(unittest
|
||||||
../engine/src/palette/combined_palette.cpp
|
../engine/src/palette/combined_palette.cpp
|
||||||
../engine/src/timer.cpp
|
../engine/src/timer.cpp
|
||||||
../engine/src/math.cpp
|
../engine/src/math.cpp
|
||||||
|
../engine/src/mesh.cpp
|
||||||
../engine/src/vectorfx.cpp
|
../engine/src/vectorfx.cpp
|
||||||
timertest.cpp vectorfxtest.cpp matrixfxtest.cpp fixedpoinmathtest.cpp)
|
timertest.cpp vectorfxtest.cpp matrixfxtest.cpp fixedpoinmathtest.cpp)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <libgba-sprite-engine/matrixfx.h>
|
#include <libgba-sprite-engine/matrixfx.h>
|
||||||
#include <libgba-sprite-engine/math.h>
|
#include <libgba-sprite-engine/math.h>
|
||||||
|
#include <libgba-sprite-engine/mesh.h>
|
||||||
|
#include <libgba-sprite-engine/camera.h>
|
||||||
|
#include <libgba-sprite-engine/gba_engine.h>
|
||||||
|
|
||||||
class MatrixFxSuite : public ::testing::Test {
|
class MatrixFxSuite : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
|
@ -21,7 +24,7 @@ INLINE float rnd2(float val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void assertMatrix(MatrixFx expected, MatrixFx actual) {
|
void assertMatrix(MatrixFx expected, MatrixFx actual, std::string matrixName) {
|
||||||
for(int i = 0; i < MATRIX_DIMENSION; i++) {
|
for(int i = 0; i < MATRIX_DIMENSION; i++) {
|
||||||
auto expect = expected.mAt(i);
|
auto expect = expected.mAt(i);
|
||||||
auto act = actual.mAt(i);
|
auto act = actual.mAt(i);
|
||||||
|
@ -30,7 +33,82 @@ void assertMatrix(MatrixFx expected, MatrixFx actual) {
|
||||||
float expectFl = rnd2(fx2float(expect));
|
float expectFl = rnd2(fx2float(expect));
|
||||||
float actFl = rnd2(fx2float(act));
|
float actFl = rnd2(fx2float(act));
|
||||||
|
|
||||||
ASSERT_EQ(expectFl, actFl) << "M[" << i << "] does not match: (exp, act) " << expect << ", " << act << " - floats: " << expectFl << ", " << actFl;
|
ASSERT_EQ(expectFl, actFl) << matrixName << "[" << i << "] does not match: (exp, act) " << expect << ", " << act << " - floats: " << expectFl << ", " << actFl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MatrixFxSuite, RotationMatriches) {
|
||||||
|
auto result = MatrixFx::rotationZ(0);
|
||||||
|
auto expectedIdMatrix = MatrixFx(float2fx(1.0), 0, 0, 0, 0, float2fx(1.0), 0, 0, 0, 0, float2fx(1.0), 0, 0, 0, 0, float2fx(1.0));
|
||||||
|
assertMatrix(expectedIdMatrix, result, "rotz");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MatrixFxSuite, RotationYawPitchRoll) {
|
||||||
|
auto expectedIdMatrix = MatrixFx(float2fx(1.0), 0, 0, 0, 0, float2fx(1.0), 0, 0, 0, 0, float2fx(1.0), 0, 0, 0, 0, float2fx(1.0));
|
||||||
|
auto rotYwaPitchRoll = MatrixFx::rotationYawPitchRoll(0, 0, 0);
|
||||||
|
assertMatrix(expectedIdMatrix, rotYwaPitchRoll, "rotywa");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MatrixFxSuite, MeshToTransformMatrix_IntegrationTest) {
|
||||||
|
// source:
|
||||||
|
Mesh cube;
|
||||||
|
cube.add(VectorFx(-1, 1, 1));
|
||||||
|
cube.add(VectorFx(1, 1, 1));
|
||||||
|
cube.add(VectorFx(-1, -1, 1));
|
||||||
|
cube.add(VectorFx(-1, -1, -1));
|
||||||
|
cube.add(VectorFx(-1, 1, -1));
|
||||||
|
cube.add(VectorFx(1, 1, -1));
|
||||||
|
cube.add(VectorFx(1, -1, 1));
|
||||||
|
cube.add(VectorFx(-1, -1, -1));
|
||||||
|
|
||||||
|
auto currentCamera = Camera(VectorFx::fromInt(0, 0, 10), VectorFx::fromInt(0, 0, 0));
|
||||||
|
auto viewMatrix = MatrixFx::lookAtLH(currentCamera.getPosition(), currentCamera.getTarget(), VectorFx::up());
|
||||||
|
|
||||||
|
auto projectionMatrix = MatrixFx::perspectiveFovLH(float2fx(0.78), fxdiv(GBA_SCREEN_WIDTH_FX, GBA_SCREEN_HEIGHT_FX), float2fx(0.01), ONE);
|
||||||
|
auto expectedProjectionMatrix = MatrixFx(float2fx(1.64f), 0, 0, 0, 0, float2fx(2.55f), 0, 0, 0, 0, float2fx(1.05), float2fx(1.05), 0, 0, float2fx(-0.05), 0);
|
||||||
|
assertMatrix(expectedProjectionMatrix, projectionMatrix, "project");
|
||||||
|
|
||||||
|
auto expectedIdMatrix = MatrixFx(float2fx(1.0), 0, 0, 0, 0, float2fx(1.0), 0, 0, 0, 0, float2fx(1.0), 0, 0, 0, 0, float2fx(1.0));
|
||||||
|
auto rotYwaPitchRoll = MatrixFx::rotationYawPitchRoll(cube.roty(), cube.rotx(), cube.rotz());
|
||||||
|
assertMatrix(expectedIdMatrix, rotYwaPitchRoll, "rotywa");
|
||||||
|
auto translatedPos = MatrixFx::translation(cube.position());
|
||||||
|
assertMatrix(expectedIdMatrix, translatedPos, "translpos");
|
||||||
|
|
||||||
|
auto worldMatrix = rotYwaPitchRoll * translatedPos;
|
||||||
|
assertMatrix(expectedIdMatrix, worldMatrix, "worldmatrix");
|
||||||
|
|
||||||
|
auto transformMatrix = worldMatrix * viewMatrix * projectionMatrix;
|
||||||
|
auto expectedTransformMatrix = MatrixFx(float2fx(-1.67), 0, 0, 0, 0, float2fx(2.55), 0, 0, 0, 0, float2fx(-1.0), float2fx(-1.0), 0, 0, float2fx(9.85), float2fx(9.75));
|
||||||
|
assertMatrix(expectedTransformMatrix, transformMatrix, "transfomatrix");
|
||||||
|
|
||||||
|
auto coord = *cube.vertices()[0].get();
|
||||||
|
auto point = MatrixFx::transformCoordinates(coord, transformMatrix);
|
||||||
|
ASSERT_EQ(fx2float(point.x()), 0.125f);
|
||||||
|
ASSERT_EQ(fx2float(point.y()), 0.25f);
|
||||||
|
ASSERT_EQ(fx2float(point.z()), 1.00f);
|
||||||
|
|
||||||
|
auto x = fxmul(point.x(), GBA_SCREEN_WIDTH_FX) + fxdiv(GBA_SCREEN_WIDTH_FX, int2fx(2));
|
||||||
|
auto y = fxmul(-point.y(), GBA_SCREEN_HEIGHT_FX) + fxdiv(GBA_SCREEN_HEIGHT_FX, int2fx(2));
|
||||||
|
ASSERT_EQ(fx2float(x), 150);
|
||||||
|
ASSERT_EQ(fx2float(y), 40);
|
||||||
|
|
||||||
|
// dest in Babylon - dest according to for loop below (should print something roughly similar)
|
||||||
|
/*
|
||||||
|
* 163, 36 - 150,40
|
||||||
|
* 76, 36 - 60,40
|
||||||
|
* 163, 123 - 150,140
|
||||||
|
* 155, 115 - 93,26
|
||||||
|
* 155, 44 - 93,115
|
||||||
|
* 84, 44 - 172,115
|
||||||
|
* 76, 123 - 60,140
|
||||||
|
* 84, 115 - 93,26
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
for(auto& vertex : cube.vertices()) {
|
||||||
|
auto point = MatrixFx::transformCoordinates(*vertex.get(), transformMatrix);
|
||||||
|
auto x = fxmul(point.x(), GBA_SCREEN_WIDTH_FX) + fxdiv(GBA_SCREEN_WIDTH_FX, int2fx(2));
|
||||||
|
auto y = fxmul(-point.y(), GBA_SCREEN_HEIGHT_FX) + fxdiv(GBA_SCREEN_HEIGHT_FX, int2fx(2));
|
||||||
|
std::cout << "plotting (" << fx2int(x) << "," << fx2int(y) << ")" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +142,7 @@ TEST_F(MatrixFxSuite, lookAtLH_TestData) {
|
||||||
auto result = MatrixFx::lookAtLH(eye, target, up);
|
auto result = MatrixFx::lookAtLH(eye, target, up);
|
||||||
auto expected = MatrixFx(-257, 0, 0, 0, 0, 256, 0, 0, 0, 0, -250, 0, 0, 0, 2500, 256);
|
auto expected = MatrixFx(-257, 0, 0, 0, 0, 256, 0, 0, 0, 0, -250, 0, 0, 0, 2500, 256);
|
||||||
|
|
||||||
assertMatrix(expected, result);
|
assertMatrix(expected, result, "M");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,5 +170,5 @@ TEST_F(MatrixFxSuite, PerspectiveFovLH_TestData) {
|
||||||
auto result = MatrixFx::perspectiveFovLH(float2fx(0.78), float2fx(1.6), float2fx(0.01), float2fx(1));
|
auto result = MatrixFx::perspectiveFovLH(float2fx(0.78), float2fx(1.6), float2fx(0.01), float2fx(1));
|
||||||
auto expected = MatrixFx::fromFloat(1.565f, 0, 0, 0, 0, 2.505f, 0, 0, 0, 0, 1.005f, 1, 0, 0, -0.005f, 0);
|
auto expected = MatrixFx::fromFloat(1.565f, 0, 0, 0, 0, 2.505f, 0, 0, 0, 0, 1.005f, 1, 0, 0, -0.005f, 0);
|
||||||
|
|
||||||
assertMatrix(expected, result);
|
assertMatrix(expected, result, "M");
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,42 +144,6 @@ TEST_F(VectorFxSuite, ScaleAVector) {
|
||||||
ASSERT_EQ(result.z(), 6);
|
ASSERT_EQ(result.z(), 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint grad2rad(uint grad) {
|
|
||||||
//return float2fx(grad*M_PI/180);
|
|
||||||
return fxdiv(fxmul(int2fx(grad), float2fx(M_PI)), int2fx(180));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VectorFxSuite, Rotate_FromBottomHalf_0_Degrees) {
|
|
||||||
auto bottomHalf = VectorFx::fromInt(120, 200, 0);
|
|
||||||
auto vector = VectorFx::fromInt(120, 80, 0);
|
|
||||||
auto result = vector.rotateAsCenter(bottomHalf, grad2rad(0)).toInt();
|
|
||||||
ASSERT_EQ(120, result.x());
|
|
||||||
ASSERT_EQ(200, result.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VectorFxSuite, Rotate_FromBottomHalf_90_Degrees) {
|
|
||||||
auto bottomHalf = VectorFx::fromInt(120, 200, 0);
|
|
||||||
auto vector = VectorFx::fromInt(120, 80, 0);
|
|
||||||
auto result = vector.rotateAsCenter(bottomHalf, grad2rad(90)).toInt();
|
|
||||||
ASSERT_EQ(240, result.x());
|
|
||||||
ASSERT_EQ(80, result.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VectorFxSuite, Rotate_FromBottomHalf_180_Degrees) {
|
|
||||||
auto bottomHalf = VectorFx::fromInt(120, 200, 0);
|
|
||||||
auto vector = VectorFx::fromInt(120, 80, 0);
|
|
||||||
auto result = vector.rotateAsCenter(bottomHalf, grad2rad(180)).toInt();
|
|
||||||
ASSERT_EQ(120, result.x());
|
|
||||||
ASSERT_EQ(-40, result.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VectorFxSuite, Rotate_FromBottomHalf_270_Degrees) {
|
|
||||||
auto bottomHalf = VectorFx::fromInt(120, 200, 0);
|
|
||||||
auto vector = VectorFx::fromInt(120, 80, 0);
|
|
||||||
auto result = vector.rotateAsCenter(bottomHalf, grad2rad(270)).toInt();
|
|
||||||
ASSERT_EQ(0, result.x());
|
|
||||||
ASSERT_EQ(80, result.y());
|
|
||||||
}
|
|
||||||
// ---- //
|
// ---- //
|
||||||
|
|
||||||
TEST_F(VectorFxSuite, ToString) {
|
TEST_F(VectorFxSuite, ToString) {
|
||||||
|
|
Loading…
Reference in New Issue