PerspectiveFovLH with fx2lut impl
This commit is contained in:
parent
aedb3cdfcb
commit
c6374b6e59
|
@ -9,6 +9,7 @@ add_library(${PROJECT_NAME}
|
|||
src/gba/sin_lut.s
|
||||
src/gba/tonc_bios.s
|
||||
src/gba_engine.cpp
|
||||
src/math.cpp
|
||||
src/sound_control.cpp src/scene.cpp src/timer.cpp src/gbavector.cpp src/mesh.cpp)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define GBA_BITMAP_ENGINE_PROJECT_GBAMATRIX_H
|
||||
|
||||
#define MATRIX_DIMENSION 16
|
||||
#include <libgba-sprite-engine/math.h>
|
||||
|
||||
#ifdef CODE_COMPILED_AS_PART_OF_TEST
|
||||
#include <libgba-sprite-engine/gba/tonc_math_stub.h>
|
||||
|
@ -13,20 +14,11 @@
|
|||
#include <libgba-sprite-engine/gba/tonc_math.h>
|
||||
#endif
|
||||
|
||||
FIXED HALF = float2fx(0.5);
|
||||
FIXED ONE = int2fx(1);
|
||||
|
||||
class GBAMatrix {
|
||||
private:
|
||||
FIXED m[MATRIX_DIMENSION];
|
||||
|
||||
public:
|
||||
inline static FIXED tan(FIXED angle) {
|
||||
FIXED sin = lu_sin(angle) >> 4;
|
||||
FIXED cos = lu_cos(angle) >> 4;
|
||||
|
||||
return fxdiv(sin, cos);
|
||||
}
|
||||
|
||||
inline static GBAMatrix zero() { return GBAMatrix(); }
|
||||
inline FIXED mAt(int index) const {
|
||||
|
@ -57,7 +49,7 @@ public:
|
|||
|
||||
inline static GBAMatrix perspectiveFovLH(FIXED fov, FIXED aspect, FIXED znear, FIXED zfar) {
|
||||
auto matrix = GBAMatrix::zero();
|
||||
FIXED tanResult = fxdiv(ONE, tan(fxmul(fov, HALF)));
|
||||
FIXED tanResult = fxdiv(ONE, fxtan(fxmul(fov, HALF)));
|
||||
matrix.m[0] = fxdiv(tanResult, aspect);
|
||||
matrix.m[1] = matrix.m[2] = matrix.m[3] = 0;
|
||||
matrix.m[5] = tanResult;
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// Created by Wouter Groeneveld on 08/07/20.
|
||||
//
|
||||
|
||||
#ifndef GBA_BITMAP_ENGINE_PROJECT_MATH_H
|
||||
#define GBA_BITMAP_ENGINE_PROJECT_MATH_H
|
||||
|
||||
#include <libgba-sprite-engine/gba/tonc_types.h>
|
||||
#ifdef CODE_COMPILED_AS_PART_OF_TEST
|
||||
#include <libgba-sprite-engine/gba/tonc_math_stub.h>
|
||||
#else
|
||||
#include <libgba-sprite-engine/gba/tonc_math.h>
|
||||
#endif
|
||||
|
||||
// fixed point math things that were missing from TONC
|
||||
|
||||
extern FIXED HALF;
|
||||
extern FIXED ONE;
|
||||
|
||||
// -----
|
||||
INLINE float gr2rad(uint grad);
|
||||
INLINE FIXED gr2lut(uint grad);
|
||||
INLINE FIXED rad2lut(float rad);
|
||||
INLINE FIXED fxrad2lut(FIXED rad);
|
||||
INLINE float fx12ToFloat(FIXED fx);
|
||||
INLINE FIXED fx12Tofx8(FIXED fx12);
|
||||
INLINE FIXED fxtan(FIXED fxrad);
|
||||
INLINE float rnd(float val);
|
||||
|
||||
// ---- impl
|
||||
INLINE float rnd(float val) {
|
||||
return (float) ((std::floor(val * 100) + .5) / 100);
|
||||
}
|
||||
|
||||
INLINE float gr2rad(uint grad) {
|
||||
return grad*M_PI/180;
|
||||
}
|
||||
|
||||
INLINE FIXED gr2lut(uint grad) {
|
||||
return 65535 / (360 / grad);
|
||||
}
|
||||
|
||||
INLINE FIXED rad2lut(float rad) {
|
||||
return gr2lut(rad * 180 / M_PI);
|
||||
}
|
||||
|
||||
INLINE FIXED fxrad2lut(FIXED rad) {
|
||||
// TODO NOT good; too much divisions, but hey, fuck it
|
||||
return rad2lut(fx2float(rad));
|
||||
}
|
||||
|
||||
INLINE float fx12ToFloat(FIXED fx) {
|
||||
return fx / (float) (1<<12);
|
||||
}
|
||||
|
||||
INLINE FIXED fx12Tofx8(FIXED fx12) {
|
||||
return fx12 >> 4;
|
||||
}
|
||||
|
||||
INLINE FIXED fxtan(FIXED fxrad) {
|
||||
FIXED theta = fxrad2lut(fxrad);
|
||||
FIXED sin = fx12Tofx8(lu_sin(theta));
|
||||
FIXED cos = fx12Tofx8(lu_cos(theta));
|
||||
|
||||
return fxdiv(sin, cos);
|
||||
}
|
||||
|
||||
#endif //GBA_BITMAP_ENGINE_PROJECT_MATH_H
|
|
@ -0,0 +1,8 @@
|
|||
//
|
||||
// Created by Wouter Groeneveld on 08/07/20.
|
||||
//
|
||||
|
||||
#include <libgba-sprite-engine/math.h>
|
||||
|
||||
FIXED HALF = float2fx(0.5);
|
||||
FIXED ONE = int2fx(1);
|
|
@ -33,6 +33,7 @@ add_executable(unittest
|
|||
../engine/src/palette/palette_manager.cpp
|
||||
../engine/src/palette/combined_palette.cpp
|
||||
../engine/src/timer.cpp
|
||||
../engine/src/math.cpp
|
||||
../engine/src/gbavector.cpp
|
||||
timertest.cpp gbavectortest.cpp gbamatrixtest.cpp fixedpoinmathtest.cpp)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <libgba-sprite-engine/gba/tonc_math_stub.h>
|
||||
#include <libgba-sprite-engine/math.h>
|
||||
|
||||
class FpSuite : public ::testing::Test {
|
||||
protected:
|
||||
|
@ -16,30 +17,6 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
float rnd(float val) {
|
||||
return (float) ((std::floor(val * 100) + .5) / 100);
|
||||
}
|
||||
|
||||
float gr2rad(uint grad) {
|
||||
return grad*M_PI/180;
|
||||
}
|
||||
|
||||
FIXED gr2lut(uint grad) {
|
||||
return 65535 / (360 / grad);
|
||||
}
|
||||
|
||||
FIXED rad2lut(float rad) {
|
||||
return gr2lut(rad * 180 / M_PI);
|
||||
}
|
||||
|
||||
float fx12ToFloat(FIXED fx) {
|
||||
return fx / (float) (1<<12);
|
||||
}
|
||||
|
||||
FIXED fx12Tofx8(FIXED fx12) {
|
||||
return fx12 >> 4;
|
||||
}
|
||||
|
||||
|
||||
// from LUT doxygen:
|
||||
//! Look-up a cosine value (2π = 0x10000)
|
||||
|
@ -63,6 +40,25 @@ TEST_F(FpSuite, LUTValueTests) {
|
|||
ASSERT_EQ(rnd(sinLutConv8), 0.995f);
|
||||
}
|
||||
|
||||
TEST_F(FpSuite, TanFromFixedPointRadian) {
|
||||
// 20 degrees is 0.34906577777777775 rad
|
||||
// will be stored as .8f as input val
|
||||
FIXED angle = float2fx(0.34906577777777775f);
|
||||
|
||||
float result = fx2float(fxtan(angle));
|
||||
ASSERT_EQ(rnd(result), 0.355f);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(FpSuite, SinFromFixedPointRadInput) {
|
||||
// 20 degrees is 0.34906577777777775 rad
|
||||
FIXED angle = float2fx(0.34906577777777775f);
|
||||
|
||||
FIXED lusin = lu_sin(fxrad2lut(angle));
|
||||
float result = fx12ToFloat(lusin);
|
||||
ASSERT_EQ(rnd(result), 0.335f);
|
||||
}
|
||||
|
||||
TEST_F(FpSuite, TanUtilityTests) {
|
||||
// 20 degrees is 0.34906577777777775 rad
|
||||
// Math.sin(0.3...) / Math.cos(0.3...) = 0.3420 / 0.9396 = 0.3639...
|
||||
|
@ -75,7 +71,7 @@ TEST_F(FpSuite, TanUtilityTests) {
|
|||
FIXED lutalpha = rad2lut(rad);
|
||||
FIXED lusin = lu_sin(lutalpha), lucos = lu_cos(lutalpha);
|
||||
|
||||
std::cout << "sin(14) is " << fx12ToFloat(lusin) << " and cos(14) is " << fx12ToFloat(lucos) << std::endl;
|
||||
std::cout << "sin(20) is " << fx12ToFloat(lusin) << " and cos(20) is " << fx12ToFloat(lucos) << std::endl;
|
||||
|
||||
auto tanFakeLookupTables = fx2float(fxdiv(fx12Tofx8(lu_sin(lutalpha)), fx12Tofx8(lu_cos(lutalpha))));
|
||||
ASSERT_EQ(rnd(tanFakeLookupTables), 0.355f);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <math.h>
|
||||
#include <libgba-sprite-engine/gbamatrix.h>
|
||||
#include <libgba-sprite-engine/math.h>
|
||||
|
||||
class GBAMatrixSuite : public ::testing::Test {
|
||||
protected:
|
||||
|
@ -15,19 +16,6 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
TEST_F(GBAMatrixSuite, TanUtilityTests) {
|
||||
// Math.sin(14) / Math.cos(14) = 0.99 / 0.13 = 7.2446
|
||||
auto tanRef = sin(14) / cos(14);
|
||||
auto realTan = tan(14);
|
||||
ASSERT_EQ((std::floor(tanRef * 100) + .5) / 100, 7.245);
|
||||
ASSERT_EQ((std::floor(realTan * 100) + .5) / 100, 7.245);
|
||||
|
||||
auto tanFakeLookupTables = ((lu_sin(14)) / (lu_cos(14))) << 4;
|
||||
ASSERT_EQ((std::floor(tanFakeLookupTables * 100) + .5) / 100, 7.245);
|
||||
|
||||
auto result = fx2float(GBAMatrix::tan(int2fx(14)));
|
||||
ASSERT_EQ(result, 7.2446);
|
||||
}
|
||||
|
||||
TEST_F(GBAMatrixSuite, PerspectiveFovLH_TestData) {
|
||||
/* IN:
|
||||
|
@ -51,5 +39,12 @@ TEST_F(GBAMatrixSuite, PerspectiveFovLH_TestData) {
|
|||
15: 0
|
||||
*/
|
||||
auto result = GBAMatrix::perspectiveFovLH(float2fx(0.78), float2fx(1.6), float2fx(0.01), float2fx(1));
|
||||
ASSERT_EQ(fx2float(result.mAt(0)), 1.52);
|
||||
|
||||
// hmm... is this correct? rounding issues aside?
|
||||
ASSERT_EQ(rnd(fx2float(result.mAt(0))), 1.565f);
|
||||
ASSERT_EQ(fx2float(result.mAt(1)), 0);
|
||||
ASSERT_EQ(rnd(fx2float(result.mAt(5))), 2.505f);
|
||||
ASSERT_EQ(rnd(fx2float(result.mAt(10))), 1.005f);
|
||||
ASSERT_EQ(rnd(fx2float(result.mAt(14))), -0.005f);
|
||||
ASSERT_EQ(fx2float(result.mAt(15)), 0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue