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
|
||||
};
|
||||
|
||||
const FIXED pointZeroOne = float2fx(0.01);
|
||||
|
||||
std::vector<Mesh*> WireScene::meshes() {
|
||||
return { cube.get() };
|
||||
}
|
||||
|
@ -26,16 +24,31 @@ void WireScene::load() {
|
|||
backgroundPalette = std::unique_ptr<BackgroundPaletteManager>(new BackgroundPaletteManager(pal, sizeof(pal)));
|
||||
|
||||
cube = std::unique_ptr<Mesh>(new Mesh());
|
||||
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));
|
||||
cube->add(VectorFx::fromInt(-1, 1, 1));
|
||||
cube->add(VectorFx::fromInt(1, 1, 1));
|
||||
cube->add(VectorFx::fromInt(-1, -1, 1));
|
||||
cube->add(VectorFx::fromInt(-1, -1, -1));
|
||||
cube->add(VectorFx::fromInt(-1, 1, -1));
|
||||
cube->add(VectorFx::fromInt(1, 1, -1));
|
||||
cube->add(VectorFx::fromInt(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) {
|
||||
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;
|
||||
|
||||
u16* vid_page;
|
||||
MatrixFx projectionMatrix;
|
||||
|
||||
static std::unique_ptr<Timer> timer;
|
||||
static std::unique_ptr<SoundControl> activeChannelA;
|
||||
|
@ -50,7 +51,7 @@ private:
|
|||
void render();
|
||||
void renderClear();
|
||||
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();
|
||||
|
||||
public:
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
extern FIXED HALF;
|
||||
extern FIXED ONE;
|
||||
extern FIXED TWO;
|
||||
|
||||
#define FIX12_SHIFT 12
|
||||
#define FIX12_SCALE ( 1<<FIX12_SHIFT )
|
||||
|
@ -69,18 +70,21 @@ INLINE FIXED fx12Tofx8(FIXED fx12) {
|
|||
}
|
||||
|
||||
INLINE FIXED fxsin(FIXED fxrad) {
|
||||
if(fxrad == 0) return 0;
|
||||
FIXED theta = fxrad2lut(fxrad);
|
||||
FIXED sin = lu_sin(theta);
|
||||
return fx12Tofx8(sin);
|
||||
}
|
||||
|
||||
INLINE FIXED fxcos(FIXED fxrad) {
|
||||
if(fxrad == 0) return ONE;
|
||||
FIXED theta = fxrad2lut(fxrad);
|
||||
FIXED cos = lu_cos(theta);
|
||||
return fx12Tofx8(cos);
|
||||
}
|
||||
|
||||
INLINE FIXED fxtan(FIXED fxrad) {
|
||||
if(fxrad == 0) return 0;
|
||||
FIXED theta = fxrad2lut(fxrad);
|
||||
FIXED sin = lu_sin(theta);
|
||||
FIXED cos = lu_cos(theta);
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
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 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));
|
||||
|
@ -126,7 +126,7 @@ public:
|
|||
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;
|
||||
zAxis.normalize();
|
||||
auto xAxis = VectorFx::cross(up, zAxis);
|
||||
|
@ -144,8 +144,8 @@ public:
|
|||
auto result = MatrixFx::zero();
|
||||
auto s = fxsin(angle);
|
||||
auto c = fxcos(angle);
|
||||
result.m[0] = 1.0;
|
||||
result.m[15] = 1.0;
|
||||
result.m[0] = ONE;
|
||||
result.m[15] = ONE;
|
||||
result.m[5] = c;
|
||||
result.m[10] = c;
|
||||
result.m[9] = -s;
|
||||
|
@ -157,8 +157,8 @@ public:
|
|||
auto result = MatrixFx::zero();
|
||||
auto s = fxsin(angle);
|
||||
auto c = fxcos(angle);
|
||||
result.m[5] = 1.0;
|
||||
result.m[15] = 1.0;
|
||||
result.m[5] = ONE;
|
||||
result.m[15] = ONE;
|
||||
result.m[0] = c;
|
||||
result.m[2] = -s;
|
||||
result.m[8] = s;
|
||||
|
@ -170,8 +170,8 @@ public:
|
|||
auto result = MatrixFx::zero();
|
||||
auto s = fxsin(angle);
|
||||
auto c = fxcos(angle);
|
||||
result.m[10] = 1.0;
|
||||
result.m[15] = 1.0;
|
||||
result.m[10] = ONE;
|
||||
result.m[15] = ONE;
|
||||
result.m[0] = c;
|
||||
result.m[1] = s;
|
||||
result.m[4] = -s;
|
||||
|
@ -179,7 +179,7 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
inline static MatrixFx translation(VectorFx vec) {
|
||||
inline static MatrixFx translation(const VectorFx &vec) {
|
||||
auto result = MatrixFx::identity();
|
||||
result.m[12] = vec.x();
|
||||
result.m[13] = vec.y();
|
||||
|
|
|
@ -26,12 +26,17 @@ public:
|
|||
inline FIXED rotx() { return rot.x(); }
|
||||
inline FIXED roty() { return rot.y(); }
|
||||
inline FIXED rotz() { return rot.z(); }
|
||||
|
||||
inline void resetRotation() {
|
||||
rot.setX(0);
|
||||
rot.setY(0);
|
||||
}
|
||||
inline void rotate(FIXED x, FIXED y) {
|
||||
rot.setX(rot.x() + x);
|
||||
rot.setY(rot.y() + y);
|
||||
}
|
||||
|
||||
explicit Mesh() {}
|
||||
explicit Mesh() : pos(VectorFx()), rot(VectorFx()) {}
|
||||
Mesh(const Mesh&) = delete;
|
||||
Mesh& operator=(const Mesh&) = delete;
|
||||
};
|
||||
|
|
|
@ -36,7 +36,6 @@ public:
|
|||
}
|
||||
|
||||
std::deque<VECTOR> bresenhamLineTo(VECTOR dest);
|
||||
VectorFx rotateAsCenter(VectorFx point, FIXED angle);
|
||||
|
||||
// WHY all these inlines? performance reasons.
|
||||
inline static VectorFx up() { return VectorFx::fromInt(0, 1, 0); }
|
||||
|
|
|
@ -118,6 +118,7 @@ GBAEngine::GBAEngine() {
|
|||
|
||||
REG_SNDDSCNT = 0;
|
||||
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() {
|
||||
|
@ -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 x = fxmul(point.x(), GBA_SCREEN_WIDTH_FX) + fxdiv(GBA_SCREEN_WIDTH_FX, 2.0);
|
||||
auto y = fxmul(-point.y(), GBA_SCREEN_HEIGHT_FX) + fxdiv(GBA_SCREEN_HEIGHT_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, TWO);
|
||||
return VectorFx(x, y, 0);
|
||||
}
|
||||
|
||||
// does the mesh rendering - to write mem before flipping
|
||||
void GBAEngine::render() {
|
||||
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()) {
|
||||
|
||||
auto worldMatrix = MatrixFx::rotationYawPitchRoll(mesh->roty(), mesh->rotx(), mesh->rotz()) * MatrixFx::translation(mesh->position());
|
||||
auto transformMatrix = worldMatrix * viewMatrix * projectionMatrix;
|
||||
|
||||
|
@ -176,6 +174,17 @@ void GBAEngine::render() {
|
|||
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() {
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
|
||||
FIXED HALF = float2fx(0.5);
|
||||
FIXED ONE = int2fx(1);
|
||||
FIXED TWO = int2fx(2);
|
||||
|
|
|
@ -4,26 +4,6 @@
|
|||
|
||||
#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) {
|
||||
// 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_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)
|
||||
|
||||
include_directories(${GTEST_LIBRARY}/include)
|
||||
|
@ -34,6 +37,7 @@ add_executable(unittest
|
|||
../engine/src/palette/combined_palette.cpp
|
||||
../engine/src/timer.cpp
|
||||
../engine/src/math.cpp
|
||||
../engine/src/mesh.cpp
|
||||
../engine/src/vectorfx.cpp
|
||||
timertest.cpp vectorfxtest.cpp matrixfxtest.cpp fixedpoinmathtest.cpp)
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#include <math.h>
|
||||
#include <libgba-sprite-engine/matrixfx.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 {
|
||||
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++) {
|
||||
auto expect = expected.mAt(i);
|
||||
auto act = actual.mAt(i);
|
||||
|
@ -30,7 +33,82 @@ void assertMatrix(MatrixFx expected, MatrixFx actual) {
|
|||
float expectFl = rnd2(fx2float(expect));
|
||||
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 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 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue