This commit is contained in:
Irlan 2018-06-21 15:21:40 -03:00
parent c738267c2e
commit 725b771d39
7 changed files with 87 additions and 143 deletions

View File

@ -53,7 +53,7 @@ static inline bool ImGui_GLFW_GL_Init(GLFWwindow* w, bool install_callbacks)
// error
#endif
return false;
}
static inline void ImGui_GLFW_GL_Shutdown()

View File

@ -147,6 +147,8 @@ private:
// Proxy mesh
b3ClothMesh* m_mesh;
// Mesh density
float32 m_density;
// Particle pool

View File

@ -22,6 +22,8 @@
#include <bounce/common/math/vec2.h>
#include <bounce/common/math/vec3.h>
class b3Particle;
struct b3ClothMeshTriangle
{
u32 v1, v2, v3;
@ -41,8 +43,6 @@ struct b3ClothMeshSewingLine
u32 v1, v2;
};
class b3Particle;
struct b3ClothMesh
{
u32 vertexCount;

View File

@ -24,15 +24,14 @@
class b3StackAllocator;
struct b3DenseVec3;
struct b3DiagMat33;
struct b3SparseSymMat33;
struct b3SymMat33;
class b3Particle;
class b3Force;
struct b3BodyContact;
struct b3DenseVec3;
struct b3DiagMat33;
struct b3SparseSymMat33;
struct b3ClothSolverDef
{
b3StackAllocator* stack;
@ -43,11 +42,12 @@ struct b3ClothSolverDef
struct b3ClothSolverData
{
b3Vec3* x;
b3Vec3* v;
b3Vec3* f;
b3SymMat33* dfdx;
b3SymMat33* dfdv;
b3DenseVec3* x;
b3DenseVec3* v;
b3DenseVec3* f;
b3DenseVec3* y;
b3SparseSymMat33* dfdx;
b3SparseSymMat33* dfdv;
float32 dt;
float32 invdt;
};
@ -59,45 +59,6 @@ struct b3AccelerationConstraint
b3Vec3 p, q, z;
};
struct b3SymMat33
{
b3SymMat33(b3StackAllocator* a, u32 m, u32 n)
{
allocator = a;
M = m;
N = n;
values = (b3Mat33*)b3Alloc(M * N * sizeof(b3Mat33));
}
~b3SymMat33()
{
b3Free(values);
}
b3Mat33& operator()(u32 i, u32 j)
{
return values[i * N + j];
}
const b3Mat33& operator()(u32 i, u32 j) const
{
return values[i * N + j];
}
void SetZero()
{
for (u32 v = 0; v < M * N; ++v)
{
values[v].SetZero();
}
}
u32 M;
u32 N;
b3Mat33* values;
b3StackAllocator* allocator;
};
class b3ClothSolver
{
public:
@ -120,7 +81,7 @@ private:
void InitializeConstraints();
// Compute A and b in Ax = b
void Compute_A_b(b3SparseSymMat33& A, b3DenseVec3& b, const b3DenseVec3& f, const b3DenseVec3& x, const b3DenseVec3& v, const b3DenseVec3& y) const;
void Compute_A_b(b3SparseSymMat33& A, b3DenseVec3& b) const;
// Compute S and z.
void Compute_S_z(b3DiagMat33& S, b3DenseVec3& z);

View File

@ -19,7 +19,6 @@
#ifndef B3_SPARSE_SYM_MAT_33_H
#define B3_SPARSE_SYM_MAT_33_H
#include <bounce/common/memory/stack_allocator.h>
#include <bounce/common/math/mat33.h>
#include <bounce/dynamics/cloth/diag_mat33.h>
#include <bounce/dynamics/cloth/dense_vec3.h>
@ -27,7 +26,7 @@
struct b3SparseSymMat33
{
//
b3SparseSymMat33(b3StackAllocator* a, u32 m, u32 n);
b3SparseSymMat33(u32 m, u32 n);
//
~b3SparseSymMat33();
@ -42,8 +41,8 @@ struct b3SparseSymMat33
void Diagonal(b3DiagMat33& out) const;
//
void SetZero();
b3StackAllocator* allocator;
u32 M;
u32 N;
u32* row_ptrs;
@ -53,25 +52,24 @@ struct b3SparseSymMat33
u32* value_columns;
};
inline b3SparseSymMat33::b3SparseSymMat33(b3StackAllocator* a, u32 m, u32 n)
inline b3SparseSymMat33::b3SparseSymMat33(u32 m, u32 n)
{
B3_ASSERT(m == n);
allocator = a;
M = m;
N = n;
row_ptrs = (u32*)allocator->Allocate((M + 1) * sizeof(u32));
row_ptrs = (u32*)b3Alloc((M + 1) * sizeof(u32));
memset(row_ptrs, 0, (M + 1) * sizeof(u32));
value_count = 0;
value_capacity = n * (n + 1) / 2;
values = (b3Mat33*)allocator->Allocate(value_capacity * sizeof(b3Mat33));
value_columns = (u32*)allocator->Allocate(value_capacity * sizeof(u32));
value_capacity = M * (M + 1) / 2;
values = (b3Mat33*)b3Alloc(value_capacity * sizeof(b3Mat33));
value_columns = (u32*)b3Alloc(value_capacity * sizeof(u32));
}
inline b3SparseSymMat33::~b3SparseSymMat33()
{
allocator->Free(value_columns);
allocator->Free(values);
allocator->Free(row_ptrs);
b3Free(value_columns);
b3Free(values);
b3Free(row_ptrs);
}
inline const b3Mat33& b3SparseSymMat33::operator()(u32 i, u32 j) const
@ -103,7 +101,7 @@ inline const b3Mat33& b3SparseSymMat33::operator()(u32 i, u32 j) const
}
inline b3Mat33& b3SparseSymMat33::operator()(u32 i, u32 j)
{
{
B3_ASSERT(i < M);
B3_ASSERT(j < N);
@ -120,57 +118,44 @@ inline b3Mat33& b3SparseSymMat33::operator()(u32 i, u32 j)
{
u32 row_value_index = row_value_begin + row_value;
u32 row_value_column = value_columns[row_value_index];
if (row_value_column == j)
{
return values[row_value_index];
}
}
// Insert sorted by column
u32 max_column_row_value = 0;
// Find insert position
u32 row_value_k = 0;
for (u32 row_value = 0; row_value < row_value_count; ++row_value)
{
u32 row_value_index = row_value_begin + row_value;
u32 row_value_column = value_columns[row_value_index];
if (row_value_column >= j)
{
max_column_row_value = row_value;
row_value_k = row_value;
break;
}
}
u32 max_column_row_value_index = row_value_begin + max_column_row_value;
// Shift the values
u32 right_count = value_count - row_value_begin - row_value_k;
memcpy(value_columns + row_value_begin + row_value_k + 1, value_columns + row_value_begin + row_value_k, right_count * sizeof(u32));
memcpy(values + row_value_begin + row_value_k + 1, values + row_value_begin + row_value_k, right_count * sizeof(b3Mat33));
// Copy the values to be shifted
u32 shift_count = value_count - max_column_row_value_index;
b3Mat33* shift_values = (b3Mat33*)allocator->Allocate(shift_count * sizeof(b3Mat33));
memcpy(shift_values, values + max_column_row_value_index, shift_count * sizeof(b3Mat33));
u32* shift_value_columns = (u32*)allocator->Allocate(shift_count * sizeof(u32));
memcpy(shift_value_columns, value_columns + max_column_row_value_index, shift_count * sizeof(u32));
// Insert the new value
B3_ASSERT(value_count < value_capacity);
value_columns[max_column_row_value_index] = j;
++value_count;
// Shift the old values
memcpy(values + max_column_row_value_index + 1, shift_values, shift_count * sizeof(b3Mat33));
memcpy(value_columns + max_column_row_value_index + 1, shift_value_columns, shift_count * sizeof(u32));
allocator->Free(shift_value_columns);
allocator->Free(shift_values);
// Shift the old row pointers as well
// Shift the row pointers
for (u32 row_ptr_index = i + 1; row_ptr_index < M + 1; ++row_ptr_index)
{
++row_ptrs[row_ptr_index];
}
return values[max_column_row_value_index];
// Insert the value
value_columns[row_value_begin + row_value_k] = j;
++value_count;
// Return the value
return values[row_value_begin + row_value_k];
}
inline void b3SparseSymMat33::Diagonal(b3DiagMat33& out) const
@ -198,6 +183,17 @@ inline void b3SparseSymMat33::Diagonal(b3DiagMat33& out) const
}
}
inline void b3SparseSymMat33::SetZero()
{
for (u32 i = 0; i < M; ++i)
{
for (u32 j = i; j < M; ++j)
{
(*this)(i, j).SetZero();
}
}
}
inline void b3Mul(b3DenseVec3& out, const b3SparseSymMat33& A, const b3DenseVec3& v)
{
B3_ASSERT(A.N == out.n);

View File

@ -25,29 +25,6 @@
#include <bounce/dynamics/cloth/sparse_sym_mat33.h>
#include <bounce/common/memory/stack_allocator.h>
static B3_FORCE_INLINE void b3Mul(b3DenseVec3& out, const b3SymMat33& A, const b3DenseVec3& v)
{
B3_ASSERT(A.N == v.n);
B3_ASSERT(out.n == A.M);
for (u32 row = 0; row < A.M; ++row)
{
out[row].SetZero();
for (u32 column = 0; column < A.N; ++column)
{
out[row] += A(row, column) * v[column];
}
}
}
static B3_FORCE_INLINE b3DenseVec3 operator*(const b3SymMat33& m, const b3DenseVec3& v)
{
b3DenseVec3 result(v.n);
b3Mul(result, m, v);
return result;
}
// Here, we solve Ax = b using the Modified Preconditioned Conjugate Gradient (MPCG) algorithm.
// described in the paper:
// "Large Steps in Cloth Simulation - David Baraff, Andrew Witkin".
@ -168,23 +145,22 @@ void b3ClothSolver::InitializeConstraints()
void b3ClothSolver::Solve(float32 dt, const b3Vec3& gravity)
{
B3_PROFILE("Integrate");
b3DenseVec3 sx(m_particleCount);
b3DenseVec3 sv(m_particleCount);
b3DenseVec3 sf(m_particleCount);
b3DenseVec3 sy(m_particleCount);
b3DenseVec3 sx0(m_particleCount);
b3SymMat33 dfdx(m_allocator, m_particleCount, m_particleCount);
b3SparseSymMat33 dfdx(m_particleCount, m_particleCount);
dfdx.SetZero();
b3SymMat33 dfdv(m_allocator, m_particleCount, m_particleCount);
b3SparseSymMat33 dfdv(m_particleCount, m_particleCount);
dfdv.SetZero();
m_solverData.x = sx.v;
m_solverData.v = sv.v;
m_solverData.f = sf.v;
m_solverData.x = &sx;
m_solverData.v = &sv;
m_solverData.f = &sf;
m_solverData.y = &sy;
m_solverData.dfdx = &dfdx;
m_solverData.dfdv = &dfdv;
m_solverData.dt = dt;
@ -235,12 +211,12 @@ void b3ClothSolver::Solve(float32 dt, const b3Vec3& gravity)
// b = h * (f0 + h * dfdx * v0 + dfdx * y)
// A
b3SparseSymMat33 A(m_allocator, m_particleCount, m_particleCount);
b3SparseSymMat33 A(m_particleCount, m_particleCount);
// b
b3DenseVec3 b(m_particleCount);
Compute_A_b(A, b, sf, sx, sv, sy);
Compute_A_b(A, b);
// x
b3DenseVec3 x(m_particleCount);
@ -292,11 +268,17 @@ void b3ClothSolver::Solve(float32 dt, const b3Vec3& gravity)
}
}
void b3ClothSolver::Compute_A_b(b3SparseSymMat33& A, b3DenseVec3& b, const b3DenseVec3& f, const b3DenseVec3& x, const b3DenseVec3& v, const b3DenseVec3& y) const
void b3ClothSolver::Compute_A_b(b3SparseSymMat33& A, b3DenseVec3& b) const
{
B3_PROFILE("Compute A, b");
b3DenseVec3& x = *m_solverData.x;
b3DenseVec3& v = *m_solverData.v;
b3DenseVec3& f = *m_solverData.f;
b3DenseVec3& y = *m_solverData.y;
b3SparseSymMat33& dfdx = *m_solverData.dfdx;
b3SparseSymMat33& dfdv = *m_solverData.dfdv;
float32 h = m_solverData.dt;
b3SymMat33& dfdx = *m_solverData.dfdx;
b3SymMat33& dfdv = *m_solverData.dfdv;
// Compute A
// A = M - h * dfdv - h * h * dfdx
@ -439,8 +421,6 @@ void b3ClothSolver::Solve(b3DenseVec3& x, u32& iterations,
break;
}
B3_ASSERT(b3IsValid(delta_new));
// Convergence check.
if (delta_new <= tolerance * tolerance * b_delta)
{

View File

@ -19,6 +19,8 @@
#include <bounce/dynamics/cloth/spring_force.h>
#include <bounce/dynamics/cloth/particle.h>
#include <bounce/dynamics/cloth/cloth_solver.h>
#include <bounce/dynamics/cloth/dense_vec3.h>
#include <bounce/dynamics/cloth/sparse_sym_mat33.h>
void b3SpringForceDef::Initialize(b3Particle* particle1, b3Particle* particle2, float32 structuralStiffness, float32 dampingStiffness)
{
@ -50,14 +52,17 @@ b3SpringForce::~b3SpringForce()
void b3SpringForce::Initialize(const b3ClothSolverData* data)
{
b3DenseVec3& x = *data->x;
b3DenseVec3& v = *data->v;
u32 i1 = m_p1->m_solverId;
u32 i2 = m_p2->m_solverId;
b3Vec3 x1 = data->x[i1];
b3Vec3 v1 = data->v[i1];
b3Vec3 x1 = x[i1];
b3Vec3 v1 = v[i1];
b3Vec3 x2 = data->x[i2];
b3Vec3 v2 = data->v[i2];
b3Vec3 x2 = x[i2];
b3Vec3 v2 = v[i2];
b3Mat33 I; I.SetIdentity();
@ -90,9 +95,9 @@ void b3SpringForce::Initialize(const b3ClothSolverData* data)
void b3SpringForce::Apply(const b3ClothSolverData* data)
{
b3Vec3* f = data->f;
b3SymMat33& dfdx = *data->dfdx;
b3SymMat33& dfdv = *data->dfdv;
b3DenseVec3& f = *data->f;
b3SparseSymMat33& dfdx = *data->dfdx;
b3SparseSymMat33& dfdv = *data->dfdv;
u32 i1 = m_p1->m_solverId;
u32 i2 = m_p2->m_solverId;
@ -102,21 +107,21 @@ void b3SpringForce::Apply(const b3ClothSolverData* data)
b3Mat33 Jx11 = m_Jx;
b3Mat33 Jx12 = -Jx11;
b3Mat33 Jx21 = Jx12;
//b3Mat33 Jx21 = Jx12;
b3Mat33 Jx22 = Jx11;
dfdx(i1, i1) += Jx11;
dfdx(i1, i2) += Jx12;
dfdx(i2, i1) += Jx21;
//dfdx(i2, i1) += Jx21;
dfdx(i2, i2) += Jx22;
b3Mat33 Jv11 = m_Jv;
b3Mat33 Jv12 = -Jv11;
b3Mat33 Jv21 = Jv12;
//b3Mat33 Jv21 = Jv12;
b3Mat33 Jv22 = Jv11;
dfdv(i1, i1) += Jv11;
dfdv(i1, i2) += Jv12;
dfdv(i2, i1) += Jv21;
//dfdv(i2, i1) += Jv21;
dfdv(i2, i2) += Jv22;
}