Use proper classes for Vector and Matrix types
This commit is contained in:
+2
-2
@@ -2425,8 +2425,8 @@ static ALvoid InitContext(ALCcontext *Context)
|
||||
Context->ExtensionList = alExtList;
|
||||
|
||||
|
||||
listener.Params.Matrix = aluMatrixf::Identity;
|
||||
aluVectorSet(&listener.Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
listener.Params.Matrix = alu::Matrix::Identity();
|
||||
listener.Params.Velocity = alu::Vector{};
|
||||
listener.Params.Gain = listener.Gain;
|
||||
listener.Params.MetersPerUnit = Context->MetersPerUnit;
|
||||
listener.Params.DopplerFactor = Context->DopplerFactor;
|
||||
|
||||
+63
-97
@@ -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);
|
||||
alu::Vector U{aluCrossproduct(N, V)};
|
||||
U.normalize();
|
||||
|
||||
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
|
||||
);
|
||||
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};
|
||||
|
||||
@@ -122,7 +122,7 @@ void ALautowahState::update(const ALCcontext *context, const ALeffectslot *slot,
|
||||
mOutBuffer = device->FOAOut.Buffer;
|
||||
mOutChannels = device->FOAOut.NumChannels;
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
|
||||
ComputePanGains(&device->FOAOut, alu::Matrix::Identity()[i].data(), slot->Params.Gain,
|
||||
mChans[i].TargetGains);
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,8 @@ void ALcompressorState::update(const ALCcontext *context, const ALeffectslot *sl
|
||||
mOutBuffer = device->FOAOut.Buffer;
|
||||
mOutChannels = device->FOAOut.NumChannels;
|
||||
for(ALsizei i{0};i < 4;i++)
|
||||
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain, mGain[i]);
|
||||
ComputePanGains(&device->FOAOut, alu::Matrix::Identity()[i].data(),
|
||||
slot->Params.Gain, mGain[i]);
|
||||
}
|
||||
|
||||
void ALcompressorState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesIn)[BUFFERSIZE], ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
|
||||
|
||||
@@ -155,7 +155,7 @@ void ALequalizerState::update(const ALCcontext *context, const ALeffectslot *slo
|
||||
mOutBuffer = device->FOAOut.Buffer;
|
||||
mOutChannels = device->FOAOut.NumChannels;
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
|
||||
ComputePanGains(&device->FOAOut, alu::Matrix::Identity()[i].data(), slot->Params.Gain,
|
||||
mChans[i].TargetGains);
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ void ALmodulatorState::update(const ALCcontext *context, const ALeffectslot *slo
|
||||
mOutBuffer = device->FOAOut.Buffer;
|
||||
mOutChannels = device->FOAOut.NumChannels;
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&device->FOAOut, aluMatrixf::Identity.m[i], slot->Params.Gain,
|
||||
ComputePanGains(&device->FOAOut, alu::Matrix::Identity()[i].data(), slot->Params.Gain,
|
||||
mChans[i].TargetGains);
|
||||
}
|
||||
|
||||
|
||||
+38
-44
@@ -68,20 +68,20 @@ ALfloat ReverbBoost = 1.0f;
|
||||
* tetrahedron, but it's close enough. Should the model be extended to 8-lines
|
||||
* in the future, true opposites can be used.
|
||||
*/
|
||||
static const aluMatrixf B2A = {{
|
||||
{ 0.288675134595f, 0.288675134595f, 0.288675134595f, 0.288675134595f },
|
||||
{ 0.288675134595f, -0.288675134595f, -0.288675134595f, 0.288675134595f },
|
||||
{ 0.288675134595f, 0.288675134595f, -0.288675134595f, -0.288675134595f },
|
||||
{ 0.288675134595f, -0.288675134595f, 0.288675134595f, -0.288675134595f }
|
||||
}};
|
||||
static constexpr alu::Matrix B2A{
|
||||
0.288675134595f, 0.288675134595f, 0.288675134595f, 0.288675134595f,
|
||||
0.288675134595f, -0.288675134595f, -0.288675134595f, 0.288675134595f,
|
||||
0.288675134595f, 0.288675134595f, -0.288675134595f, -0.288675134595f,
|
||||
0.288675134595f, -0.288675134595f, 0.288675134595f, -0.288675134595f
|
||||
};
|
||||
|
||||
/* Converts A-Format to B-Format. */
|
||||
static const aluMatrixf A2B = {{
|
||||
{ 0.866025403785f, 0.866025403785f, 0.866025403785f, 0.866025403785f },
|
||||
{ 0.866025403785f, -0.866025403785f, 0.866025403785f, -0.866025403785f },
|
||||
{ 0.866025403785f, -0.866025403785f, -0.866025403785f, 0.866025403785f },
|
||||
{ 0.866025403785f, 0.866025403785f, -0.866025403785f, -0.866025403785f }
|
||||
}};
|
||||
static constexpr alu::Matrix A2B{
|
||||
0.866025403785f, 0.866025403785f, 0.866025403785f, 0.866025403785f,
|
||||
0.866025403785f, -0.866025403785f, 0.866025403785f, -0.866025403785f,
|
||||
0.866025403785f, -0.866025403785f, -0.866025403785f, 0.866025403785f,
|
||||
0.866025403785f, 0.866025403785f, -0.866025403785f, -0.866025403785f
|
||||
};
|
||||
|
||||
static const ALfloat FadeStep = 1.0f / FADE_SAMPLES;
|
||||
|
||||
@@ -755,12 +755,8 @@ static ALvoid UpdateLateLines(const ALfloat density, const ALfloat diffusion, co
|
||||
* focal strength. This function results in a B-Format transformation matrix
|
||||
* that spatially focuses the signal in the desired direction.
|
||||
*/
|
||||
static aluMatrixf GetTransformFromVector(const ALfloat *vec)
|
||||
static alu::Matrix GetTransformFromVector(const ALfloat *vec)
|
||||
{
|
||||
aluMatrixf focus;
|
||||
ALfloat norm[3];
|
||||
ALfloat mag;
|
||||
|
||||
/* Normalize the panning vector according to the N3D scale, which has an
|
||||
* extra sqrt(3) term on the directional components. Converting from OpenAL
|
||||
* to B-Format also requires negating X (ACN 1) and Z (ACN 3). Note however
|
||||
@@ -768,7 +764,8 @@ static aluMatrixf GetTransformFromVector(const ALfloat *vec)
|
||||
* rest of OpenAL which use right-handed. This is fixed by negating Z,
|
||||
* which cancels out with the B-Format Z negation.
|
||||
*/
|
||||
mag = sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
|
||||
ALfloat norm[3];
|
||||
ALfloat mag{sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2])};
|
||||
if(mag > 1.0f)
|
||||
{
|
||||
norm[0] = vec[0] / mag * -SQRTF_3;
|
||||
@@ -787,50 +784,47 @@ static aluMatrixf GetTransformFromVector(const ALfloat *vec)
|
||||
norm[2] = vec[2] * SQRTF_3;
|
||||
}
|
||||
|
||||
aluMatrixfSet(&focus,
|
||||
return alu::Matrix{
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
norm[0], 1.0f-mag, 0.0f, 0.0f,
|
||||
norm[1], 0.0f, 1.0f-mag, 0.0f,
|
||||
norm[2], 0.0f, 0.0f, 1.0f-mag
|
||||
);
|
||||
|
||||
return focus;
|
||||
};
|
||||
}
|
||||
|
||||
/* Update the early and late 3D panning gains. */
|
||||
static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, const ALfloat earlyGain, const ALfloat lateGain, ReverbState *State)
|
||||
{
|
||||
aluMatrixf transform, rot;
|
||||
ALsizei i;
|
||||
|
||||
State->mOutBuffer = Device->FOAOut.Buffer;
|
||||
State->mOutChannels = Device->FOAOut.NumChannels;
|
||||
|
||||
/* Note: _res is transposed. */
|
||||
#define MATRIX_MULT(_res, _m1, _m2) do { \
|
||||
int row, col; \
|
||||
for(col = 0;col < 4;col++) \
|
||||
{ \
|
||||
for(row = 0;row < 4;row++) \
|
||||
_res.m[col][row] = _m1.m[row][0]*_m2.m[0][col] + _m1.m[row][1]*_m2.m[1][col] + \
|
||||
_m1.m[row][2]*_m2.m[2][col] + _m1.m[row][3]*_m2.m[3][col]; \
|
||||
} \
|
||||
} while(0)
|
||||
/* Note: ret is transposed. */
|
||||
auto MatrixMult = [](const alu::Matrix &m1, const alu::Matrix &m2) noexcept -> alu::Matrix
|
||||
{
|
||||
alu::Matrix ret;
|
||||
for(int col{0};col < 4;col++)
|
||||
{
|
||||
for(int row{0};row < 4;row++)
|
||||
ret[col][row] = m1[row][0]*m2[0][col] + m1[row][1]*m2[1][col] +
|
||||
m1[row][2]*m2[2][col] + m1[row][3]*m2[3][col];
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/* Create a matrix that first converts A-Format to B-Format, then
|
||||
* transforms the B-Format signal according to the panning vector.
|
||||
*/
|
||||
rot = GetTransformFromVector(ReflectionsPan);
|
||||
MATRIX_MULT(transform, rot, A2B);
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&Device->FOAOut, transform.m[i], earlyGain,
|
||||
alu::Matrix rot{GetTransformFromVector(ReflectionsPan)};
|
||||
alu::Matrix transform{MatrixMult(rot, A2B)};
|
||||
for(ALsizei i{0};i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&Device->FOAOut, transform[i].data(), earlyGain,
|
||||
State->mEarly.PanGain[i]);
|
||||
|
||||
rot = GetTransformFromVector(LateReverbPan);
|
||||
MATRIX_MULT(transform, rot, A2B);
|
||||
for(i = 0;i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&Device->FOAOut, transform.m[i], lateGain,
|
||||
transform = MatrixMult(rot, A2B);
|
||||
for(ALsizei i{0};i < MAX_EFFECT_CHANNELS;i++)
|
||||
ComputePanGains(&Device->FOAOut, transform[i].data(), lateGain,
|
||||
State->mLate.PanGain[i]);
|
||||
#undef MATRIX_MULT
|
||||
}
|
||||
|
||||
void ReverbState::update(const ALCcontext *Context, const ALeffectslot *Slot, const ALeffectProps *props)
|
||||
@@ -1380,7 +1374,7 @@ void ReverbState::process(ALsizei SamplesToDo, const ALfloat (*RESTRICT SamplesI
|
||||
for(c = 0;c < NUM_LINES;c++)
|
||||
{
|
||||
std::fill(std::begin(afmt[c]), std::end(afmt[c]), 0.0f);
|
||||
MixRowSamples(afmt[c], B2A.m[c],
|
||||
MixRowSamples(afmt[c], B2A[c].data(),
|
||||
SamplesIn, MAX_EFFECT_CHANNELS, base, todo
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ struct ALlistener {
|
||||
std::atomic<ALlistenerProps*> Update{nullptr};
|
||||
|
||||
struct {
|
||||
aluMatrixf Matrix;
|
||||
aluVector Velocity;
|
||||
alu::Matrix Matrix;
|
||||
alu::Vector Velocity;
|
||||
|
||||
ALfloat Gain;
|
||||
ALfloat MetersPerUnit;
|
||||
|
||||
@@ -2,11 +2,3 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "vecmat.h"
|
||||
|
||||
|
||||
const aluMatrixf aluMatrixf::Identity{{
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
}};
|
||||
|
||||
+88
-32
@@ -1,46 +1,102 @@
|
||||
#ifndef COMMON_VECMAT_H
|
||||
#define COMMON_VECMAT_H
|
||||
|
||||
#include "AL/al.h"
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
|
||||
#include "math_defs.h"
|
||||
|
||||
struct aluVector {
|
||||
alignas(16) ALfloat v[4];
|
||||
namespace alu {
|
||||
|
||||
class Vector {
|
||||
alignas(16) std::array<float,4> mVals{};
|
||||
|
||||
public:
|
||||
constexpr Vector() noexcept = default;
|
||||
constexpr Vector(float a, float b, float c, float d) noexcept
|
||||
: mVals{{a, b, c, d}}
|
||||
{ }
|
||||
Vector(const Vector &rhs) noexcept
|
||||
{ std::copy(rhs.mVals.begin(), rhs.mVals.end(), mVals.begin()); }
|
||||
|
||||
Vector& operator=(const Vector &rhs) noexcept
|
||||
{
|
||||
std::copy(rhs.mVals.begin(), rhs.mVals.end(), mVals.begin());
|
||||
return *this;
|
||||
}
|
||||
|
||||
float& operator[](size_t idx) noexcept { return mVals[idx]; }
|
||||
constexpr const float& operator[](size_t idx) const noexcept { return mVals[idx]; }
|
||||
|
||||
Vector& operator+=(const Vector &rhs) noexcept
|
||||
{
|
||||
mVals[0] += rhs.mVals[0];
|
||||
mVals[1] += rhs.mVals[1];
|
||||
mVals[2] += rhs.mVals[2];
|
||||
mVals[3] += rhs.mVals[3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
float normalize()
|
||||
{
|
||||
const float length{std::sqrt(mVals[0]*mVals[0] + mVals[1]*mVals[1] + mVals[2]*mVals[2])};
|
||||
if(length > FLT_EPSILON)
|
||||
{
|
||||
float inv_length = 1.0f/length;
|
||||
mVals[0] *= inv_length;
|
||||
mVals[1] *= inv_length;
|
||||
mVals[2] *= inv_length;
|
||||
return length;
|
||||
}
|
||||
mVals[0] = mVals[1] = mVals[2] = 0.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
inline void aluVectorSet(aluVector *vector, ALfloat x, ALfloat y, ALfloat z, ALfloat w)
|
||||
{
|
||||
vector->v[0] = x;
|
||||
vector->v[1] = y;
|
||||
vector->v[2] = z;
|
||||
vector->v[3] = w;
|
||||
}
|
||||
class Matrix {
|
||||
alignas(16) std::array<std::array<float,4>,4> mVals{};
|
||||
|
||||
public:
|
||||
constexpr Matrix() noexcept = default;
|
||||
constexpr Matrix(float aa, float ab, float ac, float ad,
|
||||
float ba, float bb, float bc, float bd,
|
||||
float ca, float cb, float cc, float cd,
|
||||
float da, float db, float dc, float dd) noexcept
|
||||
: mVals{{{{aa, ab, ac, ad}}, {{ba, bb, bc, bd}}, {{ca, cb, cc, cd}}, {{da, db, dc, dd}}}}
|
||||
{ }
|
||||
Matrix(const Matrix &rhs) noexcept
|
||||
{ std::copy(rhs.mVals.begin(), rhs.mVals.end(), mVals.begin()); }
|
||||
|
||||
struct aluMatrixf {
|
||||
alignas(16) ALfloat m[4][4];
|
||||
Matrix& operator=(const Matrix &rhs) noexcept
|
||||
{
|
||||
std::copy(rhs.mVals.begin(), rhs.mVals.end(), mVals.begin());
|
||||
return *this;
|
||||
}
|
||||
|
||||
static const aluMatrixf Identity;
|
||||
std::array<float,4>& operator[](size_t idx) noexcept { return mVals[idx]; }
|
||||
constexpr const std::array<float,4>& operator[](size_t idx) const noexcept { return mVals[idx]; }
|
||||
|
||||
void setRow(size_t idx, float a, float b, float c, float d) noexcept
|
||||
{
|
||||
mVals[idx][0] = a;
|
||||
mVals[idx][1] = b;
|
||||
mVals[idx][2] = c;
|
||||
mVals[idx][3] = d;
|
||||
}
|
||||
|
||||
static const Matrix &Identity() noexcept
|
||||
{
|
||||
static constexpr Matrix identity{
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
return identity;
|
||||
}
|
||||
};
|
||||
|
||||
inline void aluMatrixfSetRow(aluMatrixf *matrix, ALuint row,
|
||||
ALfloat m0, ALfloat m1, ALfloat m2, ALfloat m3)
|
||||
{
|
||||
matrix->m[row][0] = m0;
|
||||
matrix->m[row][1] = m1;
|
||||
matrix->m[row][2] = m2;
|
||||
matrix->m[row][3] = m3;
|
||||
}
|
||||
|
||||
inline void aluMatrixfSet(aluMatrixf *matrix, ALfloat m00, ALfloat m01, ALfloat m02, ALfloat m03,
|
||||
ALfloat m10, ALfloat m11, ALfloat m12, ALfloat m13,
|
||||
ALfloat m20, ALfloat m21, ALfloat m22, ALfloat m23,
|
||||
ALfloat m30, ALfloat m31, ALfloat m32, ALfloat m33)
|
||||
{
|
||||
aluMatrixfSetRow(matrix, 0, m00, m01, m02, m03);
|
||||
aluMatrixfSetRow(matrix, 1, m10, m11, m12, m13);
|
||||
aluMatrixfSetRow(matrix, 2, m20, m21, m22, m23);
|
||||
aluMatrixfSetRow(matrix, 3, m30, m31, m32, m33);
|
||||
}
|
||||
} // namespace alu
|
||||
|
||||
#endif /* COMMON_VECMAT_H */
|
||||
|
||||
Reference in New Issue
Block a user