From 7060f513ade0b73740c14b6f94ee3cc6d4f1875a Mon Sep 17 00:00:00 2001 From: Irlan <-> Date: Fri, 20 Jul 2018 13:51:09 -0300 Subject: [PATCH] preparation --- examples/testbed/tests/table_cloth.h | 1 + include/bounce/dynamics/cloth/bend_force.h | 158 +++++++++++++++++++++ include/bounce/dynamics/cloth/force.h | 1 + include/bounce/dynamics/cloth/particle.h | 1 + src/bounce/dynamics/cloth/bend_force.cpp | 128 +++++++++++++++++ src/bounce/dynamics/cloth/cloth.cpp | 23 ++- src/bounce/dynamics/cloth/force.cpp | 14 ++ 7 files changed, 312 insertions(+), 14 deletions(-) create mode 100644 include/bounce/dynamics/cloth/bend_force.h create mode 100644 src/bounce/dynamics/cloth/bend_force.cpp diff --git a/examples/testbed/tests/table_cloth.h b/examples/testbed/tests/table_cloth.h index cbaad9b..fba0787 100644 --- a/examples/testbed/tests/table_cloth.h +++ b/examples/testbed/tests/table_cloth.h @@ -41,6 +41,7 @@ public: b3ClothDef def; def.mesh = &m_rectangleClothMesh; def.density = 0.2f; + def.bending = 10000.0f; def.structural = 10000.0f; def.damping = 0.0f; diff --git a/include/bounce/dynamics/cloth/bend_force.h b/include/bounce/dynamics/cloth/bend_force.h new file mode 100644 index 0000000..069a88e --- /dev/null +++ b/include/bounce/dynamics/cloth/bend_force.h @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B3_BEND_FORCE_H +#define B3_BEND_FORCE_H + +#include + +struct b3BendForceDef : public b3ForceDef +{ + b3BendForceDef() + { + type = e_bendForce; + p1 = nullptr; + p2 = nullptr; + p3 = nullptr; + p4 = nullptr; + restDistance = 0.0f; + restAngle = 0.0f; + structural = 0.0f; + damping = 0.0f; + } + + // + void Initialize(b3Particle* particle1, b3Particle* particle2, b3Particle* particle3, b3Particle* particle4, + float32 structuralStiffness, float32 dampingStiffness); + + // Particle 1 + b3Particle* p1; + + // Particle 2 + b3Particle* p2; + + // Particle 3 + b3Particle* p3; + + // Particle 4 + b3Particle* p4; + + // Rest distance + float32 restDistance; + + // Rest angle + float32 restAngle; + + // Structural stiffness + float32 structural; + + // Damping stiffness + float32 damping; +}; + +// +class b3BendForce : public b3Force +{ +public: + b3Particle* GetParticle1(); + + b3Particle* GetParticle2(); + + b3Particle* GetParticle3(); + + b3Particle* GetParticle4(); + + float32 GetRestDistance() const; + + float32 GetRestAngle() const; + + float32 GetStructuralStiffness() const; + + float32 GetDampingStiffness() const; +private: + friend class b3Force; + friend class b3Cloth; + + b3BendForce(const b3BendForceDef* def); + ~b3BendForce(); + + void Apply(const b3ClothSolverData* data); + + // Solver shared + + // Particle 1 + b3Particle* m_p1; + + // Particle 2 + b3Particle* m_p2; + + // Particle 3 + b3Particle* m_p3; + + // Particle 4 + b3Particle* m_p4; + + // Rest distance + float32 m_L0; + + // Rest angle + float32 m_angle0; + + // Structural stiffness + float32 m_ks; + + // Structural stiffness + float32 m_kd; +}; + +inline b3Particle* b3BendForce::GetParticle1() +{ + return m_p1; +} + +inline b3Particle* b3BendForce::GetParticle2() +{ + return m_p2; +} + +inline b3Particle* b3BendForce::GetParticle3() +{ + return m_p3; +} + +inline b3Particle* b3BendForce::GetParticle4() +{ + return m_p4; +} + +inline float32 b3BendForce::GetRestAngle() const +{ + return m_angle0; +} + +inline float32 b3BendForce::GetStructuralStiffness() const +{ + return m_ks; +} + +inline float32 b3BendForce::GetDampingStiffness() const +{ + return m_kd; +} + +#endif \ No newline at end of file diff --git a/include/bounce/dynamics/cloth/force.h b/include/bounce/dynamics/cloth/force.h index ca5a323..87bcb5b 100644 --- a/include/bounce/dynamics/cloth/force.h +++ b/include/bounce/dynamics/cloth/force.h @@ -31,6 +31,7 @@ enum b3ForceType { e_frictionForce, e_springForce, + e_bendForce, }; struct b3ForceDef diff --git a/include/bounce/dynamics/cloth/particle.h b/include/bounce/dynamics/cloth/particle.h index a089349..0566486 100644 --- a/include/bounce/dynamics/cloth/particle.h +++ b/include/bounce/dynamics/cloth/particle.h @@ -143,6 +143,7 @@ private: friend class b3ClothSolver; friend class b3Force; friend class b3SpringForce; + friend class b3BendForce; friend class b3FrictionForce; b3Particle(const b3ParticleDef& def, b3Cloth* cloth); diff --git a/src/bounce/dynamics/cloth/bend_force.cpp b/src/bounce/dynamics/cloth/bend_force.cpp new file mode 100644 index 0000000..d540706 --- /dev/null +++ b/src/bounce/dynamics/cloth/bend_force.cpp @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include +#include +#include +#include +#include + +void b3BendForceDef::Initialize(b3Particle* particle1, b3Particle* particle2, b3Particle* particle3, b3Particle* particle4, float32 structuralStiffness, float32 dampingStiffness) +{ + type = e_bendForce; + p1 = particle1; + p2 = particle2; + p3 = particle3; + p4 = particle4; + + b3Vec3 x1 = p1->GetPosition(); + b3Vec3 x2 = p2->GetPosition(); + b3Vec3 x3 = p3->GetPosition(); + b3Vec3 x4 = p4->GetPosition(); + + restDistance = b3Distance(x2, x3); + structural = structuralStiffness; + damping = dampingStiffness; +} + +b3BendForce::b3BendForce(const b3BendForceDef* def) +{ + m_type = e_bendForce; + m_p1 = def->p1; + m_p2 = def->p2; + m_p3 = def->p3; + m_p4 = def->p4; + m_L0 = def->restDistance; + m_angle0 = def->restAngle; + m_ks = def->structural; + m_kd = def->damping; +} + +b3BendForce::~b3BendForce() +{ + +} + +void b3BendForce::Apply(const b3ClothSolverData* data) +{ + b3DenseVec3& x = *data->x; + b3DenseVec3& v = *data->v; + b3DenseVec3& f = *data->f; + b3SparseSymMat33& dfdx = *data->dfdx; + b3SparseSymMat33& dfdv = *data->dfdv; + + u32 i1 = m_p2->m_solverId; + u32 i2 = m_p3->m_solverId; + + b3Vec3 x1 = x[i1]; + b3Vec3 v1 = v[i1]; + + b3Vec3 x2 = x[i2]; + b3Vec3 v2 = v[i2]; + + b3Mat33 I; I.SetIdentity(); + + b3Vec3 ef; ef.SetZero(); + + if (m_ks > 0.0f) + { + b3Vec3 dx = x1 - x2; + + float32 L = b3Length(dx); + + if (L >= m_L0) + { + // Apply tension + b3Vec3 n = dx / L; + + ef += -m_ks * (L - m_L0) * n; + + // Jacobian + b3Mat33 Jx11 = -m_ks * (b3Outer(dx, dx) + (1.0f - m_L0 / L) * (I - b3Outer(dx, dx))); + b3Mat33 Jx12 = -Jx11; + //b3Mat33 Jx21 = Jx12; + b3Mat33 Jx22 = Jx11; + + dfdx(i1, i1) += Jx11; + dfdx(i1, i2) += Jx12; + //dfdx(i2, i1) += Jx21; + dfdx(i2, i2) += Jx22; + } + } + + if (m_kd > 0.0f) + { + // Apply damping + b3Vec3 dv = v1 - v2; + + ef += -m_kd * dv; + + b3Mat33 Jv11 = -m_kd * I; + b3Mat33 Jv12 = -Jv11; + //b3Mat33 Jv21 = Jv12; + b3Mat33 Jv22 = Jv11; + + dfdv(i1, i1) += Jv11; + dfdv(i1, i2) += Jv12; + //dfdv(i2, i1) += Jv21; + dfdv(i2, i2) += Jv22; + } + + f[i1] += ef; + f[i2] -= ef; +} \ No newline at end of file diff --git a/src/bounce/dynamics/cloth/cloth.cpp b/src/bounce/dynamics/cloth/cloth.cpp index 77c2d7c..14992fb 100644 --- a/src/bounce/dynamics/cloth/cloth.cpp +++ b/src/bounce/dynamics/cloth/cloth.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -30,10 +31,6 @@ #include #include -#define B3_FORCE_THRESHOLD 0.005f - -#define B3_CLOTH_BENDING 0 - static B3_FORCE_INLINE u32 b3NextIndex(u32 i) { return i + 1 < 3 ? i + 1 : 0; @@ -204,24 +201,22 @@ b3Cloth::b3Cloth(const b3ClothDef& def, b3World* world) : m_particleBlocks(sizeo CreateForce(fd); } -#if B3_CLOTH_BENDING - // Bending for (u32 i = 0; i < sharedCount; ++i) { b3SharedEdge* e = sharedEdges + i; - b3Particle* p1 = m->particles[e->nsv1]; - b3Particle* p2 = m->particles[e->nsv2]; - - b3SpringForceDef fd; - fd.Initialize(p1, p2, def.bending, def.damping); + b3Particle* p1 = m->particles[e->v1]; + b3Particle* p2 = m->particles[e->v2]; + b3Particle* p3 = m->particles[e->nsv1]; + b3Particle* p4 = m->particles[e->nsv2]; + + b3BendForceDef fd; + fd.Initialize(p1, p2, p3, p4, def.bending, def.damping); CreateForce(fd); } -#endif - allocator->Free(sharedEdges); allocator->Free(uniqueEdges); @@ -579,7 +574,7 @@ void b3Cloth::UpdateContacts() // The contact persists // Has the contact constraint been satisfied? - if (c0.Fn <= -B3_FORCE_THRESHOLD) + if (c0.Fn <= 0.0f) { // Contact force is attractive. diff --git a/src/bounce/dynamics/cloth/force.cpp b/src/bounce/dynamics/cloth/force.cpp index 3b42718..0365c66 100644 --- a/src/bounce/dynamics/cloth/force.cpp +++ b/src/bounce/dynamics/cloth/force.cpp @@ -18,6 +18,7 @@ #include #include +#include b3Force* b3Force::Create(const b3ForceDef* def) { @@ -30,6 +31,12 @@ b3Force* b3Force::Create(const b3ForceDef* def) force = new (block) b3SpringForce((b3SpringForceDef*)def); break; } + case e_bendForce: + { + void* block = b3Alloc(sizeof(b3BendForce)); + force = new (block) b3BendForce((b3BendForceDef*)def); + break; + } default: { B3_ASSERT(false); @@ -53,6 +60,13 @@ void b3Force::Destroy(b3Force* force) b3Free(force); break; } + case e_bendForce: + { + b3BendForce* o = (b3BendForce*)force; + o->~b3BendForce(); + b3Free(force); + break; + } default: { B3_ASSERT(false);