aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/alu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/alu.cpp')
-rw-r--r--Alc/alu.cpp162
1 files changed, 64 insertions, 98 deletions
diff --git a/Alc/alu.cpp b/Alc/alu.cpp
index 37d23c60..75504af5 100644
--- a/Alc/alu.cpp
+++ b/Alc/alu.cpp
@@ -260,50 +260,30 @@ inline ALuint dither_rng(ALuint *seed) noexcept
}
-inline void aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector)
+inline alu::Vector aluCrossproduct(const alu::Vector &in1, const alu::Vector &in2)
{
- outVector[0] = inVector1[1]*inVector2[2] - inVector1[2]*inVector2[1];
- outVector[1] = inVector1[2]*inVector2[0] - inVector1[0]*inVector2[2];
- outVector[2] = inVector1[0]*inVector2[1] - inVector1[1]*inVector2[0];
+ return alu::Vector{
+ in1[1]*in2[2] - in1[2]*in2[1],
+ in1[2]*in2[0] - in1[0]*in2[2],
+ in1[0]*in2[1] - in1[1]*in2[0],
+ 0.0f
+ };
}
-inline ALfloat aluDotproduct(const aluVector *vec1, const aluVector *vec2)
+inline ALfloat aluDotproduct(const alu::Vector &vec1, const alu::Vector &vec2)
{
- return vec1->v[0]*vec2->v[0] + vec1->v[1]*vec2->v[1] + vec1->v[2]*vec2->v[2];
+ return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
}
-ALfloat aluNormalize(ALfloat *vec)
-{
- const ALfloat length{std::sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2])};
- if(length > FLT_EPSILON)
- {
- ALfloat inv_length = 1.0f/length;
- vec[0] *= inv_length;
- vec[1] *= inv_length;
- vec[2] *= inv_length;
- return length;
- }
- vec[0] = vec[1] = vec[2] = 0.0f;
- return 0.0f;
-}
-void aluMatrixfFloat3(ALfloat *vec, ALfloat w, const aluMatrixf *mtx)
+alu::Vector operator*(const alu::Matrix &mtx, const alu::Vector &vec) noexcept
{
- const ALfloat v[4]{ vec[0], vec[1], vec[2], w };
-
- vec[0] = v[0]*mtx->m[0][0] + v[1]*mtx->m[1][0] + v[2]*mtx->m[2][0] + v[3]*mtx->m[3][0];
- vec[1] = v[0]*mtx->m[0][1] + v[1]*mtx->m[1][1] + v[2]*mtx->m[2][1] + v[3]*mtx->m[3][1];
- vec[2] = v[0]*mtx->m[0][2] + v[1]*mtx->m[1][2] + v[2]*mtx->m[2][2] + v[3]*mtx->m[3][2];
-}
-
-aluVector aluMatrixfVector(const aluMatrixf *mtx, const aluVector *vec)
-{
- aluVector v;
- v.v[0] = vec->v[0]*mtx->m[0][0] + vec->v[1]*mtx->m[1][0] + vec->v[2]*mtx->m[2][0] + vec->v[3]*mtx->m[3][0];
- v.v[1] = vec->v[0]*mtx->m[0][1] + vec->v[1]*mtx->m[1][1] + vec->v[2]*mtx->m[2][1] + vec->v[3]*mtx->m[3][1];
- v.v[2] = vec->v[0]*mtx->m[0][2] + vec->v[1]*mtx->m[1][2] + vec->v[2]*mtx->m[2][2] + vec->v[3]*mtx->m[3][2];
- v.v[3] = vec->v[0]*mtx->m[0][3] + vec->v[1]*mtx->m[1][3] + vec->v[2]*mtx->m[2][3] + vec->v[3]*mtx->m[3][3];
- return v;
+ return alu::Vector{
+ vec[0]*mtx[0][0] + vec[1]*mtx[1][0] + vec[2]*mtx[2][0] + vec[3]*mtx[3][0],
+ vec[0]*mtx[0][1] + vec[1]*mtx[1][1] + vec[2]*mtx[2][1] + vec[3]*mtx[3][1],
+ vec[0]*mtx[0][2] + vec[1]*mtx[1][2] + vec[2]*mtx[2][2] + vec[3]*mtx[3][2],
+ vec[0]*mtx[0][3] + vec[1]*mtx[1][3] + vec[2]*mtx[2][3] + vec[3]*mtx[3][3]
+ };
}
@@ -350,29 +330,27 @@ bool CalcListenerParams(ALCcontext *Context)
if(!props) return false;
/* AT then UP */
- ALfloat N[3]{ props->Forward[0], props->Forward[1], props->Forward[2] };
- aluNormalize(N);
- ALfloat V[3]{ props->Up[0], props->Up[1], props->Up[2] };
- aluNormalize(V);
+ alu::Vector N{props->Forward[0], props->Forward[1], props->Forward[2], 0.0f};
+ N.normalize();
+ alu::Vector V{props->Up[0], props->Up[1], props->Up[2], 0.0f};
+ V.normalize();
/* Build and normalize right-vector */
- ALfloat U[3];
- aluCrossproduct(N, V, U);
- aluNormalize(U);
-
- aluMatrixfSet(&Listener.Params.Matrix,
- U[0], V[0], -N[0], 0.0,
- U[1], V[1], -N[1], 0.0,
- U[2], V[2], -N[2], 0.0,
- 0.0, 0.0, 0.0, 1.0
- );
+ alu::Vector U{aluCrossproduct(N, V)};
+ U.normalize();
+
+ Listener.Params.Matrix = alu::Matrix{
+ U[0], V[0], -N[0], 0.0f,
+ U[1], V[1], -N[1], 0.0f,
+ U[2], V[2], -N[2], 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ };
- ALfloat P[3]{ props->Position[0], props->Position[1], props->Position[2] };
- aluMatrixfFloat3(P, 1.0, &Listener.Params.Matrix);
- aluMatrixfSetRow(&Listener.Params.Matrix, 3, -P[0], -P[1], -P[2], 1.0f);
+ alu::Vector P{props->Position[0], props->Position[1], props->Position[2], 1.0f};
+ P = Listener.Params.Matrix * P;
+ Listener.Params.Matrix.setRow(3, -P[0], -P[1], -P[2], 1.0f);
- aluVector vel;
- aluVectorSet(&vel, props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f);
- Listener.Params.Velocity = aluMatrixfVector(&Listener.Params.Matrix, &vel);
+ alu::Vector vel{props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f};
+ Listener.Params.Velocity = Listener.Params.Matrix * vel;
Listener.Params.Gain = props->Gain * Context->GainBoost;
@@ -666,46 +644,43 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat Azi, const ALfloat Elev
* to the orientation.
*/
/* AT then UP */
- ALfloat N[3]{ props->Orientation[0][0], props->Orientation[0][1],
- props->Orientation[0][2] };
- aluNormalize(N);
- ALfloat V[3]{ props->Orientation[1][0], props->Orientation[1][1],
- props->Orientation[1][2] };
- aluNormalize(V);
+ alu::Vector N{props->Orientation[0][0], props->Orientation[0][1],
+ props->Orientation[0][2], 0.0f};
+ N.normalize();
+ alu::Vector V{props->Orientation[1][0], props->Orientation[1][1],
+ props->Orientation[1][2], 0.0f};
+ V.normalize();
if(!props->HeadRelative)
{
- const aluMatrixf *lmatrix = &Listener.Params.Matrix;
- aluMatrixfFloat3(N, 0.0f, lmatrix);
- aluMatrixfFloat3(V, 0.0f, lmatrix);
+ N = Listener.Params.Matrix * N;
+ V = Listener.Params.Matrix * V;
}
/* Build and normalize right-vector */
- ALfloat U[3];
- aluCrossproduct(N, V, U);
- aluNormalize(U);
+ alu::Vector U{aluCrossproduct(N, V)};
+ U.normalize();
/* Build a rotate + conversion matrix (FuMa -> ACN+N3D). NOTE: This
* matrix is transposed, for the inputs to align on the rows and
* outputs on the columns.
*/
- aluMatrixf matrix;
- aluMatrixfSet(&matrix,
+ const alu::Matrix matrix{
// ACN0 ACN1 ACN2 ACN3
SQRTF_2, 0.0f, 0.0f, 0.0f, // Ambi W
0.0f, -N[0]*SQRTF_3, N[1]*SQRTF_3, -N[2]*SQRTF_3, // Ambi X
0.0f, U[0]*SQRTF_3, -U[1]*SQRTF_3, U[2]*SQRTF_3, // Ambi Y
0.0f, -V[0]*SQRTF_3, V[1]*SQRTF_3, -V[2]*SQRTF_3 // Ambi Z
- );
+ };
voice->Direct.Buffer = Device->FOAOut.Buffer;
voice->Direct.Channels = Device->FOAOut.NumChannels;
for(ALsizei c{0};c < num_channels;c++)
- ComputePanGains(&Device->FOAOut, matrix.m[c], DryGain,
+ ComputePanGains(&Device->FOAOut, matrix[c].data(), DryGain,
voice->Direct.Params[c].Gains.Target);
for(ALsizei i{0};i < NumSends;i++)
{
if(const ALeffectslot *Slot{SendSlots[i]})
for(ALsizei c{0};c < num_channels;c++)
- ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, matrix.m[c],
+ ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, matrix[c].data(),
WetGain[i], voice->Send[i].Params[c].Gains.Target
);
}
@@ -1125,34 +1100,25 @@ void CalcAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const A
}
/* Transform source to listener space (convert to head relative) */
- aluVector Position, Velocity, Direction;
- aluVectorSet(&Position, props->Position[0], props->Position[1], props->Position[2], 1.0f);
- aluVectorSet(&Direction, props->Direction[0], props->Direction[1], props->Direction[2], 0.0f);
- aluVectorSet(&Velocity, props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f);
+ alu::Vector Position{props->Position[0], props->Position[1], props->Position[2], 1.0f};
+ alu::Vector Velocity{props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f};
+ alu::Vector Direction{props->Direction[0], props->Direction[1], props->Direction[2], 0.0f};
if(props->HeadRelative == AL_FALSE)
{
- const aluMatrixf *Matrix = &Listener.Params.Matrix;
/* Transform source vectors */
- Position = aluMatrixfVector(Matrix, &Position);
- Velocity = aluMatrixfVector(Matrix, &Velocity);
- Direction = aluMatrixfVector(Matrix, &Direction);
+ Position = Listener.Params.Matrix * Position;
+ Velocity = Listener.Params.Matrix * Velocity;
+ Direction = Listener.Params.Matrix * Direction;
}
else
{
- const aluVector *lvelocity = &Listener.Params.Velocity;
/* Offset the source velocity to be relative of the listener velocity */
- Velocity.v[0] += lvelocity->v[0];
- Velocity.v[1] += lvelocity->v[1];
- Velocity.v[2] += lvelocity->v[2];
+ Velocity += Listener.Params.Velocity;
}
- bool directional{aluNormalize(Direction.v) > 0.0f};
- aluVector SourceToListener;
- SourceToListener.v[0] = -Position.v[0];
- SourceToListener.v[1] = -Position.v[1];
- SourceToListener.v[2] = -Position.v[2];
- SourceToListener.v[3] = 0.0f;
- ALfloat Distance{aluNormalize(SourceToListener.v)};
+ const bool directional{Direction.normalize() > 0.0f};
+ alu::Vector SourceToListener{-Position[0], -Position[1], -Position[2], 0.0f};
+ const ALfloat Distance{SourceToListener.normalize()};
/* Initial source gain */
ALfloat DryGain{props->Gain};
@@ -1235,7 +1201,7 @@ void CalcAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const A
/* Calculate directional soundcones */
if(directional && props->InnerAngle < 360.0f)
{
- ALfloat Angle{std::acos(aluDotproduct(&Direction, &SourceToListener))};
+ ALfloat Angle{std::acos(aluDotproduct(Direction, SourceToListener))};
Angle = RAD2DEG(Angle * ConeScale * 2.0f);
ALfloat ConeVolume, ConeHF;
@@ -1334,9 +1300,9 @@ void CalcAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const A
ALfloat DopplerFactor{props->DopplerFactor * Listener.Params.DopplerFactor};
if(DopplerFactor > 0.0f)
{
- const aluVector *lvelocity = &Listener.Params.Velocity;
- ALfloat vss{aluDotproduct(&Velocity, &SourceToListener) * DopplerFactor};
- ALfloat vls{aluDotproduct(lvelocity, &SourceToListener) * DopplerFactor};
+ const alu::Vector &lvelocity = Listener.Params.Velocity;
+ ALfloat vss{aluDotproduct(Velocity, SourceToListener) * DopplerFactor};
+ ALfloat vls{aluDotproduct(lvelocity, SourceToListener) * DopplerFactor};
const ALfloat SpeedOfSound{Listener.Params.SpeedOfSound};
if(!(vls < SpeedOfSound))
@@ -1382,12 +1348,12 @@ void CalcAttnSourceParams(ALvoice *voice, const ALvoicePropsBase *props, const A
/* Clamp Y, in case rounding errors caused it to end up outside of
* -1...+1.
*/
- ev = std::asin(clampf(-SourceToListener.v[1], -1.0f, 1.0f));
+ ev = std::asin(clampf(-SourceToListener[1], -1.0f, 1.0f));
/* Double negation on Z cancels out; negate once for changing source-
* to-listener to listener-to-source, and again for right-handed coords
* with -Z in front.
*/
- az = std::atan2(-SourceToListener.v[0], SourceToListener.v[2]*ZScale);
+ az = std::atan2(-SourceToListener[0], SourceToListener[2]*ZScale);
}
ALfloat spread{0.0f};