More additions and enhancements to math code, see details (#19)
Added C3D_AngleFromDegrees Added FVec4_PerspDivide Added LH option for projections
This commit is contained in:
parent
dde8877f38
commit
dc4d81eea9
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
*~
|
||||
*.3dsx
|
||||
*.elf
|
||||
*.exe
|
||||
*.smdh
|
||||
*.tar.bz2
|
||||
Thumbs.db
|
||||
|
@ -8,12 +8,19 @@
|
||||
/// The one true circumference-to-radius ratio
|
||||
#define M_TAU (2*M_PI)
|
||||
|
||||
/**
|
||||
* @brief Convert an angle from revolutions to radians
|
||||
* @param[in] _angle Proportion of a full revolution
|
||||
* @return Angle in radians
|
||||
*/
|
||||
#define C3D_Angle(_angle) ((_angle)*M_TAU)
|
||||
|
||||
/**
|
||||
* @brief Convert an angle from degrees to radians
|
||||
* @param[in] _angle Angle in degrees
|
||||
* @return Angle in radians
|
||||
*/
|
||||
#define C3D_Angle(_angle) ((_angle)*M_TAU)
|
||||
#define C3D_AngleFromDegrees(_angle) ((_angle)*M_TAU/360.0f)
|
||||
|
||||
#define C3D_AspectRatioTop (400.0f / 240.0f) ///< Aspect ratio for 3DS top screen
|
||||
#define C3D_AspectRatioBot (320.0f / 240.0f) ///< Aspect ratio for 3DS bottom screen
|
||||
@ -81,6 +88,17 @@ static inline C3D_FVec FVec4_Scale(C3D_FVec v, float s)
|
||||
return FVec4_New(v.x*s, v.y*s, v.z*s, v.w*s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perspective divide
|
||||
* @param[in] v Vector to divide
|
||||
* @return v/v.w
|
||||
*/
|
||||
static inline C3D_FVec FVec4_PerspDivide(C3D_FVec v)
|
||||
{
|
||||
// divide by w
|
||||
return FVec4_New(v.x/v.w, v.y/v.w, v.z/v.w, 1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dot product of two FVec4s
|
||||
* @param[in] lhs Left-side FVec4
|
||||
@ -383,24 +401,26 @@ void Mtx_RotateZ(C3D_Mtx* mtx, float angle, bool bRightSide);
|
||||
/**
|
||||
* @brief Orthogonal projection
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] left Left clip plane (X=left)
|
||||
* @param[in] right Right clip plane (X=right)
|
||||
* @param[in] bottom Bottom clip plane (Y=bottom)
|
||||
* @param[in] top Top clip plane (Y=top)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] left Left clip plane (X=left)
|
||||
* @param[in] right Right clip plane (X=right)
|
||||
* @param[in] bottom Bottom clip plane (Y=bottom)
|
||||
* @param[in] top Top clip plane (Y=top)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] isLeftHanded Whether to build a LH projection
|
||||
*/
|
||||
void Mtx_Ortho(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far);
|
||||
void Mtx_Ortho(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far, bool isLeftHanded);
|
||||
|
||||
/**
|
||||
* @brief Perspective projection
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] fovy Vertical field of view in radians
|
||||
* @param[in] aspect Aspect ration of projection plane (width/height)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] fovy Vertical field of view in radians
|
||||
* @param[in] aspect Aspect ration of projection plane (width/height)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] isLeftHanded Whether to build a LH projection
|
||||
*/
|
||||
void Mtx_Persp(C3D_Mtx* mtx, float fovy, float aspect, float near, float far);
|
||||
void Mtx_Persp(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, bool isLeftHanded);
|
||||
|
||||
/**
|
||||
* @brief Stereo perspective projection
|
||||
@ -410,49 +430,53 @@ void Mtx_Persp(C3D_Mtx* mtx, float fovy, float aspect, float near, float far);
|
||||
* they will appear to be inside the screen. If objects are closer than this,
|
||||
* they will appear to pop out of the screen. Objects at this distance appear
|
||||
* to be at the screen.
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] fovy Vertical field of view in radians
|
||||
* @param[in] aspect Aspect ration of projection plane (width/height)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] iod Interocular distance
|
||||
* @param[in] screen Focal length
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] fovy Vertical field of view in radians
|
||||
* @param[in] aspect Aspect ration of projection plane (width/height)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] iod Interocular distance
|
||||
* @param[in] screen Focal length
|
||||
* @param[in] isLeftHanded Whether to build a LH projection
|
||||
*/
|
||||
void Mtx_PerspStereo(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, float iod, float screen);
|
||||
void Mtx_PerspStereo(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, float iod, float screen, bool isLeftHanded);
|
||||
|
||||
/**
|
||||
* @brief Orthogonal projection, tilted to account for the 3DS screen rotation
|
||||
* @param[in] left Left clip plane (X=left)
|
||||
* @param[in] right Right clip plane (X=right)
|
||||
* @param[in] bottom Bottom clip plane (Y=bottom)
|
||||
* @param[in] top Top clip plane (Y=top)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] left Left clip plane (X=left)
|
||||
* @param[in] right Right clip plane (X=right)
|
||||
* @param[in] bottom Bottom clip plane (Y=bottom)
|
||||
* @param[in] top Top clip plane (Y=top)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] isLeftHanded Whether to build a LH projection
|
||||
*/
|
||||
void Mtx_OrthoTilt(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far);
|
||||
void Mtx_OrthoTilt(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far, bool isLeftHanded);
|
||||
|
||||
/**
|
||||
* @brief Perspective projection, tilted to account for the 3DS screen rotation
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] fovy Vertical field of view in radians
|
||||
* @param[in] aspect Aspect ration of projection plane (width/height)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] fovy Vertical field of view in radians
|
||||
* @param[in] aspect Aspect ration of projection plane (width/height)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] isLeftHanded Whether to build a LH projection
|
||||
*/
|
||||
void Mtx_PerspTilt(C3D_Mtx* mtx, float fovy, float aspect, float near, float far);
|
||||
void Mtx_PerspTilt(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, bool isLeftHanded);
|
||||
|
||||
/**
|
||||
* @brief Stereo perspective projection, tilted to account for the 3DS screen rotation
|
||||
* @note See the notes for Mtx_PerspStereo
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] fovy Vertical field of view in radians
|
||||
* @param[in] aspect Aspect ration of projection plane (width/height)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] iod Interocular distance
|
||||
* @param[in] screen Focal length
|
||||
* @param[out] mtx Output matrix
|
||||
* @param[in] fovy Vertical field of view in radians
|
||||
* @param[in] aspect Aspect ration of projection plane (width/height)
|
||||
* @param[in] near Near clip plane (Z=near)
|
||||
* @param[in] far Far clip plane (Z=far)
|
||||
* @param[in] iod Interocular distance
|
||||
* @param[in] screen Focal length
|
||||
* @param[in] isLeftHanded Whether to build a LH projection
|
||||
*/
|
||||
void Mtx_PerspStereoTilt(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, float iod, float screen);
|
||||
void Mtx_PerspStereoTilt(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, float iod, float screen, bool isLeftHanded);
|
||||
|
||||
/**
|
||||
* @brief Left-handed Look-At matrix, using DirectX implementation
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Ortho(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far)
|
||||
void Mtx_Ortho(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far, bool isLeftHanded)
|
||||
{
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
@ -11,7 +11,10 @@ void Mtx_Ortho(C3D_Mtx* mtx, float left, float right, float bottom, float top, f
|
||||
mtx->r[0].w = (left + right) / (left - right);
|
||||
mtx->r[1].y = 2.0f / (top - bottom);
|
||||
mtx->r[1].w = (bottom + top) / (bottom - top);
|
||||
mtx->r[2].z = 1.0f / (far - near);
|
||||
if (isLeftHanded)
|
||||
mtx->r[2].z = 1.0f / (far - near);
|
||||
else
|
||||
mtx->r[2].z = 1.0f / (near - far);
|
||||
mtx->r[2].w = 0.5f*(near + far) / (near - far) - 0.5f;
|
||||
mtx->r[3].w = 1.0f;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_OrthoTilt(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far)
|
||||
void Mtx_OrthoTilt(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far, bool isLeftHanded)
|
||||
{
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
@ -12,7 +12,10 @@ void Mtx_OrthoTilt(C3D_Mtx* mtx, float left, float right, float bottom, float to
|
||||
mtx->r[0].w = (bottom + top) / (bottom - top);
|
||||
mtx->r[1].x = 2.0f / (left - right);
|
||||
mtx->r[1].w = (left + right) / (right - left);
|
||||
mtx->r[2].z = 1.0f / (far - near);
|
||||
if (isLeftHanded)
|
||||
mtx->r[2].z = 1.0f / (far - near);
|
||||
else
|
||||
mtx->r[2].z = 1.0f / (near - far);
|
||||
mtx->r[2].w = 0.5f*(near + far) / (near - far) - 0.5f;
|
||||
mtx->r[3].w = 1.0f;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Persp(C3D_Mtx* mtx, float fovy, float aspect, float near, float far)
|
||||
void Mtx_Persp(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, bool isLeftHanded)
|
||||
{
|
||||
float fovy_tan = tanf(fovy/2.0f);
|
||||
|
||||
@ -11,7 +11,16 @@ void Mtx_Persp(C3D_Mtx* mtx, float fovy, float aspect, float near, float far)
|
||||
|
||||
mtx->r[0].x = 1.0f / (aspect * fovy_tan);
|
||||
mtx->r[1].y = 1.0f / fovy_tan;
|
||||
mtx->r[2].z = 0.5f*(far + near) / (near - far) + 0.5f;
|
||||
mtx->r[2].w = far*near / (near - far);
|
||||
mtx->r[3].z = -1.0f;
|
||||
|
||||
if (isLeftHanded)
|
||||
{
|
||||
mtx->r[2].z = 0.5f*(far + near) / (far - near) - 0.5f;
|
||||
mtx->r[3].z = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx->r[2].z = 0.5f*(far + near) / (near - far) + 0.5f;
|
||||
mtx->r[3].z = -1.0f;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_PerspStereo(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, float iod, float screen)
|
||||
void Mtx_PerspStereo(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, float iod, float screen, bool isLeftHanded)
|
||||
{
|
||||
float fovy_tan = tanf(fovy/2.0f);
|
||||
float fovy_tan_aspect = fovy_tan*aspect;
|
||||
@ -9,10 +9,20 @@ void Mtx_PerspStereo(C3D_Mtx* mtx, float fovy, float aspect, float near, float f
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
mtx->r[0].x = 1.0f / fovy_tan_aspect;
|
||||
mtx->r[0].z = -shift / fovy_tan_aspect;
|
||||
mtx->r[0].w = -iod / 2.0f;
|
||||
mtx->r[1].y = 1.0f / fovy_tan;
|
||||
mtx->r[2].z = 0.5f*(near + far) / (near - far) + 0.5f;
|
||||
mtx->r[2].w = near * far / (near - far);
|
||||
mtx->r[3].z = -1.0f;
|
||||
|
||||
if (isLeftHanded)
|
||||
{
|
||||
mtx->r[0].z = shift / fovy_tan_aspect;
|
||||
mtx->r[2].z = 0.5f*(near + far) / (far - near) - 0.5f;
|
||||
mtx->r[3].z = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx->r[0].z = -shift / fovy_tan_aspect;
|
||||
mtx->r[2].z = 0.5f*(near + far) / (near - far) + 0.5f;
|
||||
mtx->r[3].z = -1.0f;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_PerspStereoTilt(C3D_Mtx* mtx, float fovx, float invaspect, float near, float far, float iod, float screen)
|
||||
void Mtx_PerspStereoTilt(C3D_Mtx* mtx, float fovx, float invaspect, float near, float far, float iod, float screen, bool isLeftHanded)
|
||||
{
|
||||
// Notes:
|
||||
// Once again, we are passed "fovy" and the "aspect ratio"; however the 3DS screens are sideways,
|
||||
@ -15,9 +15,19 @@ void Mtx_PerspStereoTilt(C3D_Mtx* mtx, float fovx, float invaspect, float near,
|
||||
|
||||
mtx->r[0].y = 1.0f / fovx_tan;
|
||||
mtx->r[1].x = -1.0f / fovx_tan_invaspect;
|
||||
mtx->r[1].z = shift / fovx_tan_invaspect;
|
||||
mtx->r[1].w = iod / 2.0f;
|
||||
mtx->r[2].z = 0.5f*(near + far) / (near - far) + 0.5f;
|
||||
mtx->r[2].w = near * far / (near - far);
|
||||
mtx->r[3].z = -1.0f;
|
||||
|
||||
if (isLeftHanded)
|
||||
{
|
||||
mtx->r[1].z = -shift / fovx_tan_invaspect;
|
||||
mtx->r[2].z = 0.5f*(near + far) / (far - near) - 0.5f;
|
||||
mtx->r[3].z = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx->r[1].z = shift / fovx_tan_invaspect;
|
||||
mtx->r[2].z = 0.5f*(near + far) / (near - far) + 0.5f;
|
||||
mtx->r[3].z = -1.0f;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_PerspTilt(C3D_Mtx* mtx, float fovx, float invaspect, float near, float far)
|
||||
void Mtx_PerspTilt(C3D_Mtx* mtx, float fovx, float invaspect, float near, float far, bool isLeftHanded)
|
||||
{
|
||||
// Notes:
|
||||
// We are passed "fovy" and the "aspect ratio". However, the 3DS screens are sideways,
|
||||
@ -31,7 +31,16 @@ void Mtx_PerspTilt(C3D_Mtx* mtx, float fovx, float invaspect, float near, float
|
||||
|
||||
mtx->r[0].y = 1.0f / fovx_tan;
|
||||
mtx->r[1].x = -1.0f / (fovx_tan*invaspect);
|
||||
mtx->r[2].z = 0.5f*(far + near) / (near - far) + 0.5f;
|
||||
mtx->r[2].w = far*near / (near - far);
|
||||
mtx->r[3].z = -1.0f;
|
||||
|
||||
if (isLeftHanded)
|
||||
{
|
||||
mtx->r[2].z = 0.5f*(far + near) / (far - near) - 0.5f;
|
||||
mtx->r[3].z = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx->r[2].z = 0.5f*(far + near) / (near - far) + 0.5f;
|
||||
mtx->r[3].z = -1.0f;
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ void persp_tilt_test()
|
||||
C3D_RenderTargetSetClear(top, C3D_CLEAR_ALL, CLEAR_COLOR, 0);
|
||||
C3D_RenderTargetSetOutput(top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
||||
|
||||
Mtx_PerspTilt(&projection, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f);
|
||||
Mtx_PerspTilt(&projection, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, false);
|
||||
|
||||
Mtx_Identity(&modelView);
|
||||
Mtx_Translate(&modelView, x, y, z, true);
|
||||
@ -286,7 +286,7 @@ void ortho_tilt_test()
|
||||
C3D_RenderTargetSetClear(top, C3D_CLEAR_ALL, CLEAR_COLOR, 0);
|
||||
C3D_RenderTargetSetOutput(top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
||||
|
||||
Mtx_OrthoTilt(&projection, 0.0f, 400.0f, 0.0f, 240.0f, 100.0f, -100.0f);
|
||||
Mtx_OrthoTilt(&projection, 0.0f, 400.0f, 0.0f, 240.0f, 100.0f, -100.0f, false);
|
||||
|
||||
Mtx_Identity(&texView);
|
||||
|
||||
@ -380,8 +380,8 @@ void stereo_tilt_test()
|
||||
C3D_RenderTargetSetOutput(topLeft, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
||||
C3D_RenderTargetSetOutput(topRight, GFX_TOP, GFX_RIGHT, DISPLAY_TRANSFER_FLAGS);
|
||||
|
||||
Mtx_PerspStereoTilt(&projLeft, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, -iod, focLen);
|
||||
Mtx_PerspStereoTilt(&projRight, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, iod, focLen);
|
||||
Mtx_PerspStereoTilt(&projLeft, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, -iod, focLen, false);
|
||||
Mtx_PerspStereoTilt(&projRight, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, iod, focLen, false);
|
||||
|
||||
Mtx_Identity(&texView);
|
||||
|
||||
@ -446,8 +446,8 @@ void stereo_tilt_test()
|
||||
std::printf("(Y/A) focLen %.1f\n", focLen);
|
||||
std::printf("(3D Slider) iod %.1f\n", iod);
|
||||
|
||||
Mtx_PerspStereoTilt(&projLeft, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, -iod, focLen);
|
||||
Mtx_PerspStereoTilt(&projRight, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, iod, focLen);
|
||||
Mtx_PerspStereoTilt(&projLeft, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, -iod, focLen, false);
|
||||
Mtx_PerspStereoTilt(&projRight, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, iod, focLen, false);
|
||||
}
|
||||
|
||||
Mtx_Identity(&modelView);
|
||||
@ -499,12 +499,12 @@ void persp_test()
|
||||
C3D_RenderTargetSetClear(tex, C3D_CLEAR_ALL, CLEAR_COLOR, 0);
|
||||
C3D_TexSetFilter(&tex->renderBuf.colorBuf, GPU_LINEAR, GPU_NEAREST);
|
||||
|
||||
Mtx_Persp(&projTex, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f);
|
||||
Mtx_Persp(&projTex, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, false);
|
||||
|
||||
Mtx_Identity(&modelView);
|
||||
Mtx_Translate(&modelView, x, y, z, true);
|
||||
|
||||
Mtx_OrthoTilt(&projTop, -0.5f, 0.5f, -0.5f, 0.5f, 100.0f, -100.0f);
|
||||
Mtx_OrthoTilt(&projTop, -0.5f, 0.5f, -0.5f, 0.5f, 100.0f, -100.0f, false);
|
||||
Mtx_Identity(&texView);
|
||||
|
||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_modelView, &modelView);
|
||||
@ -553,7 +553,7 @@ void persp_test()
|
||||
std::printf("(UP/DOWN) y %.1f\n", y);
|
||||
std::printf("(L/R) z %.1f\n", z);
|
||||
|
||||
Mtx_Persp(&projTex, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f);
|
||||
Mtx_Persp(&projTex, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, false);
|
||||
}
|
||||
|
||||
Mtx_Identity(&modelView);
|
||||
@ -615,13 +615,13 @@ void stereo_test()
|
||||
C3D_TexSetFilter(&texLeft->renderBuf.colorBuf, GPU_LINEAR, GPU_NEAREST);
|
||||
C3D_TexSetFilter(&texRight->renderBuf.colorBuf, GPU_LINEAR, GPU_NEAREST);
|
||||
|
||||
Mtx_PerspStereo(&projLeft, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, -iod, focLen);
|
||||
Mtx_PerspStereo(&projRight, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, iod, focLen);
|
||||
Mtx_PerspStereo(&projLeft, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, -iod, focLen, false);
|
||||
Mtx_PerspStereo(&projRight, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, iod, focLen, false);
|
||||
|
||||
Mtx_Identity(&modelView);
|
||||
Mtx_Translate(&modelView, x, y, z, true);
|
||||
|
||||
Mtx_OrthoTilt(&proj, -0.5f, 0.5f, -0.5f, 0.5f, 100.0f, -100.0f);
|
||||
Mtx_OrthoTilt(&proj, -0.5f, 0.5f, -0.5f, 0.5f, 100.0f, -100.0f, false);
|
||||
Mtx_Identity(&texView);
|
||||
|
||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_modelView, &modelView);
|
||||
@ -683,8 +683,8 @@ void stereo_test()
|
||||
std::printf("(Y/A) focLen %.1f\n", focLen);
|
||||
std::printf("(3D Slider) iod %.1f\n", iod);
|
||||
|
||||
Mtx_PerspStereo(&projLeft, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, -iod, focLen);
|
||||
Mtx_PerspStereo(&projRight, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, iod, focLen);
|
||||
Mtx_PerspStereo(&projLeft, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, -iod, focLen, false);
|
||||
Mtx_PerspStereo(&projRight, 60.0f*M_TAU/360.0f, 400.0f/240.0f, 1.0f, 10.0f, iod, focLen, false);
|
||||
}
|
||||
|
||||
Mtx_Identity(&modelView);
|
||||
@ -753,12 +753,12 @@ void ortho_test()
|
||||
C3D_RenderTargetSetClear(tex, C3D_CLEAR_ALL, CLEAR_COLOR, 0);
|
||||
C3D_TexSetFilter(&tex->renderBuf.colorBuf, GPU_LINEAR, GPU_NEAREST);
|
||||
|
||||
Mtx_Ortho(&projTex, 0.0f, 400.0f, 0.0f, 240.0f, 100.0f, -100.0f);
|
||||
Mtx_Ortho(&projTex, 0.0f, 400.0f, 0.0f, 240.0f, 100.0f, -100.0f, false);
|
||||
|
||||
Mtx_Identity(&modelView);
|
||||
Mtx_Translate(&modelView, x, y, z, true);
|
||||
|
||||
Mtx_OrthoTilt(&projTop, -0.5f, 0.5f, -0.5f, 0.5f, 100.0f, -100.0f);
|
||||
Mtx_OrthoTilt(&projTop, -0.5f, 0.5f, -0.5f, 0.5f, 100.0f, -100.0f, false);
|
||||
Mtx_Identity(&texView);
|
||||
|
||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_modelView, &modelView);
|
||||
|
@ -2,8 +2,9 @@ TARGET := test
|
||||
|
||||
CFILES := $(wildcard *.c) $(wildcard ../../source/maths/*.c)
|
||||
CXXFILES := $(wildcard *.cpp)
|
||||
OFILES := $(CXXFILES:.cpp=.o) $(CFILES:.c=.o)
|
||||
DFILES := $(wildcard *.d) $(wildcard ../../source/maths/*.d)
|
||||
OFILES := $(addprefix build/,$(CXXFILES:.cpp=.o)) \
|
||||
$(patsubst ../../source/maths/%,build/%,$(CFILES:.c=.o))
|
||||
DFILES := $(wildcard build/*.d)
|
||||
|
||||
CFLAGS := -Wall -g -pipe -I../../include
|
||||
CXXFLAGS := $(CFLAGS) -std=gnu++11 -DGLM_FORCE_RADIANS
|
||||
@ -17,15 +18,20 @@ $(TARGET): $(OFILES)
|
||||
@echo "Linking $@"
|
||||
$(CXX) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
%.o : %.cpp $(wildcard *.h)
|
||||
@echo "Compiling $@"
|
||||
@$(CXX) -o $@ -c $< $(CXXFLAGS) -MMD -MP -MF $*.d
|
||||
$(OFILES): | build
|
||||
|
||||
%.o : %.c $(wildcard *.h)
|
||||
build:
|
||||
@[ -d build ] || mkdir build
|
||||
|
||||
build/%.o : %.cpp $(wildcard *.h)
|
||||
@echo "Compiling $@"
|
||||
@$(CC) -o $@ -c $< $(CFLAGS) -MMD -MP -MF $*.d
|
||||
@$(CXX) -o $@ -c $< $(CXXFLAGS) -MMD -MP -MF build/$*.d
|
||||
|
||||
build/%.o : ../../source/maths/%.c $(wildcard *.h)
|
||||
@echo "Compiling $@"
|
||||
@$(CC) -o $@ -c $< $(CFLAGS) -MMD -MP -MF build/$*.d
|
||||
|
||||
clean:
|
||||
$(RM) $(OFILES) $(DFILES) $(TARGET)
|
||||
$(RM) -r $(TARGET) build/
|
||||
|
||||
-include $(DFILES)
|
||||
|
111
test/pc/main.cpp
111
test/pc/main.cpp
@ -207,6 +207,7 @@ print(const glm::quat &q)
|
||||
static const glm::vec3 x_axis(1.0f, 0.0f, 0.0f);
|
||||
static const glm::vec3 y_axis(0.0f, 1.0f, 0.0f);
|
||||
static const glm::vec3 z_axis(0.0f, 0.0f, 1.0f);
|
||||
static const glm::vec3 z_flip(1.0f, 1.0f, -1.0f);
|
||||
|
||||
static void
|
||||
check_matrix(generator_t &gen, distribution_t &dist)
|
||||
@ -225,6 +226,52 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
assert(m == glm::mat4());
|
||||
}
|
||||
|
||||
// ortho nominal cases
|
||||
{
|
||||
C3D_Mtx m;
|
||||
C3D_FVec v;
|
||||
float l = 0.0f,
|
||||
r = 400.0f,
|
||||
b = 0.0f,
|
||||
t = 320.0f,
|
||||
n = 0.0f,
|
||||
f = 100.0f;
|
||||
|
||||
Mtx_Ortho(&m, l, r, b, t, n, f, false);
|
||||
|
||||
// check near clip plane
|
||||
v = Mtx_MultiplyFVecH(&m, FVec3_New((r-l)/2.0f, (t-b)/2.0f, -n));
|
||||
v = FVec4_PerspDivide(v);
|
||||
assert(v == FVec4_New(0.0f, 0.0f, -1.0f, 1.0f));
|
||||
|
||||
// check far clip plane
|
||||
v = Mtx_MultiplyFVecH(&m, FVec3_New((r-l)/2.0f, (t-b)/2.0f, -f));
|
||||
v = FVec4_PerspDivide(v);
|
||||
assert(v == FVec4_New(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
// perspective nominal cases
|
||||
{
|
||||
C3D_Mtx m;
|
||||
C3D_FVec v;
|
||||
float fovy = C3D_Angle(60.0f/360.0f),
|
||||
aspect = C3D_AspectRatioTop,
|
||||
near = 0.1f,
|
||||
far = 10.0f;
|
||||
|
||||
Mtx_Persp(&m, fovy, aspect, near, far, false);
|
||||
|
||||
// check near clip plane
|
||||
v = Mtx_MultiplyFVecH(&m, FVec3_New(0.0f, 0.0f, -near));
|
||||
v = FVec4_PerspDivide(v);
|
||||
assert(v == FVec4_New(0.0f, 0.0f, -1.0f, 1.0f));
|
||||
|
||||
// check far clip plane
|
||||
v = Mtx_MultiplyFVecH(&m, FVec3_New(0.0f, 0.0f, -far));
|
||||
v = FVec4_PerspDivide(v);
|
||||
assert(v == FVec4_New(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
for(size_t x = 0; x < 10000; ++x)
|
||||
{
|
||||
// check inverse
|
||||
@ -270,11 +317,15 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
while(std::abs(far - near) < 0.1f)
|
||||
far = dist(gen);
|
||||
|
||||
Mtx_Persp(&m, fovy, aspect, near, far);
|
||||
|
||||
// RH
|
||||
Mtx_Persp(&m, fovy, aspect, near, far, false);
|
||||
glm::mat4 g = glm::perspective(fovy, aspect, near, far);
|
||||
|
||||
assert(m == fix_depth*g);
|
||||
|
||||
// LH
|
||||
Mtx_Persp(&m, fovy, aspect, near, far, true);
|
||||
g = glm::perspective(fovy, aspect, near, far);
|
||||
assert(m == fix_depth*glm::scale(g, z_flip));
|
||||
}
|
||||
|
||||
// check perspective tilt
|
||||
@ -300,11 +351,15 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
while(std::abs(far - near) < 0.1f)
|
||||
far = dist(gen);
|
||||
|
||||
Mtx_PerspTilt(&m, fovy, aspect, near, far);
|
||||
|
||||
// RH
|
||||
Mtx_PerspTilt(&m, fovy, aspect, near, far, false);
|
||||
glm::mat4 g = glm::perspective(fovx, 1.0f / aspect, near, far);
|
||||
|
||||
assert(m == fix_depth*g*tilt);
|
||||
|
||||
// LH
|
||||
Mtx_PerspTilt(&m, fovy, aspect, near, far, true);
|
||||
g = glm::perspective(fovx, 1.0f / aspect, near, far);
|
||||
assert(m == fix_depth*glm::scale(g, z_flip)*tilt);
|
||||
}
|
||||
|
||||
// check perspective stereo
|
||||
@ -336,9 +391,6 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
while(focLen < 0.25f)
|
||||
focLen = dist(gen);
|
||||
|
||||
Mtx_PerspStereo(&left, fovy, aspect, near, far, -iod, focLen);
|
||||
Mtx_PerspStereo(&right, fovy, aspect, near, far, iod, focLen);
|
||||
|
||||
glm::mat4 g = glm::perspective(fovy, aspect, near, far);
|
||||
|
||||
fovy_tan = tanf(fovy/2.0f);
|
||||
@ -351,8 +403,17 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
-iod/(focLen*2.0f), 0.0f, 1.0f, 0.0f,
|
||||
-iod*fovy_tan*aspect/2.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
// RH
|
||||
Mtx_PerspStereo(&left, fovy, aspect, near, far, -iod, focLen, false);
|
||||
Mtx_PerspStereo(&right, fovy, aspect, near, far, iod, focLen, false);
|
||||
assert(left == fix_depth*g*left_eye);
|
||||
assert(right == fix_depth*g*right_eye);
|
||||
|
||||
// LH
|
||||
Mtx_PerspStereo(&left, fovy, aspect, near, far, -iod, focLen, true);
|
||||
Mtx_PerspStereo(&right, fovy, aspect, near, far, iod, focLen, true);
|
||||
assert(left == fix_depth*glm::scale(g*left_eye, z_flip));
|
||||
assert(right == fix_depth*glm::scale(g*right_eye, z_flip));
|
||||
}
|
||||
|
||||
// check perspective stereo tilt
|
||||
@ -384,9 +445,6 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
while(focLen < 0.25f)
|
||||
focLen = dist(gen);
|
||||
|
||||
Mtx_PerspStereoTilt(&left, fovy, aspect, near, far, -iod, focLen);
|
||||
Mtx_PerspStereoTilt(&right, fovy, aspect, near, far, iod, focLen);
|
||||
|
||||
glm::mat4 g = glm::perspective(fovx, 1.0f / aspect, near, far);
|
||||
|
||||
fovx_tan = tanf(fovx/2.0f);
|
||||
@ -399,8 +457,17 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
0.0f, iod/(focLen*2.0f), 1.0f, 0.0f,
|
||||
0.0f, iod*fovx_tan/2.0f, 0.0f, 1.0f);
|
||||
|
||||
// RH
|
||||
Mtx_PerspStereoTilt(&left, fovy, aspect, near, far, -iod, focLen, false);
|
||||
Mtx_PerspStereoTilt(&right, fovy, aspect, near, far, iod, focLen, false);
|
||||
assert(left == fix_depth*g*left_eye*tilt);
|
||||
assert(right == fix_depth*g*right_eye*tilt);
|
||||
|
||||
// LH
|
||||
Mtx_PerspStereoTilt(&left, fovy, aspect, near, far, -iod, focLen, true);
|
||||
Mtx_PerspStereoTilt(&right, fovy, aspect, near, far, iod, focLen, true);
|
||||
assert(left == fix_depth*glm::scale(g*left_eye, z_flip)*tilt);
|
||||
assert(right == fix_depth*glm::scale(g*right_eye, z_flip)*tilt);
|
||||
}
|
||||
|
||||
// check ortho
|
||||
@ -422,11 +489,15 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
while(std::abs(f-n) < 0.1f)
|
||||
f = dist(gen);
|
||||
|
||||
Mtx_Ortho(&m, l, r, b, t, n, f);
|
||||
|
||||
// RH
|
||||
Mtx_Ortho(&m, l, r, b, t, n, f, false);
|
||||
glm::mat4 g = glm::ortho(l, r, b, t, n, f);
|
||||
|
||||
assert(m == fix_depth*g);
|
||||
|
||||
// LH
|
||||
Mtx_Ortho(&m, l, r, b, t, n, f, true);
|
||||
g = glm::ortho(l, r, b, t, n, f);
|
||||
assert(m == fix_depth*glm::scale(g, z_flip));
|
||||
}
|
||||
|
||||
// check ortho tilt
|
||||
@ -448,11 +519,15 @@ check_matrix(generator_t &gen, distribution_t &dist)
|
||||
while(std::abs(f-n) < 0.1f)
|
||||
f = dist(gen);
|
||||
|
||||
Mtx_OrthoTilt(&m, l, r, b, t, n, f);
|
||||
|
||||
// RH
|
||||
Mtx_OrthoTilt(&m, l, r, b, t, n, f, false);
|
||||
glm::mat4 g = glm::ortho(l, r, b, t, n, f);
|
||||
|
||||
assert(m == tilt*fix_depth*g);
|
||||
|
||||
// LH
|
||||
Mtx_OrthoTilt(&m, l, r, b, t, n, f, true);
|
||||
g = glm::ortho(l, r, b, t, n, f);
|
||||
assert(m == tilt*fix_depth*glm::scale(g, z_flip));
|
||||
}
|
||||
|
||||
// check multiply
|
||||
|
Loading…
Reference in New Issue
Block a user