optimization
This commit is contained in:
parent
c1a5d1b93f
commit
246072f2d3
@ -372,9 +372,8 @@ static void b3Compute_z(b3DenseVec3& out,
|
|||||||
out.SetZero();
|
out.SetZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maintains invariants inside the MCG solver.
|
//
|
||||||
static void b3Filter(b3DenseVec3& out,
|
static void b3Compute_S(b3Mat33* out, u32 massCount, const b3MassType* types, const b3MassContact* contacts)
|
||||||
const b3DenseVec3& v, u32 massCount, const b3MassType* types, const b3MassContact* contacts)
|
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < massCount; ++i)
|
for (u32 i = 0; i < massCount; ++i)
|
||||||
{
|
{
|
||||||
@ -407,11 +406,11 @@ static void b3Filter(b3DenseVec3& out,
|
|||||||
S -= b3Outer(t2, t2);
|
S -= b3Outer(t2, t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
out[i] = S * v[i];
|
out[i] = S;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out[i] = v[i];
|
out[i].SetIdentity();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -423,8 +422,22 @@ static void b3Filter(b3DenseVec3& out,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maintains invariants inside the MCG solver.
|
||||||
|
static void b3Filter(b3DenseVec3& out,
|
||||||
|
const b3DenseVec3& v, const b3Mat33* S, u32 massCount)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < massCount; ++i)
|
||||||
|
{
|
||||||
|
out[i] = S[i] * v[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void b3SpringSolver::Solve_MCG(b3DenseVec3& dv, const b3SparseMat33& A, b3DenseVec3& e, u32& iterations, const b3DenseVec3& b) const
|
void b3SpringSolver::Solve_MCG(b3DenseVec3& dv, const b3SparseMat33& A, b3DenseVec3& e, u32& iterations, const b3DenseVec3& b) const
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
b3Mat33* S = (b3Mat33*)m_allocator->Allocate(m_massCount * sizeof(b3Mat33));
|
||||||
|
b3Compute_S(S, m_massCount, m_types, m_contacts);
|
||||||
|
|
||||||
// dv = z
|
// dv = z
|
||||||
b3Compute_z(dv, m_massCount, m_types, m_contacts);
|
b3Compute_z(dv, m_massCount, m_types, m_contacts);
|
||||||
|
|
||||||
@ -435,7 +448,7 @@ void b3SpringSolver::Solve_MCG(b3DenseVec3& dv, const b3SparseMat33& A, b3DenseV
|
|||||||
// r = filter(b - Adv)
|
// r = filter(b - Adv)
|
||||||
b3DenseVec3 r(m_massCount);
|
b3DenseVec3 r(m_massCount);
|
||||||
b3Sub(r, b, Adv);
|
b3Sub(r, b, Adv);
|
||||||
b3Filter(r, r, m_massCount, m_types, m_contacts);
|
b3Filter(r, r, S, m_massCount);
|
||||||
|
|
||||||
// c = r
|
// c = r
|
||||||
b3DenseVec3 c = r;
|
b3DenseVec3 c = r;
|
||||||
@ -459,7 +472,7 @@ void b3SpringSolver::Solve_MCG(b3DenseVec3& dv, const b3SparseMat33& A, b3DenseV
|
|||||||
// q = filter(A * c)
|
// q = filter(A * c)
|
||||||
b3DenseVec3 q(m_massCount);
|
b3DenseVec3 q(m_massCount);
|
||||||
A.Mul(q, c);
|
A.Mul(q, c);
|
||||||
b3Filter(q, q, m_massCount, m_types, m_contacts);
|
b3Filter(q, q, S, m_massCount);
|
||||||
|
|
||||||
// alpha = epsNew / dot(c, q)
|
// alpha = epsNew / dot(c, q)
|
||||||
float32 alpha_den = b3Dot(c, q);
|
float32 alpha_den = b3Dot(c, q);
|
||||||
@ -487,11 +500,13 @@ void b3SpringSolver::Solve_MCG(b3DenseVec3& dv, const b3SparseMat33& A, b3DenseV
|
|||||||
b3DenseVec3 beta_c(m_massCount);
|
b3DenseVec3 beta_c(m_massCount);
|
||||||
b3Mul(beta_c, beta, c);
|
b3Mul(beta_c, beta, c);
|
||||||
b3Add(c, r, beta_c);
|
b3Add(c, r, beta_c);
|
||||||
b3Filter(c, c, m_massCount, m_types, m_contacts);
|
b3Filter(c, c, S, m_massCount);
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_allocator->Free(S);
|
||||||
|
|
||||||
iterations = iter;
|
iterations = iter;
|
||||||
|
|
||||||
// f = A * dv - b
|
// f = A * dv - b
|
||||||
@ -522,6 +537,10 @@ static bool b3IsPD(const b3Mat33* diagA, u32 n)
|
|||||||
|
|
||||||
void b3SpringSolver::Solve_MPCG(b3DenseVec3& dv, const b3SparseMat33& A, b3DenseVec3& e, u32& iterations, const b3DenseVec3& b) const
|
void b3SpringSolver::Solve_MPCG(b3DenseVec3& dv, const b3SparseMat33& A, b3DenseVec3& e, u32& iterations, const b3DenseVec3& b) const
|
||||||
{
|
{
|
||||||
|
// S
|
||||||
|
b3Mat33* S = (b3Mat33*)m_allocator->Allocate(m_massCount * sizeof(b3Mat33));
|
||||||
|
b3Compute_S(S, m_massCount, m_types, m_contacts);
|
||||||
|
|
||||||
b3DenseVec3 r(m_massCount);
|
b3DenseVec3 r(m_massCount);
|
||||||
|
|
||||||
b3DenseVec3 c(m_massCount);
|
b3DenseVec3 c(m_massCount);
|
||||||
@ -563,18 +582,18 @@ void b3SpringSolver::Solve_MPCG(b3DenseVec3& dv, const b3SparseMat33& A, b3Dense
|
|||||||
m_allocator->Free(diagA);
|
m_allocator->Free(diagA);
|
||||||
|
|
||||||
// eps0 = dot( filter(b), P * filter(b) )
|
// eps0 = dot( filter(b), P * filter(b) )
|
||||||
b3DenseVec3 filter_b(m_massCount);
|
b3DenseVec3 filtered_b(m_massCount);
|
||||||
b3Filter(filter_b, b, m_massCount, m_types, m_contacts);
|
b3Filter(filtered_b, b, S, m_massCount);
|
||||||
|
|
||||||
b3DenseVec3 P_filter_b(m_massCount);
|
b3DenseVec3 P_filtered_b(m_massCount);
|
||||||
for (u32 i = 0; i < m_massCount; ++i)
|
for (u32 i = 0; i < m_massCount; ++i)
|
||||||
{
|
{
|
||||||
P_filter_b[i][0] = P[i][0] * filter_b[i][0];
|
P_filtered_b[i][0] = P[i][0] * filtered_b[i][0];
|
||||||
P_filter_b[i][1] = P[i][1] * filter_b[i][1];
|
P_filtered_b[i][1] = P[i][1] * filtered_b[i][1];
|
||||||
P_filter_b[i][2] = P[i][2] * filter_b[i][2];
|
P_filtered_b[i][2] = P[i][2] * filtered_b[i][2];
|
||||||
}
|
}
|
||||||
|
|
||||||
float32 eps0 = b3Dot(filter_b, P_filter_b);
|
float32 eps0 = b3Dot(filtered_b, P_filtered_b);
|
||||||
|
|
||||||
// r = filter(b - Adv)
|
// r = filter(b - Adv)
|
||||||
|
|
||||||
@ -582,7 +601,7 @@ void b3SpringSolver::Solve_MPCG(b3DenseVec3& dv, const b3SparseMat33& A, b3Dense
|
|||||||
b3DenseVec3 Adv(m_massCount);
|
b3DenseVec3 Adv(m_massCount);
|
||||||
A.Mul(Adv, dv);
|
A.Mul(Adv, dv);
|
||||||
b3Sub(r, b, Adv);
|
b3Sub(r, b, Adv);
|
||||||
b3Filter(r, r, m_massCount, m_types, m_contacts);
|
b3Filter(r, r, S, m_massCount);
|
||||||
|
|
||||||
// c = filter(P^-1 * r)
|
// c = filter(P^-1 * r)
|
||||||
for (u32 i = 0; i < m_massCount; ++i)
|
for (u32 i = 0; i < m_massCount; ++i)
|
||||||
@ -591,7 +610,7 @@ void b3SpringSolver::Solve_MPCG(b3DenseVec3& dv, const b3SparseMat33& A, b3Dense
|
|||||||
c[i][1] = inv_P[i][1] * r[i][1];
|
c[i][1] = inv_P[i][1] * r[i][1];
|
||||||
c[i][2] = inv_P[i][2] * r[i][2];
|
c[i][2] = inv_P[i][2] * r[i][2];
|
||||||
}
|
}
|
||||||
b3Filter(c, c, m_massCount, m_types, m_contacts);
|
b3Filter(c, c, S, m_massCount);
|
||||||
|
|
||||||
// epsNew = dot(r, c)
|
// epsNew = dot(r, c)
|
||||||
float32 epsNew = b3Dot(r, c);
|
float32 epsNew = b3Dot(r, c);
|
||||||
@ -609,7 +628,7 @@ void b3SpringSolver::Solve_MPCG(b3DenseVec3& dv, const b3SparseMat33& A, b3Dense
|
|||||||
// q = filter(A * c)
|
// q = filter(A * c)
|
||||||
b3DenseVec3 q(m_massCount);
|
b3DenseVec3 q(m_massCount);
|
||||||
A.Mul(q, c);
|
A.Mul(q, c);
|
||||||
b3Filter(q, q, m_massCount, m_types, m_contacts);
|
b3Filter(q, q, S, m_massCount);
|
||||||
|
|
||||||
// alpha = epsNew / dot(c, q)
|
// alpha = epsNew / dot(c, q)
|
||||||
float32 alpha = epsNew / b3Dot(c, q);
|
float32 alpha = epsNew / b3Dot(c, q);
|
||||||
@ -648,11 +667,13 @@ void b3SpringSolver::Solve_MPCG(b3DenseVec3& dv, const b3SparseMat33& A, b3Dense
|
|||||||
{
|
{
|
||||||
c[i] = s[i] + beta * c[i];
|
c[i] = s[i] + beta * c[i];
|
||||||
}
|
}
|
||||||
b3Filter(c, c, m_massCount, m_types, m_contacts);
|
b3Filter(c, c, S, m_massCount);
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_allocator->Free(S);
|
||||||
|
|
||||||
iterations = iter;
|
iterations = iter;
|
||||||
|
|
||||||
// Residual error
|
// Residual error
|
||||||
|
Loading…
x
Reference in New Issue
Block a user