From f98374143a44a86f563bd270115fb6a7a093908e Mon Sep 17 00:00:00 2001 From: Irlan <-> Date: Mon, 8 Oct 2018 16:18:28 -0300 Subject: [PATCH] refactoring --- examples/testbed/framework/body_dragger.cpp | 98 ++++++++ examples/testbed/framework/body_dragger.h | 72 ++++++ examples/testbed/framework/cloth_dragger.cpp | 184 ++++++++++++++ .../cloth_dragger.h} | 64 +++-- examples/testbed/framework/test.cpp | 29 +-- examples/testbed/framework/test.h | 29 +-- examples/testbed/framework/test_entries.cpp | 1 - examples/testbed/tests/pinned_cloth.h | 87 +++++-- examples/testbed/tests/ray_cast.h | 4 +- examples/testbed/tests/self_collision.h | 83 ++++++- examples/testbed/tests/shirt.h | 63 ++++- examples/testbed/tests/table_cloth.h | 82 ++++++- examples/testbed/tests/tension_mapping.h | 75 +++++- include/bounce/bounce.h | 23 +- include/bounce/{dynamics => }/cloth/cloth.h | 72 +++--- .../cloth/cloth_contact_solver.h | 0 .../bounce/{dynamics => }/cloth/cloth_mesh.h | 0 .../{dynamics => }/cloth/cloth_solver.h | 0 .../bounce/{dynamics => }/cloth/dense_vec3.h | 0 .../bounce/{dynamics => }/cloth/diag_mat33.h | 2 +- include/bounce/{dynamics => }/cloth/force.h | 2 - include/bounce/{ => cloth}/garment/garment.h | 2 +- .../bounce/{ => cloth}/garment/garment_mesh.h | 0 .../{ => cloth}/garment/sewing_pattern.h | 0 .../bounce/{dynamics => }/cloth/particle.h | 4 +- .../{dynamics => }/cloth/sparse_sym_mat33.h | 4 +- .../{dynamics => }/cloth/spring_force.h | 2 +- include/bounce/controllers/body_dragger.h | 129 ---------- include/bounce/controllers/cloth_dragger.h | 224 ------------------ include/bounce/dynamics/cloth/bend_force.h | 158 ------------ include/bounce/dynamics/world.h | 49 +--- include/bounce/dynamics/world_listeners.h | 7 - include/bounce/{dynamics => }/rope/rope.h | 0 include/bounce/{dynamics => rope}/spatial.h | 0 premake5.lua | 6 + src/bounce/{dynamics => }/cloth/cloth.cpp | 82 +++---- .../cloth/cloth_contact_solver.cpp | 8 +- .../{dynamics => }/cloth/cloth_mesh.cpp | 8 +- .../{dynamics => }/cloth/cloth_solver.cpp | 22 +- src/bounce/{dynamics => }/cloth/force.cpp | 18 +- .../{ => cloth}/garment/garment_mesh.cpp | 6 +- src/bounce/{dynamics => }/cloth/particle.cpp | 10 +- .../{dynamics => }/cloth/spring_force.cpp | 10 +- src/bounce/dynamics/cloth/bend_force.cpp | 128 ---------- src/bounce/dynamics/world.cpp | 90 +------ src/bounce/{dynamics => }/rope/rope.cpp | 4 +- test/ignore.txt | 0 47 files changed, 895 insertions(+), 1046 deletions(-) create mode 100644 examples/testbed/framework/body_dragger.cpp create mode 100644 examples/testbed/framework/body_dragger.h create mode 100644 examples/testbed/framework/cloth_dragger.cpp rename examples/testbed/{tests/cloth_test.h => framework/cloth_dragger.h} (52%) rename include/bounce/{dynamics => }/cloth/cloth.h (85%) rename include/bounce/{dynamics => }/cloth/cloth_contact_solver.h (100%) rename include/bounce/{dynamics => }/cloth/cloth_mesh.h (100%) rename include/bounce/{dynamics => }/cloth/cloth_solver.h (100%) rename include/bounce/{dynamics => }/cloth/dense_vec3.h (100%) rename include/bounce/{dynamics => }/cloth/diag_mat33.h (98%) rename include/bounce/{dynamics => }/cloth/force.h (97%) rename include/bounce/{ => cloth}/garment/garment.h (98%) rename include/bounce/{ => cloth}/garment/garment_mesh.h (100%) rename include/bounce/{ => cloth}/garment/sewing_pattern.h (100%) rename include/bounce/{dynamics => }/cloth/particle.h (99%) rename include/bounce/{dynamics => }/cloth/sparse_sym_mat33.h (98%) rename include/bounce/{dynamics => }/cloth/spring_force.h (98%) delete mode 100644 include/bounce/controllers/body_dragger.h delete mode 100644 include/bounce/controllers/cloth_dragger.h delete mode 100644 include/bounce/dynamics/cloth/bend_force.h rename include/bounce/{dynamics => }/rope/rope.h (100%) rename include/bounce/{dynamics => rope}/spatial.h (100%) rename src/bounce/{dynamics => }/cloth/cloth.cpp (92%) rename src/bounce/{dynamics => }/cloth/cloth_contact_solver.cpp (99%) rename src/bounce/{dynamics => }/cloth/cloth_mesh.cpp (95%) rename src/bounce/{dynamics => }/cloth/cloth_solver.cpp (96%) rename src/bounce/{dynamics => }/cloth/force.cpp (79%) rename src/bounce/{ => cloth}/garment/garment_mesh.cpp (97%) rename src/bounce/{dynamics => }/cloth/particle.cpp (91%) rename src/bounce/{dynamics => }/cloth/spring_force.cpp (91%) delete mode 100644 src/bounce/dynamics/cloth/bend_force.cpp rename src/bounce/{dynamics => }/rope/rope.cpp (99%) delete mode 100644 test/ignore.txt diff --git a/examples/testbed/framework/body_dragger.cpp b/examples/testbed/framework/body_dragger.cpp new file mode 100644 index 0000000..58456a5 --- /dev/null +++ b/examples/testbed/framework/body_dragger.cpp @@ -0,0 +1,98 @@ +/* +* 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 + +b3BodyDragger::b3BodyDragger(b3Ray3* ray, b3World* world) +{ + m_ray = ray; + m_world = world; + m_shape = nullptr; + m_mouseJoint = nullptr; +} + +b3BodyDragger::~b3BodyDragger() +{ + +} + +bool b3BodyDragger::StartDragging() +{ + B3_ASSERT(IsDragging() == false); + + b3RayCastSingleOutput out; + if (m_world->RayCastSingle(&out, m_ray->A(), m_ray->B()) == false) + { + return false; + } + + m_x = out.fraction; + m_shape = out.shape; + + b3BodyDef bd; + b3Body* groundBody = m_world->CreateBody(bd); + + b3Body* body = m_shape->GetBody(); + body->SetAwake(true); + + b3MouseJointDef jd; + jd.bodyA = groundBody; + jd.bodyB = body; + jd.target = out.point; + jd.maxForce = 2000.0f * body->GetMass(); + + m_mouseJoint = (b3MouseJoint*)m_world->CreateJoint(jd); + + m_p = body->GetLocalPoint(out.point); + + return true; +} + +void b3BodyDragger::Drag() +{ + B3_ASSERT(IsDragging() == true); + m_mouseJoint->SetTarget(GetPointB()); +} + +void b3BodyDragger::StopDragging() +{ + B3_ASSERT(IsDragging() == true); + b3Body* groundBody = m_mouseJoint->GetBodyA(); + m_world->DestroyJoint(m_mouseJoint); + m_mouseJoint = nullptr; + m_world->DestroyBody(groundBody); + m_shape = nullptr; +} + +b3Body* b3BodyDragger::GetBody() const +{ + B3_ASSERT(IsDragging() == true); + return m_shape->GetBody(); +} + +b3Vec3 b3BodyDragger::GetPointA() const +{ + B3_ASSERT(IsDragging() == true); + return m_shape->GetBody()->GetWorldPoint(m_p); +} + +b3Vec3 b3BodyDragger::GetPointB() const +{ + B3_ASSERT(IsDragging() == true); + return (1.0f - m_x) * m_ray->A() + m_x * m_ray->B(); +} \ No newline at end of file diff --git a/examples/testbed/framework/body_dragger.h b/examples/testbed/framework/body_dragger.h new file mode 100644 index 0000000..10d5a66 --- /dev/null +++ b/examples/testbed/framework/body_dragger.h @@ -0,0 +1,72 @@ +/* +* 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_BODY_DRAGGER_H +#define B3_BODY_DRAGGER_H + +#include +#include +#include +#include +#include +#include + +// A body shape dragger. +class b3BodyDragger +{ +public: + b3BodyDragger(b3Ray3* ray, b3World* world); + ~b3BodyDragger(); + + bool StartDragging(); + + void Drag(); + + void StopDragging(); + + bool IsDragging() const; + + b3Ray3* GetRay() const; + + b3Body* GetBody() const; + + b3Vec3 GetPointA() const; + + b3Vec3 GetPointB() const; +private: + b3Ray3 * m_ray; + float32 m_x; + + b3World* m_world; + + b3Shape* m_shape; + b3Vec3 m_p; + b3MouseJoint* m_mouseJoint; +}; + +inline bool b3BodyDragger::IsDragging() const +{ + return m_shape != nullptr; +} + +inline b3Ray3* b3BodyDragger::GetRay() const +{ + return m_ray; +} + +#endif \ No newline at end of file diff --git a/examples/testbed/framework/cloth_dragger.cpp b/examples/testbed/framework/cloth_dragger.cpp new file mode 100644 index 0000000..ea228ba --- /dev/null +++ b/examples/testbed/framework/cloth_dragger.cpp @@ -0,0 +1,184 @@ +/* +* 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 + +b3ClothDragger::b3ClothDragger(b3Ray3* ray, b3Cloth* cloth) +{ + m_spring = false; + m_ray = ray; + m_cloth = cloth; + m_triangle = nullptr; +} + +b3ClothDragger::~b3ClothDragger() +{ + +} + +bool b3ClothDragger::StartDragging() +{ + B3_ASSERT(IsDragging() == false); + + b3ClothRayCastSingleOutput rayOut; + if (m_cloth->RayCastSingle(&rayOut, m_ray->A(), m_ray->B()) == false) + { + return false; + } + + m_mesh = m_cloth->GetMesh(); + m_triangle = m_mesh->triangles + rayOut.triangle; + m_x = rayOut.fraction; + + b3Particle* p1 = m_cloth->GetVertexParticle(m_triangle->v1); + b3Particle* p2 = m_cloth->GetVertexParticle(m_triangle->v2); + b3Particle* p3 = m_cloth->GetVertexParticle(m_triangle->v3); + + b3Vec3 v1 = p1->GetPosition(); + b3Vec3 v2 = p2->GetPosition(); + b3Vec3 v3 = p3->GetPosition(); + + b3Vec3 B = GetPointB(); + + float32 wABC[4]; + b3BarycentricCoordinates(wABC, v1, v2, v3, B); + + if (wABC[3] > B3_EPSILON) + { + m_u = wABC[0] / wABC[3]; + m_v = wABC[1] / wABC[3]; + } + else + { + m_u = m_v = 0.0f; + } + + if (m_spring) + { + b3ParticleDef pd; + pd.type = e_staticParticle; + pd.position = B; + + m_particle = m_cloth->CreateParticle(pd); + + { + b3SpringForceDef sfd; + sfd.p1 = m_particle; + sfd.p2 = p1; + sfd.restLength = 0.0f; + sfd.structural = 10000.0f; + m_s1 = (b3SpringForce*)m_cloth->CreateForce(sfd); + } + + { + b3SpringForceDef sfd; + sfd.p1 = m_particle; + sfd.p2 = p2; + sfd.restLength = 0.0f; + sfd.structural = 10000.0f; + m_s2 = (b3SpringForce*)m_cloth->CreateForce(sfd); + } + + { + b3SpringForceDef sfd; + sfd.p1 = m_particle; + sfd.p2 = p3; + sfd.restLength = 0.0f; + sfd.structural = 10000.0f; + m_s3 = (b3SpringForce*)m_cloth->CreateForce(sfd); + } + } + else + { + m_t1 = p1->GetType(); + p1->SetType(e_staticParticle); + + m_t2 = p2->GetType(); + p2->SetType(e_staticParticle); + + m_t3 = p3->GetType(); + p3->SetType(e_staticParticle); + } + + return true; +} + +void b3ClothDragger::Drag() +{ + B3_ASSERT(IsDragging() == true); + + b3Vec3 A = GetPointA(); + b3Vec3 B = GetPointB(); + + b3Vec3 dx = B - A; + + if (m_spring) + { + m_particle->SetPosition(B); + } + else + { + b3Particle* p1 = m_cloth->GetVertexParticle(m_triangle->v1); + p1->ApplyTranslation(dx); + + b3Particle* p2 = m_cloth->GetVertexParticle(m_triangle->v2); + p2->ApplyTranslation(dx); + + b3Particle* p3 = m_cloth->GetVertexParticle(m_triangle->v3); + p3->ApplyTranslation(dx); + } +} + +void b3ClothDragger::StopDragging() +{ + B3_ASSERT(IsDragging() == true); + + if (m_spring) + { + m_cloth->DestroyForce(m_s1); + m_cloth->DestroyForce(m_s2); + m_cloth->DestroyForce(m_s3); + m_cloth->DestroyParticle(m_particle); + } + else + { + m_cloth->GetVertexParticle(m_triangle->v1)->SetType(m_t1); + m_cloth->GetVertexParticle(m_triangle->v2)->SetType(m_t2); + m_cloth->GetVertexParticle(m_triangle->v3)->SetType(m_t3); + } + + m_triangle = nullptr; +} + +b3Vec3 b3ClothDragger::GetPointA() const +{ + B3_ASSERT(IsDragging() == true); + + b3Vec3 A = m_cloth->GetVertexParticle(m_triangle->v1)->GetPosition(); + b3Vec3 B = m_cloth->GetVertexParticle(m_triangle->v2)->GetPosition(); + b3Vec3 C = m_cloth->GetVertexParticle(m_triangle->v3)->GetPosition(); + + return m_u * A + m_v * B + (1.0f - m_u - m_v) * C; +} + +b3Vec3 b3ClothDragger::GetPointB() const +{ + B3_ASSERT(IsDragging() == true); + return (1.0f - m_x) * m_ray->A() + m_x * m_ray->B(); +} \ No newline at end of file diff --git a/examples/testbed/tests/cloth_test.h b/examples/testbed/framework/cloth_dragger.h similarity index 52% rename from examples/testbed/tests/cloth_test.h rename to examples/testbed/framework/cloth_dragger.h index 3f95cce..5058f20 100644 --- a/examples/testbed/tests/cloth_test.h +++ b/examples/testbed/framework/cloth_dragger.h @@ -16,37 +16,55 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#ifndef CLOTH_TESH_H -#define CLOTH_TESH_H +#ifndef B3_CLOTH_DRAGGER_H +#define B3_CLOTH_DRAGGER_H -class ClothTest : public Test +#include +#include +#include +#include +#include + +// A cloth triangle dragger. +class b3ClothDragger { public: - ClothTest() - { - m_world.SetGravity(b3Vec3(0.0f, -10.0f, 0.0f)); - m_cloth = nullptr; - } + b3ClothDragger(b3Ray3* ray, b3Cloth* cloth); + ~b3ClothDragger(); - void Step() - { - Test::Step(); + bool IsDragging() const; - m_cloth->Draw(); + bool StartDragging(); - if (m_clothDragger.IsDragging() == true) - { - g_draw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white); - } + void Drag(); + + void StopDragging(); + + b3Vec3 GetPointA() const; + + b3Vec3 GetPointB() const; +private: + b3Ray3* m_ray; + float32 m_x; - extern u32 b3_clothSolverIterations; - g_draw->DrawString(b3Color_white, "Iterations = %u", b3_clothSolverIterations); - - float32 E = m_cloth->GetEnergy(); - g_draw->DrawString(b3Color_white, "E = %f", E); - } - b3Cloth* m_cloth; + const b3ClothMesh* m_mesh; + b3ClothMeshTriangle* m_triangle; + float32 m_u, m_v; + + bool m_spring; + + b3Particle* m_particle; + b3SpringForce* m_s1; + b3SpringForce* m_s2; + b3SpringForce* m_s3; + + b3ParticleType m_t1, m_t2, m_t3; }; +inline bool b3ClothDragger::IsDragging() const +{ + return m_triangle != nullptr; +} + #endif \ No newline at end of file diff --git a/examples/testbed/framework/test.cpp b/examples/testbed/framework/test.cpp index befad6c..12ca6db 100644 --- a/examples/testbed/framework/test.cpp +++ b/examples/testbed/framework/test.cpp @@ -18,7 +18,6 @@ #include #include -#include extern u32 b3_allocCalls, b3_maxAllocCalls; extern u32 b3_convexCalls, b3_convexCacheHits; @@ -36,8 +35,7 @@ void b3EndProfileScope() } Test::Test() : - m_bodyDragger(&m_ray, &m_world), - m_clothDragger(&m_ray, &m_world) + m_bodyDragger(&m_ray, &m_world) { b3Draw_draw = g_draw; b3_convexCache = g_testSettings->convexCache; @@ -115,11 +113,6 @@ void Test::Step() g_draw->DrawString(b3Color_white, "Convex Cache Hits %d (%f)", b3_convexCacheHits, convexCacheHitRatio); g_draw->DrawString(b3Color_white, "Frame Allocations %d (%d)", b3_allocCalls, b3_maxAllocCalls); } - - if (m_clothDragger.IsDragging() == true) - { - g_draw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white); - } } void Test::MouseMove(const b3Ray3& pw) @@ -130,11 +123,6 @@ void Test::MouseMove(const b3Ray3& pw) { m_bodyDragger.Drag(); } - - if (m_clothDragger.IsDragging() == true) - { - m_clothDragger.Drag(); - } } void Test::MouseLeftDown(const b3Ray3& pw) @@ -146,14 +134,6 @@ void Test::MouseLeftDown(const b3Ray3& pw) BeginDragging(); } } - - if (m_clothDragger.IsDragging() == false) - { - if (m_clothDragger.StartDragging() == true) - { - BeginDragging(); - } - } } void Test::MouseLeftUp(const b3Ray3& pw) @@ -164,11 +144,4 @@ void Test::MouseLeftUp(const b3Ray3& pw) EndDragging(); } - - if (m_clothDragger.IsDragging() == true) - { - m_clothDragger.StopDragging(); - - EndDragging(); - } } \ No newline at end of file diff --git a/examples/testbed/framework/test.h b/examples/testbed/framework/test.h index 481c2ea..4171804 100644 --- a/examples/testbed/framework/test.h +++ b/examples/testbed/framework/test.h @@ -22,6 +22,9 @@ #include #include +#include +#include + #include #include @@ -33,27 +36,6 @@ inline float32 RandomFloat(float32 a, float32 b) return a + r; } -class RayCastListener : public b3RayCastListener -{ -public: - float32 ReportShape(b3Shape* shape, const b3Vec3& point, const b3Vec3& normal, float32 fraction) - { - hit.shape = shape; - hit.point = point; - hit.normal = normal; - hit.fraction = fraction; - return 1.0f; - } - - float32 ReportCloth(b3Shape* shape, const b3Vec3& point, const b3Vec3& normal, float32 fraction) - { - B3_ASSERT(false); - return 1.0f; - } - - b3RayCastSingleShapeOutput hit; -}; - class Test : public b3ContactListener { public: @@ -77,10 +59,9 @@ public: void EndContact(b3Contact* c) override { } void PreSolve(b3Contact* c) override { } - b3World m_world; - b3Ray3 m_ray; - b3ClothDragger m_clothDragger; + + b3World m_world; b3BodyDragger m_bodyDragger; b3BoxHull m_groundHull; diff --git a/examples/testbed/framework/test_entries.cpp b/examples/testbed/framework/test_entries.cpp index 69737b1..6da7e6f 100644 --- a/examples/testbed/framework/test_entries.cpp +++ b/examples/testbed/framework/test_entries.cpp @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include diff --git a/examples/testbed/tests/pinned_cloth.h b/examples/testbed/tests/pinned_cloth.h index dfafeab..08fe1e8 100644 --- a/examples/testbed/tests/pinned_cloth.h +++ b/examples/testbed/tests/pinned_cloth.h @@ -19,7 +19,7 @@ #ifndef PINNED_CLOTH_H #define PINNED_CLOTH_H -class PinnedCloth : public ClothTest +class PinnedCloth : public Test { public: PinnedCloth() : m_rectangleGarment(5.0f, 5.0f) @@ -30,21 +30,26 @@ public: // Create 3D mesh m_rectangleClothMesh.Set(&m_rectangleGarmentMesh); - // - b3Mat33 dq = b3Mat33RotationX(0.5f * B3_PI); + // Rotate the mesh + b3Mat33 rotation = b3Mat33RotationX(0.5f * B3_PI); for (u32 i = 0; i < m_rectangleClothMesh.vertexCount; ++i) { - m_rectangleClothMesh.vertices[i] = dq * m_rectangleClothMesh.vertices[i]; + m_rectangleClothMesh.vertices[i] = rotation * m_rectangleClothMesh.vertices[i]; } + // Create cloth b3ClothDef def; def.mesh = &m_rectangleClothMesh; def.density = 0.2f; def.structural = 100000.0f; def.damping = 0.0f; - m_cloth = m_world.CreateCloth(def); + m_cloth = new b3Cloth(def); + m_cloth->SetGravity(b3Vec3(0.0f, -9.8f, 0.0f)); + m_cloth->SetWorld(&m_world); + + // Freeze some particles b3AABB3 aabb1; aabb1.m_lower.Set(-5.0f, -1.0f, -6.0f); aabb1.m_upper.Set(5.0f, 1.0f, -4.0f); @@ -65,23 +70,70 @@ public: p->SetType(e_staticParticle); } } + + m_clothDragger = new b3ClothDragger(&m_ray, m_cloth); + } + ~PinnedCloth() + { + delete m_clothDragger; + delete m_cloth; + } + + void Step() + { + Test::Step(); + + m_cloth->Step(g_testSettings->inv_hertz); + + m_cloth->Draw(); + + if (m_clothDragger->IsDragging()) { - b3BodyDef bd; - bd.type = e_dynamicBody; - bd.position.Set(0.0f, 5.0f, 0.0f); + b3Vec3 pA = m_clothDragger->GetPointA(); + b3Vec3 pB = m_clothDragger->GetPointB(); - b3Body* b = m_world.CreateBody(bd); + g_draw->DrawPoint(pA, 2.0f, b3Color_green); - b3SphereShape sphere; - sphere.m_center.SetZero(); - sphere.m_radius = 2.0f; + g_draw->DrawPoint(pB, 2.0f, b3Color_green); - b3ShapeDef sd; - sd.shape = &sphere; - sd.density = 1.0f; + g_draw->DrawSegment(pA, pB, b3Color_white); + } - b3Shape* s = b->CreateShape(sd); + extern u32 b3_clothSolverIterations; + g_draw->DrawString(b3Color_white, "Iterations = %d", b3_clothSolverIterations); + + float32 E = m_cloth->GetEnergy(); + g_draw->DrawString(b3Color_white, "E = %f", E); + } + + void MouseMove(const b3Ray3& pw) + { + Test::MouseMove(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->Drag(); + } + } + + void MouseLeftDown(const b3Ray3& pw) + { + Test::MouseLeftDown(pw); + + if (m_clothDragger->IsDragging() == false) + { + m_clothDragger->StartDragging(); + } + } + + void MouseLeftUp(const b3Ray3& pw) + { + Test::MouseLeftUp(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->StopDragging(); } } @@ -93,6 +145,9 @@ public: b3RectangleGarment m_rectangleGarment; b3GarmentMesh m_rectangleGarmentMesh; b3GarmentClothMesh m_rectangleClothMesh; + + b3Cloth* m_cloth; + b3ClothDragger* m_clothDragger; }; #endif \ No newline at end of file diff --git a/examples/testbed/tests/ray_cast.h b/examples/testbed/tests/ray_cast.h index 3b7e7ed..610627f 100644 --- a/examples/testbed/tests/ray_cast.h +++ b/examples/testbed/tests/ray_cast.h @@ -178,8 +178,8 @@ public: void CastRay(const b3Vec3 p1, const b3Vec3 p2) const { - b3RayCastSingleShapeOutput out; - if (m_world.RayCastSingleShape(&out, p1, p2)) + b3RayCastSingleOutput out; + if (m_world.RayCastSingle(&out, p1, p2)) { g_draw->DrawSegment(p1, out.point, b3Color_green); diff --git a/examples/testbed/tests/self_collision.h b/examples/testbed/tests/self_collision.h index 9a3ed52..3135b4f 100644 --- a/examples/testbed/tests/self_collision.h +++ b/examples/testbed/tests/self_collision.h @@ -19,7 +19,7 @@ #ifndef SELF_COLLISION_H #define SELF_COLLISION_H -class SelfCollision : public ClothTest +class SelfCollision : public Test { public: SelfCollision() : m_rectangleGarment(5.0f, 5.0f) @@ -30,19 +30,24 @@ public: // Create 3D mesh m_rectangleClothMesh.Set(&m_rectangleGarmentMesh); - b3Mat33 Rx = b3Mat33RotationX(0.5f * B3_PI); + // Rotate and translate the mesh + b3Mat33 rotation = b3Mat33RotationX(0.5f * B3_PI); for (u32 i = 0; i < m_rectangleClothMesh.vertexCount; ++i) { - m_rectangleClothMesh.vertices[i] = Rx * m_rectangleClothMesh.vertices[i]; + m_rectangleClothMesh.vertices[i] = rotation * m_rectangleClothMesh.vertices[i]; m_rectangleClothMesh.vertices[i].y += 5.0f; } + // Create cloth b3ClothDef def; def.mesh = &m_rectangleClothMesh; def.density = 1.0f; def.structural = 100000.0f; - m_cloth = m_world.CreateCloth(def); + m_cloth = new b3Cloth(def); + + m_cloth->SetGravity(b3Vec3(0.0f, -9.8f, 0.0f)); + m_cloth->SetWorld(&m_world); for (b3Particle* p = m_cloth->GetParticleList().m_head; p; p = p->GetNext()) { @@ -67,6 +72,71 @@ public: b->CreateShape(sd); } + + m_clothDragger = new b3ClothDragger(&m_ray, m_cloth); + } + + ~SelfCollision() + { + delete m_cloth; + delete m_clothDragger; + } + + void Step() + { + Test::Step(); + + m_cloth->Step(g_testSettings->inv_hertz); + + m_cloth->Draw(); + + if (m_clothDragger->IsDragging()) + { + b3Vec3 pA = m_clothDragger->GetPointA(); + b3Vec3 pB = m_clothDragger->GetPointB(); + + g_draw->DrawPoint(pA, 2.0f, b3Color_green); + + g_draw->DrawPoint(pB, 2.0f, b3Color_green); + + g_draw->DrawSegment(pA, pB, b3Color_white); + } + + extern u32 b3_clothSolverIterations; + g_draw->DrawString(b3Color_white, "Iterations = %d", b3_clothSolverIterations); + + float32 E = m_cloth->GetEnergy(); + g_draw->DrawString(b3Color_white, "E = %f", E); + } + + void MouseMove(const b3Ray3& pw) + { + Test::MouseMove(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->Drag(); + } + } + + void MouseLeftDown(const b3Ray3& pw) + { + Test::MouseLeftDown(pw); + + if (m_clothDragger->IsDragging() == false) + { + m_clothDragger->StartDragging(); + } + } + + void MouseLeftUp(const b3Ray3& pw) + { + Test::MouseLeftUp(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->StopDragging(); + } } static Test* Create() @@ -77,6 +147,9 @@ public: b3RectangleGarment m_rectangleGarment; b3GarmentMesh m_rectangleGarmentMesh; b3GarmentClothMesh m_rectangleClothMesh; -}; + + b3Cloth* m_cloth; + b3ClothDragger* m_clothDragger; + }; #endif \ No newline at end of file diff --git a/examples/testbed/tests/shirt.h b/examples/testbed/tests/shirt.h index 158b8f1..1d76f1a 100644 --- a/examples/testbed/tests/shirt.h +++ b/examples/testbed/tests/shirt.h @@ -19,7 +19,7 @@ #ifndef SHIRT_H #define SHIRT_H -class Shirt : public ClothTest +class Shirt : public Test { public: Shirt() @@ -57,7 +57,63 @@ public: def.density = 0.2f; def.structural = 10000.0f; - m_cloth = m_world.CreateCloth(def); + m_cloth = new b3Cloth(def); + + m_cloth->SetGravity(b3Vec3(0.0f, -9.8f, 0.0f)); + m_cloth->SetWorld(&m_world); + + m_clothDragger = new b3ClothDragger(&m_ray, m_cloth); + } + + ~Shirt() + { + delete m_clothDragger; + delete m_cloth; + } + + void Step() + { + Test::Step(); + + m_cloth->Step(g_testSettings->inv_hertz); + + m_cloth->Draw(); + + extern u32 b3_clothSolverIterations; + g_draw->DrawString(b3Color_white, "Iterations = %d", b3_clothSolverIterations); + + float32 E = m_cloth->GetEnergy(); + g_draw->DrawString(b3Color_white, "E = %f", E); + } + + void MouseMove(const b3Ray3& pw) + { + Test::MouseMove(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->Drag(); + } + } + + void MouseLeftDown(const b3Ray3& pw) + { + Test::MouseLeftDown(pw); + + if (m_clothDragger->IsDragging() == false) + { + m_clothDragger->StartDragging(); + } + } + + void MouseLeftUp(const b3Ray3& pw) + { + Test::MouseLeftUp(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->StopDragging(); + } } static Test* Create() @@ -68,6 +124,9 @@ public: b3ShirtGarment m_shirtGarment; b3GarmentMesh m_shirtGarmentMesh; b3GarmentClothMesh m_shirtClothMesh; + + b3Cloth* m_cloth; + b3ClothDragger* m_clothDragger; }; #endif \ No newline at end of file diff --git a/examples/testbed/tests/table_cloth.h b/examples/testbed/tests/table_cloth.h index c0ec318..af43732 100644 --- a/examples/testbed/tests/table_cloth.h +++ b/examples/testbed/tests/table_cloth.h @@ -19,7 +19,7 @@ #ifndef TABLE_CLOTH_H #define TABLE_CLOTH_H -class TableCloth : public ClothTest +class TableCloth : public Test { public: TableCloth() : m_rectangleGarment(5.0f, 5.0f) @@ -30,14 +30,15 @@ public: // Create 3D mesh m_rectangleClothMesh.Set(&m_rectangleGarmentMesh); - // - b3Mat33 dq = b3Mat33RotationX(0.5f * B3_PI); + // Rotate the mesh + b3Mat33 rotation = b3Mat33RotationX(0.5f * B3_PI); for (u32 i = 0; i < m_rectangleClothMesh.vertexCount; ++i) { - m_rectangleClothMesh.vertices[i] = dq * m_rectangleClothMesh.vertices[i]; + m_rectangleClothMesh.vertices[i] = rotation * m_rectangleClothMesh.vertices[i]; m_rectangleClothMesh.vertices[i].y += 5.0f; } + // Create cloth b3ClothDef def; def.mesh = &m_rectangleClothMesh; def.density = 0.2f; @@ -45,7 +46,10 @@ public: def.structural = 10000.0f; def.damping = 0.0f; - m_cloth = m_world.CreateCloth(def); + m_cloth = new b3Cloth(def); + + m_cloth->SetGravity(b3Vec3(0.0f, -9.8f, 0.0f)); + m_cloth->SetWorld(&m_world); for (b3Particle* p = m_cloth->GetParticleList().m_head; p; p = p->GetNext()) { @@ -71,6 +75,71 @@ public: b->CreateShape(sd); } + + m_clothDragger = new b3ClothDragger(&m_ray, m_cloth); + } + + ~TableCloth() + { + delete m_clothDragger; + delete m_cloth; + } + + void Step() + { + Test::Step(); + + m_cloth->Step(g_testSettings->inv_hertz); + + m_cloth->Draw(); + + if (m_clothDragger->IsDragging()) + { + b3Vec3 pA = m_clothDragger->GetPointA(); + b3Vec3 pB = m_clothDragger->GetPointB(); + + g_draw->DrawPoint(pA, 2.0f, b3Color_green); + + g_draw->DrawPoint(pB, 2.0f, b3Color_green); + + g_draw->DrawSegment(pA, pB, b3Color_white); + } + + extern u32 b3_clothSolverIterations; + g_draw->DrawString(b3Color_white, "Iterations = %d", b3_clothSolverIterations); + + float32 E = m_cloth->GetEnergy(); + g_draw->DrawString(b3Color_white, "E = %f", E); + } + + void MouseMove(const b3Ray3& pw) + { + Test::MouseMove(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->Drag(); + } + } + + void MouseLeftDown(const b3Ray3& pw) + { + Test::MouseLeftDown(pw); + + if (m_clothDragger->IsDragging() == false) + { + m_clothDragger->StartDragging(); + } + } + + void MouseLeftUp(const b3Ray3& pw) + { + Test::MouseLeftUp(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->StopDragging(); + } } static Test* Create() @@ -82,6 +151,9 @@ public: b3GarmentMesh m_rectangleGarmentMesh; b3GarmentClothMesh m_rectangleClothMesh; + b3Cloth* m_cloth; + b3ClothDragger* m_clothDragger; + b3QHull m_tableHull; }; diff --git a/examples/testbed/tests/tension_mapping.h b/examples/testbed/tests/tension_mapping.h index 463113d..49d8d23 100644 --- a/examples/testbed/tests/tension_mapping.h +++ b/examples/testbed/tests/tension_mapping.h @@ -55,7 +55,7 @@ static inline b3Color Color(float32 x, float32 a, float32 b) return c; } -class TensionMapping : public ClothTest +class TensionMapping : public Test { public: TensionMapping() : m_rectangleGarment(5.0f, 5.0f) @@ -66,20 +66,25 @@ public: // Create 3D mesh m_rectangleClothMesh.Set(&m_rectangleGarmentMesh); - // - b3Mat33 dq = b3Mat33RotationX(0.5f * B3_PI); + // Rotate the mesh + b3Mat33 rotation = b3Mat33RotationX(0.5f * B3_PI); for (u32 i = 0; i < m_rectangleClothMesh.vertexCount; ++i) { - m_rectangleClothMesh.vertices[i] = dq * m_rectangleClothMesh.vertices[i]; + m_rectangleClothMesh.vertices[i] = rotation * m_rectangleClothMesh.vertices[i]; } + // Create cloth b3ClothDef def; def.mesh = &m_rectangleClothMesh; def.density = 0.2f; def.structural = 10000.0f; - m_cloth = m_world.CreateCloth(def); + m_cloth = new b3Cloth(def); + m_cloth->SetGravity(b3Vec3(0.0f, -9.8f, 0.0f)); + m_cloth->SetWorld(&m_world); + + // Freeze some particles b3AABB3 aabb; aabb.m_lower.Set(-5.0f, -1.0f, -6.0f); aabb.m_upper.Set(5.0f, 1.0f, -4.0f); @@ -91,12 +96,22 @@ public: p->SetType(e_staticParticle); } } + + m_clothDragger = new b3ClothDragger(&m_ray, m_cloth); + } + + ~TensionMapping() + { + delete m_clothDragger; + delete m_cloth; } void Step() { Test::Step(); + m_cloth->Step(g_testSettings->inv_hertz); + const b3ClothMesh* mesh = m_cloth->GetMesh(); b3StackArray tension; @@ -120,9 +135,9 @@ public: } } - for (u32 i = 0; i < m_rectangleClothMesh.triangleCount; ++i) + for (u32 i = 0; i < mesh->triangleCount; ++i) { - b3ClothMeshTriangle* t = m_rectangleClothMesh.triangles + i; + b3ClothMeshTriangle* t = mesh->triangles + i; b3Vec3 v1 = m_cloth->GetVertexParticle(t->v1)->GetPosition(); b3Vec3 v2 = m_cloth->GetVertexParticle(t->v2)->GetPosition(); @@ -154,18 +169,55 @@ public: g_draw->DrawSolidTriangle(n2, v1, v3, v2, color); } - if (m_clothDragger.IsDragging() == true) + if (m_clothDragger->IsDragging()) { - g_draw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white); + b3Vec3 pA = m_clothDragger->GetPointA(); + b3Vec3 pB = m_clothDragger->GetPointB(); + + g_draw->DrawPoint(pA, 2.0f, b3Color_green); + + g_draw->DrawPoint(pB, 2.0f, b3Color_green); + + g_draw->DrawSegment(pA, pB, b3Color_white); } extern u32 b3_clothSolverIterations; - g_draw->DrawString(b3Color_white, "Iterations = %u", b3_clothSolverIterations); + g_draw->DrawString(b3Color_white, "Iterations = %d", b3_clothSolverIterations); float32 E = m_cloth->GetEnergy(); g_draw->DrawString(b3Color_white, "E = %f", E); } + void MouseMove(const b3Ray3& pw) + { + Test::MouseMove(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->Drag(); + } + } + + void MouseLeftDown(const b3Ray3& pw) + { + Test::MouseLeftDown(pw); + + if (m_clothDragger->IsDragging() == false) + { + m_clothDragger->StartDragging(); + } + } + + void MouseLeftUp(const b3Ray3& pw) + { + Test::MouseLeftUp(pw); + + if (m_clothDragger->IsDragging() == true) + { + m_clothDragger->StopDragging(); + } + } + static Test* Create() { return new TensionMapping(); @@ -174,6 +226,9 @@ public: b3RectangleGarment m_rectangleGarment; b3GarmentMesh m_rectangleGarmentMesh; b3GarmentClothMesh m_rectangleClothMesh; + + b3Cloth* m_cloth; + b3ClothDragger* m_clothDragger; }; #endif \ No newline at end of file diff --git a/include/bounce/bounce.h b/include/bounce/bounce.h index 1c4162f..ba4633e 100644 --- a/include/bounce/bounce.h +++ b/include/bounce/bounce.h @@ -56,23 +56,20 @@ #include #include -#include - -#include -#include -#include - -#include -#include -#include -#include - #include #include #include -#include -#include +#include + +#include +#include +#include +#include + +#include +#include +#include #endif \ No newline at end of file diff --git a/include/bounce/dynamics/cloth/cloth.h b/include/bounce/cloth/cloth.h similarity index 85% rename from include/bounce/dynamics/cloth/cloth.h rename to include/bounce/cloth/cloth.h index 6f2d6f5..b8b6a7c 100644 --- a/include/bounce/dynamics/cloth/cloth.h +++ b/include/bounce/cloth/cloth.h @@ -21,6 +21,7 @@ #include #include +#include #include class b3World; @@ -83,7 +84,20 @@ struct b3ClothDef class b3Cloth { public: - // Get the world the cloth belongs to. + b3Cloth(const b3ClothDef& def); + ~b3Cloth(); + + // Set the acceleration of gravity. + void SetGravity(const b3Vec3& gravity); + + // Get the acceleration of gravity. + b3Vec3 GetGravity() const; + + // Attach a world to this cloth. + // The cloth will be able to respond to collisions with the static shapes in the attached world. + void SetWorld(b3World* world); + + // Get the world attached to this cloth. const b3World* GetWorld() const; b3World* GetWorld(); @@ -99,9 +113,6 @@ public: // Destroy a given force. void DestroyForce(b3Force* force); - // Perform a ray cast with the cloth. - void RayCast(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2); - // Perform a ray cast with the cloth. bool RayCastSingle(b3ClothRayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const; @@ -129,20 +140,14 @@ public: // Get the next cloth in the world cloth list. b3Cloth* GetNext(); + // Perform a time step. + void Step(float32 dt); + // Debug draw the cloth using the associated cloth mesh. void Draw() const; private: - friend class b3World; - friend class b3List2; - b3Cloth(const b3ClothDef& def, b3World* world); - ~b3Cloth(); - - // Perform a time step. - // Called only inside b3World. - void Step(float32 dt, const b3Vec3& gravity); - // Compute mass of each particle. void ComputeMass(); @@ -161,6 +166,15 @@ private: // Solve void Solve(float32 dt, const b3Vec3& gravity); + // Stack allocator + b3StackAllocator m_stackAllocator; + + // The world attached to this cloth + b3World* m_world; + + // Gravity acceleration + b3Vec3 m_gravity; + // Proxy mesh const b3ClothMesh* m_mesh; @@ -196,15 +210,23 @@ private: // List of triangle contacts b3List2 m_triangleContactList; - - // The parent world of this cloth. - b3World* m_world; - - // Links to the world cloth list. - b3Cloth* m_prev; - b3Cloth* m_next; }; +inline void b3Cloth::SetGravity(const b3Vec3& gravity) +{ + m_gravity = gravity; +} + +inline b3Vec3 b3Cloth::GetGravity() const +{ + return m_gravity; +} + +inline void b3Cloth::SetWorld(b3World* world) +{ + m_world = world; +} + inline const b3World* b3Cloth::GetWorld() const { return m_world; @@ -230,14 +252,4 @@ inline const b3List2& b3Cloth::GetForceList() const return m_forceList; } -inline const b3Cloth* b3Cloth::GetNext() const -{ - return m_next; -} - -inline b3Cloth* b3Cloth::GetNext() -{ - return m_next; -} - #endif \ No newline at end of file diff --git a/include/bounce/dynamics/cloth/cloth_contact_solver.h b/include/bounce/cloth/cloth_contact_solver.h similarity index 100% rename from include/bounce/dynamics/cloth/cloth_contact_solver.h rename to include/bounce/cloth/cloth_contact_solver.h diff --git a/include/bounce/dynamics/cloth/cloth_mesh.h b/include/bounce/cloth/cloth_mesh.h similarity index 100% rename from include/bounce/dynamics/cloth/cloth_mesh.h rename to include/bounce/cloth/cloth_mesh.h diff --git a/include/bounce/dynamics/cloth/cloth_solver.h b/include/bounce/cloth/cloth_solver.h similarity index 100% rename from include/bounce/dynamics/cloth/cloth_solver.h rename to include/bounce/cloth/cloth_solver.h diff --git a/include/bounce/dynamics/cloth/dense_vec3.h b/include/bounce/cloth/dense_vec3.h similarity index 100% rename from include/bounce/dynamics/cloth/dense_vec3.h rename to include/bounce/cloth/dense_vec3.h diff --git a/include/bounce/dynamics/cloth/diag_mat33.h b/include/bounce/cloth/diag_mat33.h similarity index 98% rename from include/bounce/dynamics/cloth/diag_mat33.h rename to include/bounce/cloth/diag_mat33.h index 34272af..24b62ff 100644 --- a/include/bounce/dynamics/cloth/diag_mat33.h +++ b/include/bounce/cloth/diag_mat33.h @@ -20,7 +20,7 @@ #define B3_DIAG_MAT_33_H #include -#include +#include // Diagonal matrix storing only the diagonal elements of the // original matrix. diff --git a/include/bounce/dynamics/cloth/force.h b/include/bounce/cloth/force.h similarity index 97% rename from include/bounce/dynamics/cloth/force.h rename to include/bounce/cloth/force.h index 87bcb5b..78a18ba 100644 --- a/include/bounce/dynamics/cloth/force.h +++ b/include/bounce/cloth/force.h @@ -29,9 +29,7 @@ class b3Particle; // Force types enum b3ForceType { - e_frictionForce, e_springForce, - e_bendForce, }; struct b3ForceDef diff --git a/include/bounce/garment/garment.h b/include/bounce/cloth/garment/garment.h similarity index 98% rename from include/bounce/garment/garment.h rename to include/bounce/cloth/garment/garment.h index 742ace0..3605584 100644 --- a/include/bounce/garment/garment.h +++ b/include/bounce/cloth/garment/garment.h @@ -19,7 +19,7 @@ #ifndef B3_GARMENT_H #define B3_GARMENT_H -#include +#include struct b3SewingLine { diff --git a/include/bounce/garment/garment_mesh.h b/include/bounce/cloth/garment/garment_mesh.h similarity index 100% rename from include/bounce/garment/garment_mesh.h rename to include/bounce/cloth/garment/garment_mesh.h diff --git a/include/bounce/garment/sewing_pattern.h b/include/bounce/cloth/garment/sewing_pattern.h similarity index 100% rename from include/bounce/garment/sewing_pattern.h rename to include/bounce/cloth/garment/sewing_pattern.h diff --git a/include/bounce/dynamics/cloth/particle.h b/include/bounce/cloth/particle.h similarity index 99% rename from include/bounce/dynamics/cloth/particle.h rename to include/bounce/cloth/particle.h index 11b93d0..7d531dc 100644 --- a/include/bounce/dynamics/cloth/particle.h +++ b/include/bounce/cloth/particle.h @@ -20,9 +20,9 @@ #define B3_PARTICLE_H #include -#include -#include #include +#include +#include class b3Shape; class b3Cloth; diff --git a/include/bounce/dynamics/cloth/sparse_sym_mat33.h b/include/bounce/cloth/sparse_sym_mat33.h similarity index 98% rename from include/bounce/dynamics/cloth/sparse_sym_mat33.h rename to include/bounce/cloth/sparse_sym_mat33.h index e84f69b..6b688d9 100644 --- a/include/bounce/dynamics/cloth/sparse_sym_mat33.h +++ b/include/bounce/cloth/sparse_sym_mat33.h @@ -20,8 +20,8 @@ #define B3_SPARSE_SYM_MAT_33_H #include -#include -#include +#include +#include // An element in a sparse symmetric matrix. struct b3RowValue diff --git a/include/bounce/dynamics/cloth/spring_force.h b/include/bounce/cloth/spring_force.h similarity index 98% rename from include/bounce/dynamics/cloth/spring_force.h rename to include/bounce/cloth/spring_force.h index c5d1bba..c0825b7 100644 --- a/include/bounce/dynamics/cloth/spring_force.h +++ b/include/bounce/cloth/spring_force.h @@ -19,7 +19,7 @@ #ifndef B3_SPRING_FORCE_H #define B3_SPRING_FORCE_H -#include +#include struct b3SpringForceDef : public b3ForceDef { diff --git a/include/bounce/controllers/body_dragger.h b/include/bounce/controllers/body_dragger.h deleted file mode 100644 index 37b28dd..0000000 --- a/include/bounce/controllers/body_dragger.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -* 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_BODY_DRAGGER_H -#define B3_BODY_DRAGGER_H - -#include -#include - -// A body dragger. -class b3BodyDragger -{ -public: - b3BodyDragger(b3Ray3* ray, b3World* world) - { - m_ray = ray; - m_world = world; - m_shape = nullptr; - m_mouseJoint = nullptr; - } - - ~b3BodyDragger() - { - - } - - bool IsDragging() const - { - return m_shape != nullptr; - } - - bool StartDragging() - { - B3_ASSERT(IsDragging() == false); - - b3RayCastSingleShapeOutput out; - if (m_world->RayCastSingleShape(&out, m_ray->A(), m_ray->B()) == false) - { - return false; - } - - m_x = out.fraction; - m_shape = out.shape; - - b3BodyDef bd; - b3Body* groundBody = m_world->CreateBody(bd); - - b3Body* body = m_shape->GetBody(); - body->SetAwake(true); - - b3MouseJointDef jd; - jd.bodyA = groundBody; - jd.bodyB = body; - jd.target = out.point; - jd.maxForce = 2000.0f * body->GetMass(); - - m_mouseJoint = (b3MouseJoint*)m_world->CreateJoint(jd); - - m_p = body->GetLocalPoint(out.point); - - return true; - } - - void Drag() - { - B3_ASSERT(IsDragging() == true); - m_mouseJoint->SetTarget(GetPointB()); - } - - void StopDragging() - { - B3_ASSERT(IsDragging() == true); - b3Body* groundBody = m_mouseJoint->GetBodyA(); - m_world->DestroyJoint(m_mouseJoint); - m_mouseJoint = nullptr; - m_world->DestroyBody(groundBody); - m_shape = nullptr; - } - - b3Ray3* GetRay() const - { - return m_ray; - } - - b3Body* GetBody() const - { - B3_ASSERT(IsDragging() == true); - return m_shape->GetBody(); - } - - b3Vec3 GetPointA() const - { - B3_ASSERT(IsDragging() == true); - return m_shape->GetBody()->GetWorldPoint(m_p); - } - - b3Vec3 GetPointB() const - { - B3_ASSERT(IsDragging() == true); - return (1.0f - m_x) * m_ray->A() + m_x * m_ray->B(); - } - -private: - b3Ray3 * m_ray; - float32 m_x; - - b3World* m_world; - - b3Shape* m_shape; - b3Vec3 m_p; - b3MouseJoint* m_mouseJoint; -}; - -#endif \ No newline at end of file diff --git a/include/bounce/controllers/cloth_dragger.h b/include/bounce/controllers/cloth_dragger.h deleted file mode 100644 index b77060a..0000000 --- a/include/bounce/controllers/cloth_dragger.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -* 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_CLOTH_DRAGGER_H -#define B3_CLOTH_DRAGGER_H - -#include -#include -#include -#include -#include -#include - -// A cloth triangle dragger. -class b3ClothDragger -{ -public: - b3ClothDragger(b3Ray3* ray, b3World* world) - { - m_spring = false; - m_ray = ray; - m_world = world; - m_cloth = nullptr; - } - - ~b3ClothDragger() - { - - } - - bool IsDragging() const - { - return m_cloth != nullptr; - } - - bool StartDragging() - { - B3_ASSERT(IsDragging() == false); - - b3RayCastSingleClothOutput rayOut; - if (m_world->RayCastSingleCloth(&rayOut, m_ray->A(), m_ray->B()) == false) - { - return false; - } - - m_cloth = rayOut.cloth; - m_mesh = m_cloth->GetMesh(); - m_triangle = m_mesh->triangles + rayOut.triangle; - m_x = rayOut.fraction; - - b3Particle* p1 = m_cloth->GetVertexParticle(m_triangle->v1); - b3Particle* p2 = m_cloth->GetVertexParticle(m_triangle->v2); - b3Particle* p3 = m_cloth->GetVertexParticle(m_triangle->v3); - - b3Vec3 v1 = p1->GetPosition(); - b3Vec3 v2 = p2->GetPosition(); - b3Vec3 v3 = p3->GetPosition(); - - b3Vec3 B = GetPointB(); - - float32 wABC[4]; - b3BarycentricCoordinates(wABC, v1, v2, v3, B); - - if (wABC[3] > B3_EPSILON) - { - m_u = wABC[0] / wABC[3]; - m_v = wABC[1] / wABC[3]; - } - else - { - m_u = m_v = 0.0f; - } - - if (m_spring) - { - b3ParticleDef pd; - pd.type = e_staticParticle; - pd.position = B; - - m_particle = m_cloth->CreateParticle(pd); - - { - b3SpringForceDef sfd; - sfd.p1 = m_particle; - sfd.p2 = p1; - sfd.restLength = 0.0f; - sfd.structural = 10000.0f; - m_s1 = (b3SpringForce*)m_cloth->CreateForce(sfd); - } - - { - b3SpringForceDef sfd; - sfd.p1 = m_particle; - sfd.p2 = p2; - sfd.restLength = 0.0f; - sfd.structural = 10000.0f; - m_s2 = (b3SpringForce*)m_cloth->CreateForce(sfd); - } - - { - b3SpringForceDef sfd; - sfd.p1 = m_particle; - sfd.p2 = p3; - sfd.restLength = 0.0f; - sfd.structural = 10000.0f; - m_s3 = (b3SpringForce*)m_cloth->CreateForce(sfd); - } - } - else - { - m_t1 = p1->GetType(); - p1->SetType(e_staticParticle); - - m_t2 = p2->GetType(); - p2->SetType(e_staticParticle); - - m_t3 = p3->GetType(); - p3->SetType(e_staticParticle); - } - - return true; - } - - void Drag() - { - B3_ASSERT(IsDragging() == true); - - b3Vec3 A = GetPointA(); - b3Vec3 B = GetPointB(); - - b3Vec3 dx = B - A; - - if (m_spring) - { - m_particle->SetPosition(B); - } - else - { - b3Particle* p1 = m_cloth->GetVertexParticle(m_triangle->v1); - p1->ApplyTranslation(dx); - - b3Particle* p2 = m_cloth->GetVertexParticle(m_triangle->v2); - p2->ApplyTranslation(dx); - - b3Particle* p3 = m_cloth->GetVertexParticle(m_triangle->v3); - p3->ApplyTranslation(dx); - } - } - - void StopDragging() - { - B3_ASSERT(IsDragging() == true); - - if (m_spring) - { - m_cloth->DestroyForce(m_s1); - m_cloth->DestroyForce(m_s2); - m_cloth->DestroyForce(m_s3); - m_cloth->DestroyParticle(m_particle); - } - else - { - m_cloth->GetVertexParticle(m_triangle->v1)->SetType(m_t1); - m_cloth->GetVertexParticle(m_triangle->v2)->SetType(m_t2); - m_cloth->GetVertexParticle(m_triangle->v3)->SetType(m_t3); - } - - m_cloth = nullptr; - } - - b3Vec3 GetPointA() const - { - B3_ASSERT(IsDragging() == true); - - b3Vec3 A = m_cloth->GetVertexParticle(m_triangle->v1)->GetPosition(); - b3Vec3 B = m_cloth->GetVertexParticle(m_triangle->v2)->GetPosition(); - b3Vec3 C = m_cloth->GetVertexParticle(m_triangle->v3)->GetPosition(); - - return m_u * A + m_v * B + (1.0f - m_u - m_v) * C; - } - - b3Vec3 GetPointB() const - { - B3_ASSERT(IsDragging() == true); - - return (1.0f - m_x) * m_ray->A() + m_x * m_ray->B(); - } -private: - b3Ray3* m_ray; - float32 m_x; - - b3World* m_world; - - b3Cloth* m_cloth; - const b3ClothMesh* m_mesh; - b3ClothMeshTriangle* m_triangle; - float32 m_u, m_v; - - bool m_spring; - - b3Particle* m_particle; - b3SpringForce* m_s1; - b3SpringForce* m_s2; - b3SpringForce* m_s3; - - b3ParticleType m_t1, m_t2, m_t3; -}; - -#endif \ No newline at end of file diff --git a/include/bounce/dynamics/cloth/bend_force.h b/include/bounce/dynamics/cloth/bend_force.h deleted file mode 100644 index 069a88e..0000000 --- a/include/bounce/dynamics/cloth/bend_force.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -* 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/world.h b/include/bounce/dynamics/world.h index 2d30247..88a7510 100644 --- a/include/bounce/dynamics/world.h +++ b/include/bounce/dynamics/world.h @@ -26,17 +26,15 @@ #include #include -struct b3ClothDef; struct b3BodyDef; -class b3Cloth; class b3Body; class b3QueryListener; class b3RayCastListener; class b3ContactListener; class b3ContactFilter; -struct b3RayCastSingleShapeOutput +struct b3RayCastSingleOutput { b3Shape* shape; // shape b3Vec3 point; // intersection point on surface @@ -44,15 +42,6 @@ struct b3RayCastSingleShapeOutput float32 fraction; // time of intersection on segment }; -struct b3RayCastSingleClothOutput -{ - b3Cloth* cloth; // cloth - u32 triangle; // triangle - b3Vec3 point; // intersection point on surface - b3Vec3 normal; // surface normal of intersection - float32 fraction; // time of intersection on segment -}; - // Use a physics world to create/destroy rigid bodies, execute ray cast and volume queries. class b3World { @@ -79,12 +68,6 @@ public: // The acceleration has units of m/s^2. void SetGravity(const b3Vec3& gravity); - // Create a new deformable cloth. - b3Cloth* CreateCloth(const b3ClothDef& def); - - // Destroy an existing deformable cloth. - void DestroyCloth(b3Cloth* cloth); - // Create a new rigid body. b3Body* CreateBody(const b3BodyDef& def); @@ -108,29 +91,14 @@ public: // The ray cast output is the intercepted shape, the intersection // point in world space, the face normal on the shape associated with the point, // and the intersection fraction. - void RayCastShape(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const; + void RayCast(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const; // Perform a ray cast with the world. // If the ray doesn't intersect with a shape in the world then return false. // The ray cast output is the intercepted shape, the intersection // point in world space, the face normal on the shape associated with the point, // and the intersection fraction. - bool RayCastSingleShape(b3RayCastSingleShapeOutput* output, const b3Vec3& p1, const b3Vec3& p2) const; - - // Perform a ray cast with the world. - // The given ray cast listener will be notified when a ray intersects a shape - // in the world. - // The ray cast output is the intercepted cloth, the intersection - // point in world space, the face normal on the cloth associated with the point, - // and the intersection fraction. - void RayCastCloth(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const; - - // Perform a ray cast with the world. - // If the ray doesn't intersect with a cloth in the world then return false. - // The ray cast output is the intercepted cloth, the intersection - // point in world space, the face normal on the cloth associated with the point, - // and the intersection fraction. - bool RayCastSingleCloth(b3RayCastSingleClothOutput* output, const b3Vec3& p1, const b3Vec3& p2) const; + bool RayCastSingle(b3RayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const; // Perform a AABB query with the world. // The query listener will be notified when two shape AABBs are overlapping. @@ -161,8 +129,7 @@ private : e_shapeAddedFlag = 0x0001, e_clearForcesFlag = 0x0002, }; - - friend class b3Cloth; + friend class b3Body; friend class b3Shape; friend class b3Contact; @@ -172,20 +139,16 @@ private : void Solve(float32 dt, u32 velocityIterations, u32 positionIterations); - void StepCloth(float32 dt); - bool m_sleeping; bool m_warmStarting; u32 m_flags; b3Vec3 m_gravity; b3StackAllocator m_stackAllocator; - b3BlockPool m_clothBlocks; + + // Pool of bodies b3BlockPool m_bodyBlocks; - // List of clothes - b3List2 m_clothList; - // List of bodies b3List2 m_bodyList; diff --git a/include/bounce/dynamics/world_listeners.h b/include/bounce/dynamics/world_listeners.h index cc9fc02..4b87efa 100644 --- a/include/bounce/dynamics/world_listeners.h +++ b/include/bounce/dynamics/world_listeners.h @@ -22,7 +22,6 @@ #include class b3Shape; -class b3Cloth; class b3Contact; class b3QueryListener @@ -47,12 +46,6 @@ public: // the intersection point on the shape, the surface normal associated with the point, and the // intersection fraction for the ray. virtual float32 ReportShape(b3Shape* shape, const b3Vec3& point, const b3Vec3& normal, float32 fraction) = 0; - - // Report that a cloth was hit by the ray to this contact listener. - // The reported information are the shape hit by the ray, - // the intersection point on the cloth, the surface normal associated with the point, the - // intersection fraction for the ray, and the triangle. - virtual float32 ReportCloth(b3Cloth* cloth, const b3Vec3& point, const b3Vec3& normal, float32 fraction, u32 triangle) = 0; }; class b3ContactListener diff --git a/include/bounce/dynamics/rope/rope.h b/include/bounce/rope/rope.h similarity index 100% rename from include/bounce/dynamics/rope/rope.h rename to include/bounce/rope/rope.h diff --git a/include/bounce/dynamics/spatial.h b/include/bounce/rope/spatial.h similarity index 100% rename from include/bounce/dynamics/spatial.h rename to include/bounce/rope/spatial.h diff --git a/premake5.lua b/premake5.lua index 3c43015..625618c 100644 --- a/premake5.lua +++ b/premake5.lua @@ -274,6 +274,12 @@ workspace(solution_name) examples_src_dir .. "/testbed/framework/test.h", + examples_src_dir .. "/testbed/framework/body_dragger.h", + examples_src_dir .. "/testbed/framework/cloth_dragger.h", + + examples_src_dir .. "/testbed/framework/body_dragger.cpp", + examples_src_dir .. "/testbed/framework/cloth_dragger.cpp", + examples_inc_dir .. "/testbed/tests/**.h", examples_src_dir .. "/testbed/framework/draw.cpp", diff --git a/src/bounce/dynamics/cloth/cloth.cpp b/src/bounce/cloth/cloth.cpp similarity index 92% rename from src/bounce/dynamics/cloth/cloth.cpp rename to src/bounce/cloth/cloth.cpp index bd526a9..cc301e3 100644 --- a/src/bounce/dynamics/cloth/cloth.cpp +++ b/src/bounce/cloth/cloth.cpp @@ -16,19 +16,16 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include -#include #include #include #include -#include #include static B3_FORCE_INLINE u32 b3NextIndex(u32 i) @@ -149,7 +146,7 @@ static u32 b3FindSharedEdges(b3SharedEdge* sharedEdges, const b3ClothMesh* m) return sharedCount; } -b3Cloth::b3Cloth(const b3ClothDef& def, b3World* world) : +b3Cloth::b3Cloth(const b3ClothDef& def) : m_particleBlocks(sizeof(b3Particle)), m_bodyContactBlocks(sizeof(b3BodyContact)), m_particleContactBlocks(sizeof(b3ParticleContact)), @@ -158,7 +155,6 @@ b3Cloth::b3Cloth(const b3ClothDef& def, b3World* world) : B3_ASSERT(def.mesh); B3_ASSERT(def.density > 0.0f); - m_world = world; m_mesh = def.mesh; m_density = def.density; @@ -184,7 +180,7 @@ b3Cloth::b3Cloth(const b3ClothDef& def, b3World* world) : ComputeMass(); // Create forces - b3StackAllocator* allocator = &m_world->m_stackAllocator; + b3StackAllocator* allocator = &m_stackAllocator; // Worst-case edge memory u32 edgeCount = 3 * m->triangleCount; @@ -218,8 +214,8 @@ b3Cloth::b3Cloth(const b3ClothDef& def, b3World* world) : b3Particle* p3 = m_vertexParticles[e->nsv1]; b3Particle* p4 = m_vertexParticles[e->nsv2]; - b3BendForceDef fd; - fd.Initialize(p1, p2, p3, p4, def.bending, def.damping); + b3SpringForceDef fd; + fd.Initialize(p3, p4, def.bending, def.damping); CreateForce(fd); } @@ -240,6 +236,9 @@ b3Cloth::b3Cloth(const b3ClothDef& def, b3World* world) : CreateForce(fd); } + + m_gravity.SetZero(); + m_world = nullptr; } b3Cloth::~b3Cloth() @@ -354,33 +353,6 @@ void b3Cloth::ComputeMass() } } -void b3Cloth::RayCast(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) -{ - b3RayCastInput input; - input.p1 = p1; - input.p2 = p2; - input.maxFraction = 1.0f; - - for (u32 i = 0; i < m_mesh->triangleCount; ++i) - { - b3RayCastOutput subOutput; - if (RayCast(&subOutput, &input, i)) - { - float32 fraction = subOutput.fraction; - b3Vec3 point = (1.0f - fraction) * input.p1 + fraction * input.p2; - b3Vec3 normal = subOutput.normal; - - float32 newFraction = listener->ReportCloth(this, point, normal, fraction, i); - - if (newFraction == 0.0f) - { - // The client has stopped the query. - return; - } - } - } -} - bool b3Cloth::RayCastSingle(b3ClothRayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const { b3RayCastInput input; @@ -440,7 +412,6 @@ bool b3Cloth::RayCast(b3RayCastOutput* output, const b3RayCastInput* input, u32 return false; } - B3_ASSERT(len > B3_EPSILON); n /= len; float32 numerator = b3Dot(n, v1 - p1); @@ -483,11 +454,8 @@ bool b3Cloth::RayCast(b3RayCastOutput* output, const b3RayCastInput* input, u32 float32 v = b3Dot(QC_x_QA, AB_x_AC); float32 w = b3Dot(QA_x_QB, AB_x_AC); - // Characteristic length of triangle - const float32 kTol = -B3_EPSILON; - // Is the intersection on the triangle? - if (u > kTol && v > kTol && w > kTol) + if (u >= 0.0f && v >= 0.0f && w >= 0.0f) { output->fraction = fraction; @@ -509,6 +477,12 @@ bool b3Cloth::RayCast(b3RayCastOutput* output, const b3RayCastInput* input, u32 void b3Cloth::UpdateBodyContacts() { + // Is there a world attached to this cloth? + if (m_world == nullptr) + { + return; + } + B3_PROFILE("Cloth Update Body Contacts"); // Clear buffer @@ -537,9 +511,13 @@ void b3Cloth::UpdateBodyContacts() for (b3Body* body = m_world->GetBodyList().m_head; body; body = body->GetNext()) { - if (p->m_type != e_dynamicParticle && body->GetType() != e_dynamicBody) + if (p->m_type != e_dynamicParticle) + { + continue; + } + + if (body->GetType() != e_staticBody) { - // At least one body should be kinematic or dynamic. continue; } @@ -887,7 +865,7 @@ void b3Cloth::Solve(float32 dt, const b3Vec3& gravity) // Solve b3ClothSolverDef solverDef; - solverDef.stack = &m_world->m_stackAllocator; + solverDef.stack = &m_stackAllocator; solverDef.particleCapacity = m_particleList.m_count; solverDef.forceCapacity = m_forceList.m_count; solverDef.bodyContactCapacity = m_bodyContactList.m_count; @@ -937,14 +915,16 @@ void b3Cloth::UpdateContacts() // Update body contacts UpdateBodyContacts(); +#if 0 // Update particle contacts UpdateParticleContacts(); // Update triangle contacts UpdateTriangleContacts(); +#endif } -void b3Cloth::Step(float32 dt, const b3Vec3& gravity) +void b3Cloth::Step(float32 dt) { B3_PROFILE("Cloth Step"); @@ -954,7 +934,7 @@ void b3Cloth::Step(float32 dt, const b3Vec3& gravity) // Solve constraints, integrate state, clear forces and translations. if (dt > 0.0f) { - Solve(dt, gravity); + Solve(dt, m_gravity); } } diff --git a/src/bounce/dynamics/cloth/cloth_contact_solver.cpp b/src/bounce/cloth/cloth_contact_solver.cpp similarity index 99% rename from src/bounce/dynamics/cloth/cloth_contact_solver.cpp rename to src/bounce/cloth/cloth_contact_solver.cpp index cf05921..e553df2 100644 --- a/src/bounce/dynamics/cloth/cloth_contact_solver.cpp +++ b/src/bounce/cloth/cloth_contact_solver.cpp @@ -16,12 +16,12 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include -#include +#include +#include +#include +#include #include #include -#include b3ClothContactSolver::b3ClothContactSolver(const b3ClothContactSolverDef& def) { diff --git a/src/bounce/dynamics/cloth/cloth_mesh.cpp b/src/bounce/cloth/cloth_mesh.cpp similarity index 95% rename from src/bounce/dynamics/cloth/cloth_mesh.cpp rename to src/bounce/cloth/cloth_mesh.cpp index f51c408..5018104 100644 --- a/src/bounce/dynamics/cloth/cloth_mesh.cpp +++ b/src/bounce/cloth/cloth_mesh.cpp @@ -16,10 +16,10 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include -#include -#include +#include +#include +#include +#include b3GarmentClothMesh::b3GarmentClothMesh() { diff --git a/src/bounce/dynamics/cloth/cloth_solver.cpp b/src/bounce/cloth/cloth_solver.cpp similarity index 96% rename from src/bounce/dynamics/cloth/cloth_solver.cpp rename to src/bounce/cloth/cloth_solver.cpp index e4d66b2..2684966 100644 --- a/src/bounce/dynamics/cloth/cloth_solver.cpp +++ b/src/bounce/cloth/cloth_solver.cpp @@ -16,18 +16,18 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include // Here, we solve Ax = b using the Modified Preconditioned Conjugate Gradient (MPCG) algorithm. // described in the paper: @@ -298,7 +298,7 @@ void b3ClothSolver::Solve(float32 dt, const b3Vec3& gravity) // Solve velocity constraints { - const u32 kVelocityIterations = 5; + const u32 kVelocityIterations = 10; for (u32 i = 0; i < kVelocityIterations; ++i) { diff --git a/src/bounce/dynamics/cloth/force.cpp b/src/bounce/cloth/force.cpp similarity index 79% rename from src/bounce/dynamics/cloth/force.cpp rename to src/bounce/cloth/force.cpp index 0365c66..53e4fce 100644 --- a/src/bounce/dynamics/cloth/force.cpp +++ b/src/bounce/cloth/force.cpp @@ -16,9 +16,8 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include -#include +#include +#include b3Force* b3Force::Create(const b3ForceDef* def) { @@ -31,12 +30,6 @@ 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); @@ -60,13 +53,6 @@ void b3Force::Destroy(b3Force* force) b3Free(force); break; } - case e_bendForce: - { - b3BendForce* o = (b3BendForce*)force; - o->~b3BendForce(); - b3Free(force); - break; - } default: { B3_ASSERT(false); diff --git a/src/bounce/garment/garment_mesh.cpp b/src/bounce/cloth/garment/garment_mesh.cpp similarity index 97% rename from src/bounce/garment/garment_mesh.cpp rename to src/bounce/cloth/garment/garment_mesh.cpp index ffc2a5e..473b5f0 100644 --- a/src/bounce/garment/garment_mesh.cpp +++ b/src/bounce/cloth/garment/garment_mesh.cpp @@ -16,9 +16,9 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include -#include +#include +#include +#include #define ANSI_DECLARATORS #define REAL double diff --git a/src/bounce/dynamics/cloth/particle.cpp b/src/bounce/cloth/particle.cpp similarity index 91% rename from src/bounce/dynamics/cloth/particle.cpp rename to src/bounce/cloth/particle.cpp index cd4c2fe..0da1c6d 100644 --- a/src/bounce/dynamics/cloth/particle.cpp +++ b/src/bounce/cloth/particle.cpp @@ -16,11 +16,11 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include void b3BodyContactWorldPoint::Initialize(const b3BodyContact* c, float32 rA, const b3Transform& xfA, float32 rB, const b3Transform& xfB) { diff --git a/src/bounce/dynamics/cloth/spring_force.cpp b/src/bounce/cloth/spring_force.cpp similarity index 91% rename from src/bounce/dynamics/cloth/spring_force.cpp rename to src/bounce/cloth/spring_force.cpp index 25ba831..4a634fb 100644 --- a/src/bounce/dynamics/cloth/spring_force.cpp +++ b/src/bounce/cloth/spring_force.cpp @@ -16,11 +16,11 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include void b3SpringForceDef::Initialize(b3Particle* particle1, b3Particle* particle2, float32 structuralStiffness, float32 dampingStiffness) { diff --git a/src/bounce/dynamics/cloth/bend_force.cpp b/src/bounce/dynamics/cloth/bend_force.cpp deleted file mode 100644 index d540706..0000000 --- a/src/bounce/dynamics/cloth/bend_force.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* -* 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/world.cpp b/src/bounce/dynamics/world.cpp index aa9647a..bc688b7 100644 --- a/src/bounce/dynamics/world.cpp +++ b/src/bounce/dynamics/world.cpp @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -32,7 +31,6 @@ extern u32 b3_gjkCalls, b3_gjkIters, b3_gjkMaxIters; extern bool b3_convexCache; b3World::b3World() : - m_clothBlocks(sizeof(b3Cloth)), m_bodyBlocks(sizeof(b3Body)) { b3_allocCalls = 0; @@ -54,14 +52,6 @@ b3World::b3World() : b3World::~b3World() { - b3Cloth* c = m_clothList.m_head; - while (c) - { - b3Cloth* c0 = c; - c = c->m_next; - c0->~b3Cloth(); - } - b3Body* b = m_bodyList.m_head; while (b) { @@ -93,21 +83,6 @@ void b3World::SetSleeping(bool flag) } } -b3Cloth* b3World::CreateCloth(const b3ClothDef& def) -{ - void* mem = m_clothBlocks.Allocate(); - b3Cloth* c = new(mem) b3Cloth(def, this); - m_clothList.PushFront(c); - return c; -} - -void b3World::DestroyCloth(b3Cloth* c) -{ - m_clothList.Remove(c); - c->~b3Cloth(); - m_clothBlocks.Free(c); -} - b3Body* b3World::CreateBody(const b3BodyDef& def) { void* mem = m_bodyBlocks.Allocate(); @@ -166,11 +141,6 @@ void b3World::Step(float32 dt, u32 velocityIterations, u32 positionIterations) { Solve(dt, velocityIterations, positionIterations); } - - //SolveTOI - - // Step cloth dynamics - StepCloth(dt); } void b3World::Solve(float32 dt, u32 velocityIterations, u32 positionIterations) @@ -366,16 +336,6 @@ void b3World::Solve(float32 dt, u32 velocityIterations, u32 positionIterations) } } -void b3World::StepCloth(float32 dt) -{ - B3_PROFILE("Step Cloth"); - - for (b3Cloth* c = m_clothList.m_head; c; c = c->GetNext()) - { - c->Step(dt, m_gravity); - } -} - struct b3ShapeRayCastCallback { float32 Report(const b3RayCastInput& input, u32 proxyId) @@ -411,7 +371,7 @@ struct b3ShapeRayCastCallback const b3BroadPhase* broadPhase; }; -void b3World::RayCastShape(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const +void b3World::RayCast(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const { b3RayCastInput input; input.p1 = p1; @@ -456,7 +416,7 @@ struct b3RayCastSingleShapeCallback const b3BroadPhase* broadPhase; }; -bool b3World::RayCastSingleShape(b3RayCastSingleShapeOutput* output, const b3Vec3& p1, const b3Vec3& p2) const +bool b3World::RayCastSingle(b3RayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const { b3RayCastInput input; input.p1 = p1; @@ -489,52 +449,6 @@ bool b3World::RayCastSingleShape(b3RayCastSingleShapeOutput* output, const b3Vec return false; } -void b3World::RayCastCloth(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const -{ - for (b3Cloth* c = m_clothList.m_head; c; c = c->m_next) - { - c->RayCast(listener, p1, p2); - } -} - -bool b3World::RayCastSingleCloth(b3RayCastSingleClothOutput* output, const b3Vec3& p1, const b3Vec3& p2) const -{ - b3Cloth* cloth0 = NULL; - b3ClothRayCastSingleOutput output0; - output0.fraction = B3_MAX_FLOAT; - - for (b3Cloth* c = m_clothList.m_head; c; c = c->m_next) - { - b3ClothRayCastSingleOutput subOutput; - if (c->RayCastSingle(&subOutput, p1, p2)) - { - if (subOutput.fraction < output0.fraction) - { - cloth0 = c; - output0 = subOutput; - } - } - } - - if (cloth0 != NULL) - { - u32 triangle = output0.triangle; - float32 fraction = output0.fraction; - b3Vec3 point = (1.0f - fraction) * p1 + fraction * p2; - b3Vec3 normal = output0.normal; - - output->cloth = cloth0; - output->triangle = triangle; - output->point = point; - output->normal = normal; - output->fraction = fraction; - - return true; - } - - return false; -} - struct b3QueryAABBCallback { bool Report(u32 proxyID) diff --git a/src/bounce/dynamics/rope/rope.cpp b/src/bounce/rope/rope.cpp similarity index 99% rename from src/bounce/dynamics/rope/rope.cpp rename to src/bounce/rope/rope.cpp index 6ddec52..d839180 100644 --- a/src/bounce/dynamics/rope/rope.cpp +++ b/src/bounce/rope/rope.cpp @@ -16,8 +16,8 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include -#include +#include +#include #include struct b3RopeBody diff --git a/test/ignore.txt b/test/ignore.txt deleted file mode 100644 index e69de29..0000000