mirror of
https://github.com/ctruLua/ctruLua.git
synced 2025-10-28 16:59:30 +00:00
Updated all the libs, added citro3d, added ctr.swkbd (WIP, untested)
This commit is contained in:
parent
68a44645f7
commit
49c87e5526
97 changed files with 7341 additions and 944 deletions
2
libs/citro3d/source/maths/.gitignore
vendored
Normal file
2
libs/citro3d/source/maths/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
*.d
|
||||
*.o
|
||||
34
libs/citro3d/source/maths/mtx_fromquat.c
Normal file
34
libs/citro3d/source/maths/mtx_fromquat.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_FromQuat(C3D_Mtx* m, C3D_FQuat q)
|
||||
{
|
||||
float ii = q.i*q.i;
|
||||
float ij = q.i*q.j;
|
||||
float ik = q.i*q.k;
|
||||
float jj = q.j*q.j;
|
||||
float jk = q.j*q.k;
|
||||
float kk = q.k*q.k;
|
||||
float ri = q.r*q.i;
|
||||
float rj = q.r*q.j;
|
||||
float rk = q.r*q.k;
|
||||
|
||||
m->r[0].x = 1.0f - (2.0f * (jj + kk));
|
||||
m->r[1].x = 2.0f * (ij + rk);
|
||||
m->r[2].x = 2.0f * (ik - rj);
|
||||
m->r[3].x = 0.0f;
|
||||
|
||||
m->r[0].y = 2.0f * (ij - rk);
|
||||
m->r[1].y = 1.0f - (2.0f * (ii + kk));
|
||||
m->r[2].y = 2.0f * (jk + ri);
|
||||
m->r[3].y = 0.0f;
|
||||
|
||||
m->r[0].z = 2.0f * (ik + rj);
|
||||
m->r[1].z = 2.0f * (jk - ri);
|
||||
m->r[2].z = 1.0f - (2.0f * (ii + jj));
|
||||
m->r[3].z = 0.0f;
|
||||
|
||||
m->r[0].w = 0.0f;
|
||||
m->r[1].w = 0.0f;
|
||||
m->r[2].w = 0.0f;
|
||||
m->r[3].w = 1.0f;
|
||||
}
|
||||
10
libs/citro3d/source/maths/mtx_identity.c
Normal file
10
libs/citro3d/source/maths/mtx_identity.c
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Identity(C3D_Mtx* out)
|
||||
{
|
||||
// http://www.wolframalpha.com/input/?i={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}}
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i)
|
||||
out->m[i] = 0.0f;
|
||||
out->r[0].x = out->r[1].y = out->r[2].z = out->r[3].w = 1.0f;
|
||||
}
|
||||
135
libs/citro3d/source/maths/mtx_inverse.c
Normal file
135
libs/citro3d/source/maths/mtx_inverse.c
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#include <float.h>
|
||||
#include <c3d/maths.h>
|
||||
|
||||
float Mtx_Inverse(C3D_Mtx* out)
|
||||
{
|
||||
//Mtx_Inverse can be used to calculate the determinant and the inverse of the matrix.
|
||||
|
||||
C3D_Mtx inv;
|
||||
float det;
|
||||
int i;
|
||||
|
||||
inv.r[0].x = out->r[1].y * out->r[2].z * out->r[3].w -
|
||||
out->r[1].y * out->r[2].w * out->r[3].z -
|
||||
out->r[2].y * out->r[1].z * out->r[3].w +
|
||||
out->r[2].y * out->r[1].w * out->r[3].z +
|
||||
out->r[3].y * out->r[1].z * out->r[2].w -
|
||||
out->r[3].y * out->r[1].w * out->r[2].z;
|
||||
|
||||
inv.r[1].x = -out->r[1].x * out->r[2].z * out->r[3].w +
|
||||
out->r[1].x * out->r[2].w * out->r[3].z +
|
||||
out->r[2].x * out->r[1].z * out->r[3].w -
|
||||
out->r[2].x * out->r[1].w * out->r[3].z -
|
||||
out->r[3].x * out->r[1].z * out->r[2].w +
|
||||
out->r[3].x * out->r[1].w * out->r[2].z;
|
||||
|
||||
inv.r[2].x = out->r[1].x * out->r[2].y * out->r[3].w -
|
||||
out->r[1].x * out->r[2].w * out->r[3].y -
|
||||
out->r[2].x * out->r[1].y * out->r[3].w +
|
||||
out->r[2].x * out->r[1].w * out->r[3].y +
|
||||
out->r[3].x * out->r[1].y * out->r[2].w -
|
||||
out->r[3].x * out->r[1].w * out->r[2].y;
|
||||
|
||||
inv.r[3].x = -out->r[1].x * out->r[2].y * out->r[3].z +
|
||||
out->r[1].x * out->r[2].z * out->r[3].y +
|
||||
out->r[2].x * out->r[1].y * out->r[3].z -
|
||||
out->r[2].x * out->r[1].z * out->r[3].y -
|
||||
out->r[3].x * out->r[1].y * out->r[2].z +
|
||||
out->r[3].x * out->r[1].z * out->r[2].y;
|
||||
|
||||
det = out->r[0].x * inv.r[0].x + out->r[0].y * inv.r[1].x +
|
||||
out->r[0].z * inv.r[2].x + out->r[0].w * inv.r[3].x;
|
||||
|
||||
if (fabsf(det) < FLT_EPSILON)
|
||||
//Returns 0.0f if we find the determinant is less than +/- FLT_EPSILON.
|
||||
return 0.0f;
|
||||
|
||||
inv.r[0].y = -out->r[0].y * out->r[2].z * out->r[3].w +
|
||||
out->r[0].y * out->r[2].w * out->r[3].z +
|
||||
out->r[2].y * out->r[0].z * out->r[3].w -
|
||||
out->r[2].y * out->r[0].w * out->r[3].z -
|
||||
out->r[3].y * out->r[0].z * out->r[2].w +
|
||||
out->r[3].y * out->r[0].w * out->r[2].z;
|
||||
|
||||
inv.r[1].y = out->r[0].x * out->r[2].z * out->r[3].w -
|
||||
out->r[0].x * out->r[2].w * out->r[3].z -
|
||||
out->r[2].x * out->r[0].z * out->r[3].w +
|
||||
out->r[2].x * out->r[0].w * out->r[3].z +
|
||||
out->r[3].x * out->r[0].z * out->r[2].w -
|
||||
out->r[3].x * out->r[0].w * out->r[2].z;
|
||||
|
||||
inv.r[2].y = -out->r[0].x * out->r[2].y * out->r[3].w +
|
||||
out->r[0].x * out->r[2].w * out->r[3].y +
|
||||
out->r[2].x * out->r[0].y * out->r[3].w -
|
||||
out->r[2].x * out->r[0].w * out->r[3].y -
|
||||
out->r[3].x * out->r[0].y * out->r[2].w +
|
||||
out->r[3].x * out->r[0].w * out->r[2].y;
|
||||
|
||||
inv.r[3].y = out->r[0].x * out->r[2].y * out->r[3].z -
|
||||
out->r[0].x * out->r[2].z * out->r[3].y -
|
||||
out->r[2].x * out->r[0].y * out->r[3].z +
|
||||
out->r[2].x * out->r[0].z * out->r[3].y +
|
||||
out->r[3].x * out->r[0].y * out->r[2].z -
|
||||
out->r[3].x * out->r[0].z * out->r[2].y;
|
||||
|
||||
inv.r[0].z = out->r[0].y * out->r[1].z * out->r[3].w -
|
||||
out->r[0].y * out->r[1].w * out->r[3].z -
|
||||
out->r[1].y * out->r[0].z * out->r[3].w +
|
||||
out->r[1].y * out->r[0].w * out->r[3].z +
|
||||
out->r[3].y * out->r[0].z * out->r[1].w -
|
||||
out->r[3].y * out->r[0].w * out->r[1].z;
|
||||
|
||||
inv.r[1].z = -out->r[0].x * out->r[1].z * out->r[3].w +
|
||||
out->r[0].x * out->r[1].w * out->r[3].z +
|
||||
out->r[1].x * out->r[0].z * out->r[3].w -
|
||||
out->r[1].x * out->r[0].w * out->r[3].z -
|
||||
out->r[3].x * out->r[0].z * out->r[1].w +
|
||||
out->r[3].x * out->r[0].w * out->r[1].z;
|
||||
|
||||
inv.r[2].z = out->r[0].x * out->r[1].y * out->r[3].w -
|
||||
out->r[0].x * out->r[1].w * out->r[3].y -
|
||||
out->r[1].x * out->r[0].y * out->r[3].w +
|
||||
out->r[1].x * out->r[0].w * out->r[3].y +
|
||||
out->r[3].x * out->r[0].y * out->r[1].w -
|
||||
out->r[3].x * out->r[0].w * out->r[1].y;
|
||||
|
||||
inv.r[3].z = -out->r[0].x * out->r[1].y * out->r[3].z +
|
||||
out->r[0].x * out->r[1].z * out->r[3].y +
|
||||
out->r[1].x * out->r[0].y * out->r[3].z -
|
||||
out->r[1].x * out->r[0].z * out->r[3].y -
|
||||
out->r[3].x * out->r[0].y * out->r[1].z +
|
||||
out->r[3].x * out->r[0].z * out->r[1].y;
|
||||
|
||||
inv.r[0].w = -out->r[0].y * out->r[1].z * out->r[2].w +
|
||||
out->r[0].y * out->r[1].w * out->r[2].z +
|
||||
out->r[1].y * out->r[0].z * out->r[2].w -
|
||||
out->r[1].y * out->r[0].w * out->r[2].z -
|
||||
out->r[2].y * out->r[0].z * out->r[1].w +
|
||||
out->r[2].y * out->r[0].w * out->r[1].z;
|
||||
|
||||
inv.r[1].w = out->r[0].x * out->r[1].z * out->r[2].w -
|
||||
out->r[0].x * out->r[1].w * out->r[2].z -
|
||||
out->r[1].x * out->r[0].z * out->r[2].w +
|
||||
out->r[1].x * out->r[0].w * out->r[2].z +
|
||||
out->r[2].x * out->r[0].z * out->r[1].w -
|
||||
out->r[2].x * out->r[0].w * out->r[1].z;
|
||||
|
||||
inv.r[2].w = -out->r[0].x * out->r[1].y * out->r[2].w +
|
||||
out->r[0].x * out->r[1].w * out->r[2].y +
|
||||
out->r[1].x * out->r[0].y * out->r[2].w -
|
||||
out->r[1].x * out->r[0].w * out->r[2].y -
|
||||
out->r[2].x * out->r[0].y * out->r[1].w +
|
||||
out->r[2].x * out->r[0].w * out->r[1].y;
|
||||
|
||||
inv.r[3].w = out->r[0].x * out->r[1].y * out->r[2].z -
|
||||
out->r[0].x * out->r[1].z * out->r[2].y -
|
||||
out->r[1].x * out->r[0].y * out->r[2].z +
|
||||
out->r[1].x * out->r[0].z * out->r[2].y +
|
||||
out->r[2].x * out->r[0].y * out->r[1].z -
|
||||
out->r[2].x * out->r[0].z * out->r[1].y;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
out->m[i] = inv.m[i] / det;
|
||||
|
||||
return det;
|
||||
}
|
||||
37
libs/citro3d/source/maths/mtx_lookat.c
Normal file
37
libs/citro3d/source/maths/mtx_lookat.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_LookAt(C3D_Mtx* out, C3D_FVec cameraPosition, C3D_FVec cameraTarget, C3D_FVec cameraUpVector, bool isLeftHanded)
|
||||
{
|
||||
//Left-handed and Right-handed Look-At matrix functions are DirectX implementations.
|
||||
//Left-handed: https://msdn.microsoft.com/en-us/library/windows/desktop/bb281710
|
||||
//Right-handed: https://msdn.microsoft.com/en-us/library/windows/desktop/bb281711
|
||||
C3D_FVec xaxis, yaxis, zaxis;
|
||||
|
||||
//Order of operations is crucial.
|
||||
if (isLeftHanded)
|
||||
zaxis = FVec3_Normalize(FVec3_Subtract(cameraTarget, cameraPosition));
|
||||
else
|
||||
zaxis = FVec3_Normalize(FVec3_Subtract(cameraPosition, cameraTarget));
|
||||
xaxis = FVec3_Normalize(FVec3_Cross(cameraUpVector, zaxis));
|
||||
yaxis = FVec3_Cross(zaxis, xaxis);
|
||||
|
||||
out->r[0].x = xaxis.x;
|
||||
out->r[0].y = xaxis.y;
|
||||
out->r[0].z = xaxis.z;
|
||||
out->r[0].w = -FVec3_Dot(xaxis, cameraPosition);
|
||||
|
||||
out->r[1].x = yaxis.x;
|
||||
out->r[1].y = yaxis.y;
|
||||
out->r[1].z = yaxis.z;
|
||||
out->r[1].w = -FVec3_Dot(yaxis, cameraPosition);
|
||||
|
||||
out->r[2].x = zaxis.x;
|
||||
out->r[2].y = zaxis.y;
|
||||
out->r[2].z = zaxis.z;
|
||||
out->r[2].w = -FVec3_Dot(zaxis, cameraPosition);
|
||||
|
||||
out->r[3].x = 0.0f;
|
||||
out->r[3].y = 0.0f;
|
||||
out->r[3].z = 0.0f;
|
||||
out->r[3].w = 1.0f;
|
||||
}
|
||||
19
libs/citro3d/source/maths/mtx_multiply.c
Normal file
19
libs/citro3d/source/maths/mtx_multiply.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Multiply(C3D_Mtx* out, const C3D_Mtx* a, const C3D_Mtx* b)
|
||||
{
|
||||
// if out is a or b, then we need to avoid overwriting them
|
||||
if(out == a || out == b)
|
||||
{
|
||||
C3D_Mtx tmp;
|
||||
Mtx_Multiply(&tmp, a, b);
|
||||
Mtx_Copy(out, &tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
// http://www.wolframalpha.com/input/?i={{a,b,c,d},{e,f,g,h},{i,j,k,l},{m,n,o,p}}{{α,β,γ,δ},{ε,θ,ι,κ},{λ,μ,ν,ξ},{ο,π,ρ,σ}}
|
||||
int i, j;
|
||||
for (j = 0; j < 4; ++j)
|
||||
for (i = 0; i < 4; ++i)
|
||||
out->r[j].c[i] = a->r[j].x*b->r[0].c[i] + a->r[j].y*b->r[1].c[i] + a->r[j].z*b->r[2].c[i] + a->r[j].w*b->r[3].c[i];
|
||||
}
|
||||
11
libs/citro3d/source/maths/mtx_multiplyfvec3.c
Normal file
11
libs/citro3d/source/maths/mtx_multiplyfvec3.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FVec Mtx_MultiplyFVec3(const C3D_Mtx* mtx, C3D_FVec v)
|
||||
{
|
||||
// http://www.wolframalpha.com/input/?i={{a,b,c},{d,e,f},{g,h,i}}{x,y,z}
|
||||
float x = FVec3_Dot(mtx->r[0], v);
|
||||
float y = FVec3_Dot(mtx->r[1], v);
|
||||
float z = FVec3_Dot(mtx->r[2], v);
|
||||
|
||||
return FVec3_New(x, y, z);
|
||||
}
|
||||
12
libs/citro3d/source/maths/mtx_multiplyfvec4.c
Normal file
12
libs/citro3d/source/maths/mtx_multiplyfvec4.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FVec Mtx_MultiplyFVec4(const C3D_Mtx* mtx, C3D_FVec v)
|
||||
{
|
||||
// http://www.wolframalpha.com/input/?i={{a,b,c,d},{e,f,g,h},{i,j,k,l},{m,n,o,p}}{x,y,z,w}
|
||||
float x = FVec4_Dot(mtx->r[0], v);
|
||||
float y = FVec4_Dot(mtx->r[1], v);
|
||||
float z = FVec4_Dot(mtx->r[2], v);
|
||||
float w = FVec4_Dot(mtx->r[3], v);
|
||||
|
||||
return FVec4_New(x, y, z, w);
|
||||
}
|
||||
20
libs/citro3d/source/maths/mtx_ortho.c
Normal file
20
libs/citro3d/source/maths/mtx_ortho.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Ortho(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far, bool isLeftHanded)
|
||||
{
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
// Standard orthogonal projection matrix, with a fixed depth range of [-1,0] (required by PICA)
|
||||
// http://www.wolframalpha.com/input/?i={{1,0,0,0},{0,1,0,0},{0,0,0.5,-0.5},{0,0,0,1}}{{2/(r-l),0,0,(l%2Br)/(l-r)},{0,2/(t-b),0,(b%2Bt)/(b-t)},{0,0,2/(n-f),(n%2Bf)/(n-f)},{0,0,0,1}}
|
||||
|
||||
mtx->r[0].x = 2.0f / (right - left);
|
||||
mtx->r[0].w = (left + right) / (left - right);
|
||||
mtx->r[1].y = 2.0f / (top - bottom);
|
||||
mtx->r[1].w = (bottom + top) / (bottom - top);
|
||||
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;
|
||||
}
|
||||
21
libs/citro3d/source/maths/mtx_orthotilt.c
Normal file
21
libs/citro3d/source/maths/mtx_orthotilt.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_OrthoTilt(C3D_Mtx* mtx, float left, float right, float bottom, float top, float near, float far, bool isLeftHanded)
|
||||
{
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
// Standard orthogonal projection matrix, with a fixed depth range of [-1,0] (required by PICA) and rotated τ/4 radians counterclockwise around the Z axis (due to 3DS screen orientation)
|
||||
// http://www.wolframalpha.com/input/?i={{0,1,0,0},{-1,0,0,0},{0,0,1,0},{0,0,0,1}}{{1,0,0,0},{0,1,0,0},{0,0,0.5,-0.5},{0,0,0,1}}
|
||||
// http://www.wolframalpha.com/input/?i={{0,1,0,0},{-1,0,0,0},{0,0,0.5,-0.5},{0,0,0,1}}{{2/(r-l),0,0,(l%2Br)/(l-r)},{0,2/(t-b),0,(b%2Bt)/(b-t)},{0,0,2/(n-f),(n%2Bf)/(n-f)},{0,0,0,1}}
|
||||
|
||||
mtx->r[0].y = 2.0f / (top - bottom);
|
||||
mtx->r[0].w = (bottom + top) / (bottom - top);
|
||||
mtx->r[1].x = 2.0f / (left - right);
|
||||
mtx->r[1].w = (left + right) / (right - left);
|
||||
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;
|
||||
}
|
||||
26
libs/citro3d/source/maths/mtx_persp.c
Normal file
26
libs/citro3d/source/maths/mtx_persp.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Persp(C3D_Mtx* mtx, float fovy, float aspect, float near, float far, bool isLeftHanded)
|
||||
{
|
||||
float fovy_tan = tanf(fovy/2.0f);
|
||||
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
// Standard perspective projection matrix, with a fixed depth range of [-1,0] (required by PICA)
|
||||
// http://www.wolframalpha.com/input/?i={{1,0,0,0},{0,1,0,0},{0,0,0.5,-0.5},{0,0,0,1}}{{1/(a*tan(v)),0,0,0},{0,1/tan(v),0,0},{0,0,(n%2Bf)/(n-f),(fn)/(n-f)},{0,0,0,-1}}
|
||||
|
||||
mtx->r[0].x = 1.0f / (aspect * fovy_tan);
|
||||
mtx->r[1].y = 1.0f / fovy_tan;
|
||||
mtx->r[2].w = far*near / (near - far);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
28
libs/citro3d/source/maths/mtx_perspstereo.c
Normal file
28
libs/citro3d/source/maths/mtx_perspstereo.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
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;
|
||||
float shift = iod / (2.0f*screen); // 'near' not in the numerator because it cancels out in mp.r[1].z
|
||||
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
mtx->r[0].x = 1.0f / fovy_tan_aspect;
|
||||
mtx->r[0].w = -iod / 2.0f;
|
||||
mtx->r[1].y = 1.0f / fovy_tan;
|
||||
mtx->r[2].w = near * far / (near - far);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
33
libs/citro3d/source/maths/mtx_perspstereotilt.c
Normal file
33
libs/citro3d/source/maths/mtx_perspstereotilt.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
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,
|
||||
// and the formula had to be tweaked. With stereo, left/right separation becomes top/bottom separation.
|
||||
// The detailed mathematical explanation is in mtx_persptilt.c.
|
||||
|
||||
float fovx_tan = tanf(fovx/2.0f);
|
||||
float fovx_tan_invaspect = fovx_tan*invaspect;
|
||||
float shift = iod / (2.0f*screen); // 'near' not in the numerator because it cancels out in mp.r[1].z
|
||||
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
mtx->r[0].y = 1.0f / fovx_tan;
|
||||
mtx->r[1].x = -1.0f / fovx_tan_invaspect;
|
||||
mtx->r[1].w = iod / 2.0f;
|
||||
mtx->r[2].w = near * far / (near - far);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
46
libs/citro3d/source/maths/mtx_persptilt.c
Normal file
46
libs/citro3d/source/maths/mtx_persptilt.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
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,
|
||||
// and so are these parameters -- in fact, they are actually the fovx and the inverse
|
||||
// of the aspect ratio. Therefore the formula for the perspective projection matrix
|
||||
// had to be modified to be expressed in these terms instead.
|
||||
|
||||
// Notes:
|
||||
// Includes adjusting depth range from [-1,1] to [-1,0]
|
||||
// Includes rotation of the matrix one quarter of a turn clockwise in order to fix the 3DS screens' orientation
|
||||
|
||||
// Notes:
|
||||
// fovx = 2 atan(tan(fovy/2)*w/h)
|
||||
// fovy = 2 atan(tan(fovx/2)*h/w)
|
||||
// invaspect = h/w
|
||||
|
||||
// a0,0 = h / (w*tan(fovy/2)) =
|
||||
// = h / (w*tan(2 atan(tan(fovx/2)*h/w) / 2)) =
|
||||
// = h / (w*tan( atan(tan(fovx/2)*h/w) )) =
|
||||
// = h / (w * tan(fovx/2)*h/w) =
|
||||
// = 1 / tan(fovx/2)
|
||||
|
||||
// a1,1 = 1 / tan(fovy/2) = (...) = w / (h*tan(fovx/2))
|
||||
|
||||
float fovx_tan = tanf(fovx/2.0f);
|
||||
|
||||
Mtx_Zeros(mtx);
|
||||
|
||||
mtx->r[0].y = 1.0f / fovx_tan;
|
||||
mtx->r[1].x = -1.0f / (fovx_tan*invaspect);
|
||||
mtx->r[2].w = far*near / (near - far);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
72
libs/citro3d/source/maths/mtx_rotate.c
Normal file
72
libs/citro3d/source/maths/mtx_rotate.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Rotate(C3D_Mtx* mtx, C3D_FVec axis, float angle, bool bRightSide)
|
||||
{
|
||||
size_t i;
|
||||
C3D_Mtx om;
|
||||
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
float t = 1.0f - c;
|
||||
|
||||
axis = FVec3_Normalize(axis);
|
||||
|
||||
float x = axis.x;
|
||||
float y = axis.y;
|
||||
float z = axis.z;
|
||||
float w;
|
||||
|
||||
om.r[0].x = t*x*x + c;
|
||||
om.r[1].x = t*x*y + s*z;
|
||||
om.r[2].x = t*x*z - s*y;
|
||||
//om.r[3].x = 0.0f; //optimized out
|
||||
|
||||
om.r[0].y = t*y*x - s*z;
|
||||
om.r[1].y = t*y*y + c;
|
||||
om.r[2].y = t*y*z + s*x;
|
||||
//om.r[3].y = 0.0f; //optimized out
|
||||
|
||||
om.r[0].z = t*z*x + s*y;
|
||||
om.r[1].z = t*z*y - s*x;
|
||||
om.r[2].z = t*z*z + c;
|
||||
//om.r[3].z = 0.0f; //optimized out
|
||||
|
||||
/* optimized out
|
||||
om.r[0].w = 0.0f;
|
||||
om.r[1].w = 0.0f;
|
||||
om.r[2].w = 0.0f;
|
||||
om.r[3].w = 1.0f;
|
||||
*/
|
||||
|
||||
if (bRightSide)
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
x = mtx->r[i].x*om.r[0].x + mtx->r[i].y*om.r[1].x + mtx->r[i].z*om.r[2].x;
|
||||
y = mtx->r[i].x*om.r[0].y + mtx->r[i].y*om.r[1].y + mtx->r[i].z*om.r[2].y;
|
||||
z = mtx->r[i].x*om.r[0].z + mtx->r[i].y*om.r[1].z + mtx->r[i].z*om.r[2].z;
|
||||
|
||||
mtx->r[i].x = x;
|
||||
mtx->r[i].y = y;
|
||||
mtx->r[i].z = z;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
x = mtx->r[0].x*om.r[i].x + mtx->r[1].x*om.r[i].y + mtx->r[2].x*om.r[i].z;
|
||||
y = mtx->r[0].y*om.r[i].x + mtx->r[1].y*om.r[i].y + mtx->r[2].y*om.r[i].z;
|
||||
z = mtx->r[0].z*om.r[i].x + mtx->r[1].z*om.r[i].y + mtx->r[2].z*om.r[i].z;
|
||||
w = mtx->r[0].w*om.r[i].x + mtx->r[1].w*om.r[i].y + mtx->r[2].w*om.r[i].z;
|
||||
|
||||
om.r[i].x = x;
|
||||
om.r[i].y = y;
|
||||
om.r[i].z = z;
|
||||
om.r[i].w = w;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
mtx->r[i] = om.r[i];
|
||||
}
|
||||
}
|
||||
30
libs/citro3d/source/maths/mtx_rotatex.c
Normal file
30
libs/citro3d/source/maths/mtx_rotatex.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_RotateX(C3D_Mtx* mtx, float angle, bool bRightSide)
|
||||
{
|
||||
float a, b;
|
||||
float cosAngle = cosf(angle);
|
||||
float sinAngle = sinf(angle);
|
||||
size_t i;
|
||||
|
||||
if (bRightSide)
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
a = mtx->r[i].y*cosAngle + mtx->r[i].z*sinAngle;
|
||||
b = mtx->r[i].z*cosAngle - mtx->r[i].y*sinAngle;
|
||||
mtx->r[i].y = a;
|
||||
mtx->r[i].z = b;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
a = mtx->r[1].c[i]*cosAngle - mtx->r[2].c[i]*sinAngle;
|
||||
b = mtx->r[2].c[i]*cosAngle + mtx->r[1].c[i]*sinAngle;
|
||||
mtx->r[1].c[i] = a;
|
||||
mtx->r[2].c[i] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
libs/citro3d/source/maths/mtx_rotatey.c
Normal file
30
libs/citro3d/source/maths/mtx_rotatey.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_RotateY(C3D_Mtx* mtx, float angle, bool bRightSide)
|
||||
{
|
||||
float a, b;
|
||||
float cosAngle = cosf(angle);
|
||||
float sinAngle = sinf(angle);
|
||||
size_t i;
|
||||
|
||||
if (bRightSide)
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
a = mtx->r[i].x*cosAngle - mtx->r[i].z*sinAngle;
|
||||
b = mtx->r[i].z*cosAngle + mtx->r[i].x*sinAngle;
|
||||
mtx->r[i].x = a;
|
||||
mtx->r[i].z = b;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
a = mtx->r[0].c[i]*cosAngle + mtx->r[2].c[i]*sinAngle;
|
||||
b = mtx->r[2].c[i]*cosAngle - mtx->r[0].c[i]*sinAngle;
|
||||
mtx->r[0].c[i] = a;
|
||||
mtx->r[2].c[i] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
libs/citro3d/source/maths/mtx_rotatez.c
Normal file
30
libs/citro3d/source/maths/mtx_rotatez.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_RotateZ(C3D_Mtx* mtx, float angle, bool bRightSide)
|
||||
{
|
||||
float a, b;
|
||||
float cosAngle = cosf(angle);
|
||||
float sinAngle = sinf(angle);
|
||||
size_t i;
|
||||
|
||||
if (bRightSide)
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
a = mtx->r[i].x*cosAngle + mtx->r[i].y*sinAngle;
|
||||
b = mtx->r[i].y*cosAngle - mtx->r[i].x*sinAngle;
|
||||
mtx->r[i].x = a;
|
||||
mtx->r[i].y = b;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
a = mtx->r[0].c[i]*cosAngle - mtx->r[1].c[i]*sinAngle;
|
||||
b = mtx->r[1].c[i]*cosAngle + mtx->r[0].c[i]*sinAngle;
|
||||
mtx->r[0].c[i] = a;
|
||||
mtx->r[1].c[i] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
libs/citro3d/source/maths/mtx_scale.c
Normal file
12
libs/citro3d/source/maths/mtx_scale.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Scale(C3D_Mtx* mtx, float x, float y, float z)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
mtx->r[i].x *= x;
|
||||
mtx->r[i].y *= y;
|
||||
mtx->r[i].z *= z;
|
||||
}
|
||||
}
|
||||
21
libs/citro3d/source/maths/mtx_translate.c
Normal file
21
libs/citro3d/source/maths/mtx_translate.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
void Mtx_Translate(C3D_Mtx* mtx, float x, float y, float z, bool bRightSide)
|
||||
{
|
||||
|
||||
C3D_FVec v = FVec4_New(x, y, z, 1.0f);
|
||||
int i, j;
|
||||
|
||||
if (bRightSide)
|
||||
{
|
||||
for (i = 0; i < 4; ++i)
|
||||
mtx->r[i].w = FVec4_Dot(mtx->r[i], v);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < 3; ++j)
|
||||
for (i = 0; i < 4; ++i)
|
||||
mtx->r[j].c[i] += mtx->r[3].c[i] * v.c[3-j];
|
||||
}
|
||||
|
||||
}
|
||||
13
libs/citro3d/source/maths/quat_crossfvec3.c
Normal file
13
libs/citro3d/source/maths/quat_crossfvec3.c
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FVec Quat_CrossFVec3(C3D_FQuat q, C3D_FVec v)
|
||||
{
|
||||
C3D_FVec qv = FVec3_New(q.i, q.j, q.k);
|
||||
C3D_FVec uv = FVec3_Cross(qv, v);
|
||||
C3D_FVec uuv = FVec3_Cross(qv, uv);
|
||||
|
||||
uv = FVec3_Scale(uv, 2.0f * q.r);
|
||||
uuv = FVec3_Scale(uuv, 2.0f);
|
||||
|
||||
return FVec3_Add(v, FVec3_Add(uv, uuv));
|
||||
}
|
||||
11
libs/citro3d/source/maths/quat_multiply.c
Normal file
11
libs/citro3d/source/maths/quat_multiply.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FQuat Quat_Multiply(C3D_FQuat lhs, C3D_FQuat rhs)
|
||||
{
|
||||
float i = lhs.r*rhs.i + lhs.i*rhs.r + lhs.j*rhs.k - lhs.k*rhs.j;
|
||||
float j = lhs.r*rhs.j + lhs.j*rhs.r + lhs.k*rhs.i - lhs.i*rhs.k;
|
||||
float k = lhs.r*rhs.k + lhs.k*rhs.r + lhs.i*rhs.j - lhs.j*rhs.i;
|
||||
float r = lhs.r*rhs.r - lhs.i*rhs.i - lhs.j*rhs.j - lhs.k*rhs.k;
|
||||
|
||||
return Quat_New(i, j, k, r);
|
||||
}
|
||||
23
libs/citro3d/source/maths/quat_pow.c
Normal file
23
libs/citro3d/source/maths/quat_pow.c
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#include <float.h>
|
||||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FQuat Quat_Pow(C3D_FQuat q, float p)
|
||||
{
|
||||
// if the power is very near to zero, return the identity quaternion to avoid blowing up with division
|
||||
if (p > -FLT_EPSILON && p < FLT_EPSILON)
|
||||
return Quat_Identity();
|
||||
|
||||
float mag = FVec4_Magnitude(q);
|
||||
|
||||
// if the magnitude is very near to one, this is equivalent to raising the real component by the power
|
||||
// also, acosf(1) == 0 and sinf(0) == 0 so you would get a divide-by-zero anyway
|
||||
if (fabsf(q.r / mag) > 1.0f - FLT_EPSILON && fabsf(q.r / mag) < 1.0f + FLT_EPSILON)
|
||||
return Quat_New(0.0f, 0.0f, 0.0f, powf(q.r, p));
|
||||
|
||||
float angle = acosf(q.r / mag);
|
||||
float newAngle = angle * p;
|
||||
float div = sinf(newAngle) / sinf(angle);
|
||||
float Mag = powf(mag, p - 1.0f);
|
||||
|
||||
return Quat_New(q.i*div*Mag, q.j*div*Mag, q.k*div*Mag, cosf(newAngle)*mag*Mag);
|
||||
}
|
||||
16
libs/citro3d/source/maths/quat_rotate.c
Normal file
16
libs/citro3d/source/maths/quat_rotate.c
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FQuat Quat_Rotate(C3D_FQuat q, C3D_FVec axis, float r, bool bRightSide)
|
||||
{
|
||||
float halfAngle = r/2.0f;
|
||||
float s = sinf(halfAngle);
|
||||
|
||||
axis = FVec3_Normalize(axis);
|
||||
|
||||
C3D_FQuat tmp = Quat_New(axis.x*s, axis.y*s, axis.z*s, cosf(halfAngle));
|
||||
|
||||
if (bRightSide)
|
||||
return Quat_Multiply(tmp, q);
|
||||
else
|
||||
return Quat_Multiply(q, tmp);
|
||||
}
|
||||
12
libs/citro3d/source/maths/quat_rotatex.c
Normal file
12
libs/citro3d/source/maths/quat_rotatex.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FQuat Quat_RotateX(C3D_FQuat q, float r, bool bRightSide)
|
||||
{
|
||||
float c = cosf(r/2.0f);
|
||||
float s = sinf(r/2.0f);
|
||||
|
||||
if (bRightSide)
|
||||
return Quat_New(q.r*s + q.i*c, q.j*c - q.k*s, q.k*c + q.j*s, q.r*c - q.i*s);
|
||||
else
|
||||
return Quat_New(q.r*s + q.i*c, q.j*c + q.k*s, q.k*c - q.j*s, q.r*c - q.i*s);
|
||||
}
|
||||
12
libs/citro3d/source/maths/quat_rotatey.c
Normal file
12
libs/citro3d/source/maths/quat_rotatey.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FQuat Quat_RotateY(C3D_FQuat q, float r, bool bRightSide)
|
||||
{
|
||||
float c = cosf(r/2.0f);
|
||||
float s = sinf(r/2.0f);
|
||||
|
||||
if (bRightSide)
|
||||
return Quat_New(q.i*c + q.k*s, q.r*s + q.j*c, q.k*c - q.i*s, q.r*c - q.j*s);
|
||||
else
|
||||
return Quat_New(q.i*c - q.k*s, q.r*s + q.j*c, q.k*c + q.i*s, q.r*c - q.j*s);
|
||||
}
|
||||
12
libs/citro3d/source/maths/quat_rotatez.c
Normal file
12
libs/citro3d/source/maths/quat_rotatez.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <c3d/maths.h>
|
||||
|
||||
C3D_FQuat Quat_RotateZ(C3D_FQuat q, float r, bool bRightSide)
|
||||
{
|
||||
float c = cosf(r/2.0f);
|
||||
float s = sinf(r/2.0f);
|
||||
|
||||
if (bRightSide)
|
||||
return Quat_New(q.i*c - q.j*s, q.j*c + q.i*s, q.r*s + q.k*c, q.r*c - q.k*s);
|
||||
else
|
||||
return Quat_New(q.i*c + q.j*s, q.j*c - q.i*s, q.r*s + q.k*c, q.r*c - q.k*s);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue