remove preconditioning experiments; use preconditioning by default; write delta
This commit is contained in:
parent
2fa4532b01
commit
3be2152264
@ -26,9 +26,6 @@
|
|||||||
// Here, we solve Ax = b using the Modified Conjugate Gradient method.
|
// Here, we solve Ax = b using the Modified Conjugate Gradient method.
|
||||||
// This work is based on the paper "Large Steps in Cloth Simulation - David Baraff, Andrew Witkin".
|
// This work is based on the paper "Large Steps in Cloth Simulation - David Baraff, Andrew Witkin".
|
||||||
|
|
||||||
// Enable preconditioning.
|
|
||||||
bool b3_enablePrecontitioning = false;
|
|
||||||
|
|
||||||
b3SpringSolver::b3SpringSolver(const b3SpringSolverDef& def)
|
b3SpringSolver::b3SpringSolver(const b3SpringSolverDef& def)
|
||||||
{
|
{
|
||||||
m_cloth = def.cloth;
|
m_cloth = def.cloth;
|
||||||
@ -101,6 +98,7 @@ void b3SpringSolver::Solve(b3DenseVec3& f)
|
|||||||
b3Mat33* S = (b3Mat33*)m_allocator->Allocate(m_massCount * sizeof(b3Mat33));
|
b3Mat33* S = (b3Mat33*)m_allocator->Allocate(m_massCount * sizeof(b3Mat33));
|
||||||
Compute_S(S);
|
Compute_S(S);
|
||||||
|
|
||||||
|
// Solve Ax = b
|
||||||
Solve(x, f, m_iterations, A, b, S);
|
Solve(x, f, m_iterations, A, b, S);
|
||||||
|
|
||||||
// Update state
|
// Update state
|
||||||
@ -429,25 +427,6 @@ static void b3Filter(b3DenseVec3& out,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sylvester's Criterion
|
|
||||||
static bool b3IsPD(const b3Mat33* diagA, u32 n)
|
|
||||||
{
|
|
||||||
// Loop over the principal elements
|
|
||||||
for (u32 i = 0; i < n; ++i)
|
|
||||||
{
|
|
||||||
b3Mat33 a = diagA[i];
|
|
||||||
|
|
||||||
float32 D = b3Det(a.x, a.y, a.z);
|
|
||||||
|
|
||||||
if (D <= B3_EPSILON)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void b3SpringSolver::Solve(b3DenseVec3& dv, b3DenseVec3& e, u32& iterations, const b3SparseMat33& A, const b3DenseVec3& b, const b3Mat33* S) const
|
void b3SpringSolver::Solve(b3DenseVec3& dv, b3DenseVec3& e, u32& iterations, const b3SparseMat33& A, const b3DenseVec3& b, const b3Mat33* S) const
|
||||||
{
|
{
|
||||||
b3DenseVec3 P(m_massCount);
|
b3DenseVec3 P(m_massCount);
|
||||||
@ -455,8 +434,7 @@ void b3SpringSolver::Solve(b3DenseVec3& dv, b3DenseVec3& e, u32& iterations, con
|
|||||||
b3DenseVec3 inv_P(m_massCount);
|
b3DenseVec3 inv_P(m_massCount);
|
||||||
|
|
||||||
// Compute P, P^-1
|
// Compute P, P^-1
|
||||||
if (b3_enablePrecontitioning)
|
|
||||||
{
|
|
||||||
// P = diag(A)^-1
|
// P = diag(A)^-1
|
||||||
|
|
||||||
// diag(A)
|
// diag(A)
|
||||||
@ -467,8 +445,8 @@ void b3SpringSolver::Solve(b3DenseVec3& dv, b3DenseVec3& e, u32& iterations, con
|
|||||||
{
|
{
|
||||||
b3Mat33 D = diagA[i];
|
b3Mat33 D = diagA[i];
|
||||||
|
|
||||||
// Sylvester's Criterion
|
// Sylvester Criterion to ensure PD-ness
|
||||||
B3_ASSERT(b3Det(D.x, D.y, D.z) <= B3_EPSILON);
|
B3_ASSERT(b3Det(D.x, D.y, D.z) > B3_EPSILON);
|
||||||
|
|
||||||
B3_ASSERT(D[0][0] != 0.0f);
|
B3_ASSERT(D[0][0] != 0.0f);
|
||||||
B3_ASSERT(D[1][1] != 0.0f);
|
B3_ASSERT(D[1][1] != 0.0f);
|
||||||
@ -479,34 +457,21 @@ void b3SpringSolver::Solve(b3DenseVec3& dv, b3DenseVec3& e, u32& iterations, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_allocator->Free(diagA);
|
m_allocator->Free(diagA);
|
||||||
}
|
|
||||||
else
|
// delta0 = dot(filter(b), P * filter(b))
|
||||||
{
|
b3DenseVec3 S_b(m_massCount);
|
||||||
// P = I
|
b3Filter(S_b, b, S, m_massCount);
|
||||||
|
|
||||||
|
// P * S * b
|
||||||
|
b3DenseVec3 P_S_b(m_massCount);
|
||||||
for (u32 i = 0; i < m_massCount; ++i)
|
for (u32 i = 0; i < m_massCount; ++i)
|
||||||
{
|
{
|
||||||
P[i].Set(1.0f, 1.0f, 1.0f);
|
P_S_b[i][0] = P[i][0] * S_b[i][0];
|
||||||
|
P_S_b[i][1] = P[i][1] * S_b[i][1];
|
||||||
|
P_S_b[i][2] = P[i][2] * S_b[i][2];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < m_massCount; ++i)
|
float32 delta0 = b3Dot(S_b, P_S_b);
|
||||||
{
|
|
||||||
inv_P[i].Set(1.0f, 1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eps0 = dot( filter(b), P * filter(b) )
|
|
||||||
b3DenseVec3 filtered_b(m_massCount);
|
|
||||||
b3Filter(filtered_b, b, S, m_massCount);
|
|
||||||
|
|
||||||
b3DenseVec3 P_filtered_b(m_massCount);
|
|
||||||
for (u32 i = 0; i < m_massCount; ++i)
|
|
||||||
{
|
|
||||||
P_filtered_b[i][0] = P[i][0] * filtered_b[i][0];
|
|
||||||
P_filtered_b[i][1] = P[i][1] * filtered_b[i][1];
|
|
||||||
P_filtered_b[i][2] = P[i][2] * filtered_b[i][2];
|
|
||||||
}
|
|
||||||
|
|
||||||
float32 delta0 = b3Dot(filtered_b, P_filtered_b);
|
|
||||||
|
|
||||||
// r = filter(b - Adv)
|
// r = filter(b - Adv)
|
||||||
b3DenseVec3 r = b - A * dv;
|
b3DenseVec3 r = b - A * dv;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user