From 32836b06945bac5da3bdd50cfed51f6387e2f5f1 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 4 Jul 2019 12:49:45 -0700 Subject: [PATCH 01/47] set up deformable world and solver (does not support contact or friction yet) --- examples/DeformableDemo/DeformableDemo.cpp | 269 ++++++++++++++++++ examples/DeformableDemo/DeformableDemo.h | 20 ++ examples/ExampleBrowser/ExampleEntries.cpp | 3 + src/.DS_Store | Bin 0 -> 6148 bytes src/BulletDynamics/Dynamics/btDynamicsWorld.h | 3 +- src/BulletSoftBody/btBackwardEulerObjective.h | 163 +++++++++++ src/BulletSoftBody/btConjugateGradient.h | 208 ++++++++++++++ src/BulletSoftBody/btDeformableBodySolver.h | 269 ++++++++++++++++++ .../btDeformableRigidDynamicsWorld.cpp | 39 +++ .../btDeformableRigidDynamicsWorld.h | 89 ++++++ src/BulletSoftBody/btLagrangianForce.h | 53 ++++ src/BulletSoftBody/btMassSpring.h | 113 ++++++++ src/BulletSoftBody/btSoftBody.cpp | 1 + src/BulletSoftBody/btSoftBody.h | 6 + src/BulletSoftBody/btSoftBodySolvers.h | 3 +- 15 files changed, 1237 insertions(+), 2 deletions(-) create mode 100644 examples/DeformableDemo/DeformableDemo.cpp create mode 100644 examples/DeformableDemo/DeformableDemo.h create mode 100644 src/.DS_Store create mode 100644 src/BulletSoftBody/btBackwardEulerObjective.h create mode 100644 src/BulletSoftBody/btConjugateGradient.h create mode 100644 src/BulletSoftBody/btDeformableBodySolver.h create mode 100644 src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp create mode 100644 src/BulletSoftBody/btDeformableRigidDynamicsWorld.h create mode 100644 src/BulletSoftBody/btLagrangianForce.h create mode 100644 src/BulletSoftBody/btMassSpring.h diff --git a/examples/DeformableDemo/DeformableDemo.cpp b/examples/DeformableDemo/DeformableDemo.cpp new file mode 100644 index 000000000..7edc3c4a3 --- /dev/null +++ b/examples/DeformableDemo/DeformableDemo.cpp @@ -0,0 +1,269 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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. +*/ + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_Z 5 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X * ARRAY_SIZE_Y * ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "DeformableDemo.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "BulletSoftBody/btDeformableRigidDynamicsWorld.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "BulletSoftBody/btDeformableBodySolver.h" +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#include //printf debugging + +#include "../CommonInterfaces/CommonRigidBodyBase.h" +#include "../Utils/b3ResourcePath.h" + +///The DeformableDemo shows the use of rolling friction. +///Spheres will come to a rest on a sloped plane using a constraint. Damping cannot achieve the same. +///Generally it is best to leave the rolling friction coefficient zero (or close to zero). +class DeformableDemo : public CommonRigidBodyBase +{ +public: + DeformableDemo(struct GUIHelperInterface* helper) + : CommonRigidBodyBase(helper) + { + } + virtual ~DeformableDemo() + { + } + void initPhysics(); + + void exitPhysics(); + + void resetCamera() + { +// float dist = 30; +// float pitch = -14; +// float yaw = 0; +// float targetPos[3] = {0, 0, 0}; + float dist = 45; + float pitch = -45; + float yaw = 100; + float targetPos[3] = {0,0, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); + } + virtual const btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() const + { + ///just make it a btSoftRigidDynamicsWorld please + ///or we will add type checking + return (btDeformableRigidDynamicsWorld*)m_dynamicsWorld; + } + + virtual btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() + { + ///just make it a btSoftRigidDynamicsWorld please + ///or we will add type checking + return (btDeformableRigidDynamicsWorld*)m_dynamicsWorld; + } + + virtual void renderScene() + { + CommonRigidBodyBase::renderScene(); + btDeformableRigidDynamicsWorld* deformableWorld = getDeformableDynamicsWorld(); + + for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++) + { + btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i]; + //if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) + { + btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags()); + } + } + } +}; + +void DeformableDemo::initPhysics() +{ + m_guiHelper->setUpAxis(1); + + ///collision configuration contains default setup for memory, collision setup +// m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration, deformableBodySolver); + // m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality + m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); + getDeformableDynamicsWorld()->getSoftDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); + + { + ///create a few basic rigid bodies +// btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.), btScalar(5.), btScalar(25.))); + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.), btScalar(25.), btScalar(50.))); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, -30, 0)); +// groundTransform.setRotation(btQuaternion(btVector3(0, 1, 0), SIMD_PI * 0.03)); + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0, 0, 0); + if (isDynamic) + groundShape->calculateLocalInertia(mass, localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(.5); + + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } +// +// { +// ///create a few basic rigid bodies +// btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(100.), btScalar(100.), btScalar(50.))); +// +// m_collisionShapes.push_back(groundShape); +// +// btTransform groundTransform; +// groundTransform.setIdentity(); +// groundTransform.setOrigin(btVector3(0, 0, -54)); +// //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: +// btScalar mass(0.); +// +// //rigidbody is dynamic if and only if mass is non zero, otherwise static +// bool isDynamic = (mass != 0.f); +// +// btVector3 localInertia(0, 0, 0); +// if (isDynamic) +// groundShape->calculateLocalInertia(mass, localInertia); +// +// //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects +// btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); +// btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); +// btRigidBody* body = new btRigidBody(rbInfo); +// body->setFriction(.1); +// //add the body to the dynamics world +// m_dynamicsWorld->addRigidBody(body); +// } +// +// { +// // add a simple deformable body +// const btVector3 s(3,2,1); // side length +// const btVector3 p(0,30,0); // origin; +// const btVector3 h = s * 0.5; +// const btVector3 c[] = {p + h * btVector3(-1, -1, -1), +// p + h * btVector3(+1, -1, -1), +// p + h * btVector3(-1, +1, -1), +// p + h * btVector3(+1, +1, -1), +// p + h * btVector3(-1, -1, +1), +// p + h * btVector3(+1, -1, +1), +// p + h * btVector3(-1, +1, +1), +// p + h * btVector3(+1, +1, +1)}; +// btSoftBody* psb = btSoftBodyHelpers::CreateFromConvexHull(getDeformableDynamicsWorld()->getSoftDynamicsWorld()->getWorldInfo(), c, 8); +// psb->generateBendingConstraints(2); +// psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS; +// psb->setTotalMass(150); +// getDeformableDynamicsWorld()->addSoftBody(psb); +// } + { + const btScalar s = 8; + btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getSoftDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), + btVector3(+s, 0, -s), + btVector3(-s, 0, +s), + btVector3(+s, 0, +s), + 10, 10, + // 31,31, + 1 + 2 + 4 + 8, true); +// 0, true); + + psb->getCollisionShape()->setMargin(0.5); +// btSoftBody::Material* pm = psb->appendMaterial(); +// pm->m_kLST = 0.4 * 1000; +// pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->generateBendingConstraints(2); + psb->setTotalMass(1); + psb->setDampingCoefficient(0.01); + getDeformableDynamicsWorld()->addSoftBody(psb); + } + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); +} + +void DeformableDemo::exitPhysics() +{ + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject(obj); + delete obj; + } + + //delete collision shapes + for (int j = 0; j < m_collisionShapes.size(); j++) + { + btCollisionShape* shape = m_collisionShapes[j]; + delete shape; + } + m_collisionShapes.clear(); + + delete m_dynamicsWorld; + + delete m_solver; + + delete m_broadphase; + + delete m_dispatcher; + + delete m_collisionConfiguration; +} + + +class CommonExampleInterface* DeformableCreateFunc(struct CommonExampleOptions& options) +{ + return new DeformableDemo(options.m_guiHelper); +} diff --git a/examples/DeformableDemo/DeformableDemo.h b/examples/DeformableDemo/DeformableDemo.h new file mode 100644 index 000000000..c688cea9d --- /dev/null +++ b/examples/DeformableDemo/DeformableDemo.h @@ -0,0 +1,20 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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 _DEFORMABLE_DEMO_H +#define _DEFORMABLE_DEMO_H + +class CommonExampleInterface* DeformableCreateFunc(struct CommonExampleOptions& options); + +#endif //_DEFORMABLE_DEMO_H diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp index e80b4eee9..6d3db549e 100644 --- a/examples/ExampleBrowser/ExampleEntries.cpp +++ b/examples/ExampleBrowser/ExampleEntries.cpp @@ -47,6 +47,7 @@ #include "../FractureDemo/FractureDemo.h" #include "../DynamicControlDemo/MotorDemo.h" #include "../RollingFrictionDemo/RollingFrictionDemo.h" +#include "../DeformableDemo/DeformableDemo.h" #include "../SharedMemory/PhysicsServerExampleBullet2.h" #include "../SharedMemory/PhysicsServerExample.h" #include "../SharedMemory/PhysicsClientExample.h" @@ -118,6 +119,8 @@ static ExampleEntry gDefaultExamples[] = ExampleEntry(1, "Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc), + ExampleEntry(0, "Deformable", "Deformable test", DeformableCreateFunc), + ExampleEntry(1, "Constraints", "Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.", AllConstraintCreateFunc), diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ee616d543128a1988ca9f9dc9bb19e1f51a11544 GIT binary patch literal 6148 zcmeHKQESvd5T3oBn)IMV5VYXKf)9PUhZFUxZy~mQDp;D*K4?7?61_mkmR!<9j)Tx2 z&>x_$T7QS_pXd+i4{&C8uUKmPSgXt&v)^QPW_I)Kv6}?|5!A_301p5hRKk{v%^!sN zNiRvudI*KCkwOI_DENrT@-HwzYqtOa)R5!v_w@^K9TWH*k4JlPu40Tki}&(uRP}nN zqBYmPbN8O(&Uf6-LdV?=hiV*FQB{wEs2q5Y!z@YTsNBhtYPgjat9iPg7H`V+s7lMX z6uhNWjseDw;_WOQ54;DjRZ&G*k(RoisqtUZUf{>y1sPL`K@UHSZ3e>!y?XK`t5^L>4A_~q-j??*p=9_u6!`2W>% z-{K5T(72YL{je-@ReZv@S&dmPBQwAZFax)h0lQy0o!dG=o)ihr2Bz|HBn1TO_0nuIwR|0$`d$wMBIXY`4 t>IYO3ifas>r=X#aVvMDu_z|iW^h+`jeT$7j^q}yEfTn>PX5dB{_yxA-W?TRO literal 0 HcmV?d00001 diff --git a/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDynamicsWorld.h index eadd8c12e..10853b761 100644 --- a/src/BulletDynamics/Dynamics/btDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -34,7 +34,8 @@ enum btDynamicsWorldType BT_CONTINUOUS_DYNAMICS_WORLD = 3, BT_SOFT_RIGID_DYNAMICS_WORLD = 4, BT_GPU_DYNAMICS_WORLD = 5, - BT_SOFT_MULTIBODY_DYNAMICS_WORLD = 6 + BT_SOFT_MULTIBODY_DYNAMICS_WORLD = 6, + BT_DEFORMABLE_RIGID_DYNAMICS_WORLD = 7 }; ///The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc. diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h new file mode 100644 index 000000000..2dca39bb6 --- /dev/null +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -0,0 +1,163 @@ +// +// btBackwardEulerObjective.h +// BulletSoftBody +// +// Created by Xuchen Han on 7/1/19. +// + +#ifndef BT_BACKWARD_EULER_OBJECTIVE_H +#define BT_BACKWARD_EULER_OBJECTIVE_H +#include +#include "btConjugateGradient.h" +#include "btLagrangianForce.h" +#include "btMassSpring.h" + +struct DirichletDofProjection +{ + using TVStack = btAlignedObjectArray; + const btAlignedObjectArray& m_softBodies; + DirichletDofProjection(const btAlignedObjectArray& softBodies) + : m_softBodies(softBodies) + {} + + void operator()(TVStack& x) + { + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + const btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + if (psb->m_nodes[j].m_im == 0) + { + x[counter].setZero(); + } + ++counter; + } + } + } +}; + +class btBackwardEulerObjective +{ +public: + using TVStack = btAlignedObjectArray; + struct EmptyProjection + { + void operator()(TVStack& x) + {} + }; + struct DefaultPreconditioner + { + void operator()(const TVStack& x, TVStack& b) + { + btAssert(b.size() == x.size()); + for (int i = 0; i < b.size(); ++i) + b[i] = x[i]; + } + }; + btScalar m_dt; + btConjugateGradient cg; + + btAlignedObjectArray m_lf; + btAlignedObjectArray& m_softBodies; + std::function project; + std::function precondition; + + btBackwardEulerObjective(btAlignedObjectArray& softBodies) + : cg(20) + , m_softBodies(softBodies) + , project(EmptyProjection()) + , precondition(DefaultPreconditioner()) + { + // this should really be specified in initialization instead of here + btMassSpring* mass_spring = new btMassSpring(m_softBodies); + m_lf.push_back(mass_spring); + } + + virtual ~btBackwardEulerObjective() {} + + void initialize(){} + + void computeResidual(btScalar dt, TVStack& residual) const + { + // gravity is treated explicitly in predictUnconstraintMotion + + // add force + for (int i = 0; i < m_lf.size(); ++i) + { + m_lf[i]->addScaledForce(dt, residual); + } + } + + btScalar computeNorm(const TVStack& residual) const + { + btScalar norm_squared = 0; + for (int i = 0; i < residual.size(); ++i) + { + norm_squared += residual[i].length2(); + } + return std::sqrt(norm_squared); + } + + void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt) + { + m_dt = dt; + // TODO:figure out what the tolerance should be + btScalar tolerance = std::numeric_limits::epsilon()*16 * computeNorm(residual); + cg.solve(*this, dv, residual, tolerance); + } + + void multiply(const TVStack& x, TVStack& b) const + { + for (int i = 0; i < b.size(); ++i) + b[i].setZero(); + + // add in the mass term + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + const auto& node = psb->m_nodes[j]; + b[counter] += (node.m_im == 0) ? btVector3(0,0,0) : x[counter] / node.m_im; + ++counter; + } + } + + for (int i = 0; i < m_lf.size(); ++i) + { + // damping force is implicit and elastic force is explicit + m_lf[i]->addScaledDampingForceDifferential(-m_dt, x, b); + } + } + + void reinitialize(bool nodeUpdated) + { + for (int i = 0; i < m_lf.size(); ++i) + { + m_lf[i]->reinitialize(nodeUpdated); + } + + if(nodeUpdated) + { + DirichletDofProjection dirichlet(m_softBodies); + setProjection(dirichlet); + } + } + + template + void setProjection(Func project_func) + { + project = project_func; + } + + template + void setPreconditioner(Func preconditioner_func) + { + precondition = preconditioner_func; + } +}; + +#endif /* btBackwardEulerObjective_h */ diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h new file mode 100644 index 000000000..76297226d --- /dev/null +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -0,0 +1,208 @@ +// +// btConjugateGradient.h +// BulletSoftBody +// +// Created by Xuchen Han on 7/1/19. +// + +#ifndef BT_CONJUGATE_GRADIENT_H +#define BT_CONJUGATE_GRADIENT_H +#include +template +class btConjugateGradient +{ + using TVStack = btAlignedObjectArray; + TVStack r,p,z,temp; + int max_iterations; + btScalar tolerance; + +public: + btConjugateGradient(const int max_it_in) + : max_iterations(max_it_in) + , tolerance(std::numeric_limits::epsilon() * 16) + { + } + + virtual ~btConjugateGradient(){} + +// // return the number of iterations taken +// int solve(const TM& A, TVStack& x, const TVStack& b, btScalar tolerance) +// { +// btAssert(x.size() == b.size()); +// reinitialize(b); +// +// // r = M * (b - A * x) --with assigned dof zeroed out +// A.multiply(x, temp); +// temp = sub(b, temp); +// A.project(temp); +// A.precondition(temp, r); +// +// btScalar r_dot_r = squaredNorm(r), r_dot_r_new; +// btScalar r_norm = std::sqrt(r_dot_r); +// if (r_norm < tolerance) { +// std::cout << "Iteration = 0" << std::endl; +// std::cout << "Two norm of the residual = " << r_norm << std::endl; +// return 0; +// } +// +// p = r; +// // q = M * A * q; +// A.multiply(p, temp); +// A.precondition(temp, q); +// +// // alpha = |r|^2 / (p^T * A * p) +// btScalar alpha = r_dot_r / dot(p, q), beta; +// +// for (int k = 1; k < max_iterations; k++) { +//// x += alpha * p; +//// r -= alpha * q; +// multAndAddTo(alpha, p, x); +// multAndAddTo(-alpha, q, r); +// +// // zero out the dofs of r +// A.project(r); +// +// r_dot_r_new = squaredNorm(r); +// r_norm = std::sqrt(r_dot_r_new); +// +// if (r_norm < tolerance) { +// std::cout << "ConjugateGradient iterations " << k << std::endl; +// return k; +// +// beta = r_dot_r_new / r_dot_r; +// r_dot_r = r_dot_r_new; +//// p = r + beta * p; +// p = multAndAdd(beta, p, r); +// +// // q = M * A * q; +// A.multiply(p, temp); +// A.precondition(temp, q); +// +// alpha = r_dot_r / dot(p, q); +// } +// +// setZero(q); +// setZero(r); +// } +// std::cout << "ConjugateGradient max iterations reached " << max_iterations << std::endl; +// return max_iterations; +// } + + // return the number of iterations taken + int solve(const TM& A, TVStack& x, const TVStack& b, btScalar tolerance) + { + btAssert(x.size() == b.size()); + reinitialize(b); + + // r = b - A * x --with assigned dof zeroed out + A.multiply(x, temp); + r = sub(b, temp); + A.project(r); + + btScalar r_norm = std::sqrt(squaredNorm(r)); + if (r_norm < tolerance) { + std::cout << "Iteration = 0" << std::endl; + std::cout << "Two norm of the residual = " << r_norm << std::endl; + return 0; + } + + // z = M^(-1) * r + A.precondition(r, z); + // p = z; + p = z; + // temp = A*p + A.multiply(p, temp); + + btScalar r_dot_z = dot(z,r), r_dot_z_new; + // alpha = r^T * z / (p^T * A * p) + btScalar alpha = r_dot_z / dot(p, temp), beta; + + for (int k = 1; k < max_iterations; k++) { + // x += alpha * p; + // r -= alpha * temp; + multAndAddTo(alpha, p, x); + multAndAddTo(-alpha, temp, r); + + // zero out the dofs of r + A.project(r); + + r_norm = std::sqrt(squaredNorm(r)); + + if (r_norm < tolerance) { + std::cout << "ConjugateGradient iterations " << k << std::endl; + return k; + } + + // z = M^(-1) * r + A.precondition(r, z); + r_dot_z_new = dot(r,z); + beta = r_dot_z_new/ r_dot_z; + r_dot_z = r_dot_z_new; + // p = z + beta * p; + p = multAndAdd(beta, p, z); + // temp = A * p; + A.multiply(p, temp); + // alpha = r^T * z / (p^T * A * p) + alpha = r_dot_z / dot(p, temp); + } + std::cout << "ConjugateGradient max iterations reached " << max_iterations << std::endl; + return max_iterations; + } + + void reinitialize(const TVStack& b) + { + r.resize(b.size()); + p.resize(b.size()); + z.resize(b.size()); + temp.resize(b.size()); + } + + TVStack sub(const TVStack& a, const TVStack& b) + { + // c = a-b + btAssert(a.size() == b.size()) + TVStack c; + c.resize(a.size()); + for (int i = 0; i < a.size(); ++i) + c[i] = a[i] - b[i]; + return c; + } + + btScalar squaredNorm(const TVStack& a) + { + return dot(a,a); + } + + btScalar dot(const TVStack& a, const TVStack& b) + { + btScalar ans(0); + for (int i = 0; i < a.size(); ++i) + ans += a[i].dot(b[i]); + return ans; + } + + void setZero(TVStack& a) + { + for (int i = 0; i < a.size(); ++i) + a[i].setZero(); + } + + void multAndAddTo(btScalar s, const TVStack& a, TVStack& result) + { +// result += s*a + btAssert(a.size() == result.size()) + for (int i = 0; i < a.size(); ++i) + result[i] += s * a[i]; + } + + TVStack multAndAdd(btScalar s, const TVStack& a, const TVStack& b) + { + // result = a*s + b + TVStack result; + result.resize(a.size()); + for (int i = 0; i < a.size(); ++i) + result[i] = s * a[i] + b[i]; + return result; + } +}; +#endif /* btConjugateGradient_h */ diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h new file mode 100644 index 000000000..4e36a2112 --- /dev/null +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -0,0 +1,269 @@ +// +// btDeformableBodySolver.h +// BulletSoftBody +// +// Created by Chuyuan Fu on 7/1/19. +// + +#ifndef BT_DEFORMABLE_BODY_SOLVERS_H +#define BT_DEFORMABLE_BODY_SOLVERS_H + +#include "btSoftBodySolvers.h" +#include "btBackwardEulerObjective.h" + +#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" + +struct btCollisionObjectWrapper; + +class btDeformableBodySolver : public btSoftBodySolver +{ + using TVStack = btAlignedObjectArray; +protected: + /** Variable to define whether we need to update solver constants on the next iteration */ + bool m_updateSolverConstants; + int m_numNodes; + TVStack m_dv; + TVStack m_residual; + btAlignedObjectArray m_softBodySet; + btBackwardEulerObjective m_objective; + int m_solveIterations; + int m_impulseIterations; + +public: + btDeformableBodySolver() + : m_numNodes(0) + , m_objective(m_softBodySet) + , m_solveIterations(1) + , m_impulseIterations(1) + { + } + + virtual ~btDeformableBodySolver() + { + } + + virtual SolverTypes getSolverType() const + { + return DEFORMABLE_SOLVER; + } + + virtual bool checkInitialized() + { + return true; + } + + virtual void updateSoftBodies() + { + for (int i = 0; i < m_softBodySet.size(); i++) + { + btSoftBody *psb = (btSoftBody *)m_softBodySet[i]; + if (psb->isActive()) + { + psb->integrateMotion(); // normal is updated here + } + } + } + + virtual void optimize(btAlignedObjectArray &softBodies, bool forceUpdate = false) + { + m_softBodySet.copyFromArray(softBodies); + } + + virtual void copyBackToSoftBodies(bool bMove = true) {} + + virtual void solveConstraints(float solverdt) + { + bool nodeUpdated = updateNodes(); + reinitialize(nodeUpdated); + + for (int i = 0; i < m_solveIterations; ++i) + { + // get the velocity after contact solve + // TODO: perform contact solve here + for (int j = 0; j < m_impulseIterations; ++j) + { + for (int s = 0; s < m_softBodySet.size(); ++s) + VSolve_RContacts(m_softBodySet[s], 0, solverdt); + } + + // advect with v_n+1 ** to update position based states + // where v_n+1 ** is the velocity after contact response + + // only need to advect x here if elastic force is implicit +// prepareSolve(solverdt); + + m_objective.computeResidual(solverdt, m_residual); + m_objective.computeStep(m_dv, m_residual, solverdt); + + updateVelocity(); + } + advect(solverdt); + } + + void reinitialize(bool nodeUpdated) + { + if (nodeUpdated) + { + m_dv.resize(m_numNodes); + m_residual.resize(m_numNodes); + } + for (int i = 0; i < m_dv.size(); ++i) + { + m_dv[i].setZero(); + m_residual[i].setZero(); + } + m_objective.reinitialize(nodeUpdated); + } + + void prepareSolve(btScalar dt) + { + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + auto& node = psb->m_nodes[j]; + node.m_x = node.m_q + dt * node.m_v * psb->m_dampingCoefficient; + } + } + } + void advect(btScalar dt) + { + size_t counter = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + auto& node = psb->m_nodes[j]; + node.m_x += dt * m_dv[counter++]; + } + } + } + + void updateVelocity() + { + // serial implementation + int counter = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + psb->m_nodes[j].m_v += m_dv[counter++]; + } + } + } + + bool updateNodes() + { + int numNodes = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + numNodes += m_softBodySet[i]->m_nodes.size(); + if (numNodes != m_numNodes) + { + m_numNodes = numNodes; + return true; + } + return false; + } + virtual void predictMotion(float solverdt) + { + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody *psb = m_softBodySet[i]; + + if (psb->isActive()) + { + psb->predictMotion(solverdt); + } + } + } + + virtual void copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer) {} + + virtual void processCollision(btSoftBody * softBody, const btCollisionObjectWrapper * collisionObjectWrap) + { + softBody->defaultCollisionHandler(collisionObjectWrap); + } + + virtual void processCollision(btSoftBody *, btSoftBody *) { + // TODO + } + + void VSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar dt) + { + const btScalar mrg = psb->getCollisionShape()->getMargin(); + btMultiBodyJacobianData jacobianData; + for (int i = 0, ni = psb->m_rcontacts.size(); i < ni; ++i) + { + const btSoftBody::RContact& c = psb->m_rcontacts[i]; + const btSoftBody::sCti& cti = c.m_cti; + if (cti.m_colObj->hasContactResponse()) + { + btVector3 va(0, 0, 0); + btRigidBody* rigidCol = 0; + btMultiBodyLinkCollider* multibodyLinkCol = 0; + btScalar* deltaV; + + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? rigidCol->getVelocityInLocalPoint(c.m_c1) * dt : btVector3(0, 0, 0); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); + + btScalar vel = 0.0; + for (int j = 0; j < ndof; ++j) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + } + va = cti.m_normal * vel * dt; + } + } + + const btVector3 vb = c.m_node->m_x - c.m_node->m_q; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, cti.m_normal); + if (dn <= SIMD_EPSILON) + { + const btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); + const btVector3 fv = vr - (cti.m_normal * dn); + // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient + const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst); + c.m_node->m_v -= impulse * c.m_c2 / dt; + + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + if (rigidCol) + rigidCol->applyImpulse(impulse, c.m_c1); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + if (multibodyLinkCol) + { + double multiplier = 0.5; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + } + } + } + } + } + } + +}; + +#endif /* btDeformableBodySolver_h */ diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp new file mode 100644 index 000000000..73d4f67f6 --- /dev/null +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -0,0 +1,39 @@ +// +// btDeformableRigidDynamicsWorld.cpp +// BulletSoftBody +// +// Created by Xuchen Han on 7/1/19. +// + +#include +#include "btDeformableRigidDynamicsWorld.h" +#include "btDeformableBodySolver.h" + +void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) +{ + // Let the solver grab the soft bodies and if necessary optimize for it + m_deformableBodySolver->optimize(getSoftDynamicsWorld()->getSoftBodyArray()); + + if (!m_deformableBodySolver->checkInitialized()) + { + btAssert("Solver initialization failed\n"); + } + + btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep); + + ///solve deformable bodies constraints + solveDeformableBodiesConstraints(timeStep); + + + ///update soft bodies + m_deformableBodySolver->updateSoftBodies(); + + // End solver-wise simulation step + // /////////////////////////////// +} + +void btDeformableRigidDynamicsWorld::solveDeformableBodiesConstraints(btScalar timeStep) +{ + m_deformableBodySolver->solveConstraints(timeStep); +} + diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h new file mode 100644 index 000000000..55ed41d86 --- /dev/null +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -0,0 +1,89 @@ +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + + 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 BT_DEFORMABLE_RIGID_DYNAMICS_WORLD_H +#define BT_DEFORMABLE_RIGID_DYNAMICS_WORLD_H + +#include "btSoftRigidDynamicsWorld.h" +#include "btLagrangianForce.h" +#include "btMassSpring.h" +#include "btDeformableBodySolver.h" +typedef btAlignedObjectArray btSoftBodyArray; + +class btDeformableBodySolver; +class btLagrangianForce; + +class btDeformableRigidDynamicsWorld : public btSoftRigidDynamicsWorld +{ + using TVStack = btAlignedObjectArray; + ///Solver classes that encapsulate multiple deformable bodies for solving + btDeformableBodySolver* m_deformableBodySolver; + + +protected: + virtual void internalSingleStepSimulation(btScalar timeStep); + + void solveDeformableBodiesConstraints(btScalar timeStep); + +public: + btDeformableRigidDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btDeformableBodySolver* deformableBodySolver = 0) + : btSoftRigidDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration, 0), + m_deformableBodySolver(deformableBodySolver) + { + } + + virtual ~btDeformableRigidDynamicsWorld() + { + } + + virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld() + { + return (btSoftRigidDynamicsWorld*)(this); + } + + virtual const btSoftRigidDynamicsWorld* getSoftDynamicsWorld() const + { + return (const btSoftRigidDynamicsWorld*)(this); + } + + virtual btDynamicsWorldType getWorldType() const + { + return BT_DEFORMABLE_RIGID_DYNAMICS_WORLD; + } + + virtual void predictUnconstraintMotion(btScalar timeStep) + { + btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); + m_deformableBodySolver->predictMotion(float(timeStep)); + } + // virtual void internalStepSingleStepSimulation(btScalar timeStep); + + // virtual void solveDeformableBodiesConstraints(btScalar timeStep); + + virtual void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter) + { + getSoftDynamicsWorld()->getSoftBodyArray().push_back(body); + + // Set the soft body solver that will deal with this body + // to be the world's solver + body->setSoftBodySolver(m_deformableBodySolver); + + btCollisionWorld::addCollisionObject(body, + collisionFilterGroup, + collisionFilterMask); + } +}; + +#endif //BT_DEFORMABLE_RIGID_DYNAMICS_WORLD_H diff --git a/src/BulletSoftBody/btLagrangianForce.h b/src/BulletSoftBody/btLagrangianForce.h new file mode 100644 index 000000000..40e63207e --- /dev/null +++ b/src/BulletSoftBody/btLagrangianForce.h @@ -0,0 +1,53 @@ +// +// btLagrangianForce.h +// BulletSoftBody +// +// Created by Xuchen Han on 7/1/19. +// + +#ifndef BT_LAGRANGIAN_FORCE_H +#define BT_LAGRANGIAN_FORCE_H + +#include "btSoftBody.h" +#include + +class btLagrangianForce +{ +public: + using TVStack = btAlignedObjectArray; + const btAlignedObjectArray& m_softBodies; + std::unordered_map m_indices; + + btLagrangianForce(const btAlignedObjectArray& softBodies) + : m_softBodies(softBodies) + { + } + + virtual ~btLagrangianForce(){} + + virtual void addScaledForce(btScalar scale, TVStack& force) = 0; + + virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) = 0; + + virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) = 0; + + virtual void reinitialize(bool nodeUpdated) + { + if (nodeUpdated) + updateId(); + } + + void updateId() + { + size_t index = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + m_indices[&(psb->m_nodes[j])] = index++; + } + } + } +}; +#endif /* btLagrangianForce_h */ diff --git a/src/BulletSoftBody/btMassSpring.h b/src/BulletSoftBody/btMassSpring.h new file mode 100644 index 000000000..ffe21c801 --- /dev/null +++ b/src/BulletSoftBody/btMassSpring.h @@ -0,0 +1,113 @@ +// +// btMassSpring.h +// BulletSoftBody +// +// Created by Chuyuan Fu on 7/1/19. +// + +#ifndef BT_MASS_SPRING_H +#define BT_MASS_SPRING_H + +#include "btLagrangianForce.h" + +class btMassSpring : public btLagrangianForce +{ +public: + using TVStack = btLagrangianForce::TVStack; + btMassSpring(const btAlignedObjectArray& softBodies) : btLagrangianForce(softBodies) + { + + } + + virtual void addScaledForce(btScalar scale, TVStack& force) + { + int numNodes = getNumNodes(); + btAssert(numNodes == force.size()) + for (int i = 0; i < m_softBodies.size(); ++i) + { + const btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_links.size(); ++j) + { + const auto& link = psb->m_links[j]; + const auto node1 = link.m_n[0]; + const auto node2 = link.m_n[1]; + btScalar kLST = link.Feature::m_material->m_kLST; // this is probly wrong, TODO: figure out how to get stiffness + btScalar r = link.m_rl; + size_t id1 = m_indices[node1]; + size_t id2 = m_indices[node2]; + + // elastic force + btVector3 dir = (node2->m_x - node1->m_x); + btVector3 dir_normalized = dir.normalized(); + btVector3 scaled_force = scale * kLST * (dir - dir_normalized * r); + force[id1] += scaled_force; + force[id2] -= scaled_force; + + // damping force + btVector3 v_diff = (node2->m_v - node1->m_v); + btScalar k_damp = psb->m_dampingCoefficient; // TODO: FIX THIS HACK and set k_damp properly + scaled_force = scale * v_diff * k_damp; + force[id1] += scaled_force; + force[id2] -= scaled_force; + } + } + } + + virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) + { + int numNodes = getNumNodes(); + btAssert(numNodes == dx.size()); + btAssert(numNodes == df.size()); + + // implicit elastic force + for (int i = 0; i < m_softBodies.size(); ++i) + { + const btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_links.size(); ++j) + { + const auto& link = psb->m_links[j]; + const auto node1 = link.m_n[0]; + const auto node2 = link.m_n[1]; + btScalar kLST = link.Feature::m_material->m_kLST; + size_t id1 = m_indices[node1]; + size_t id2 = m_indices[node2]; + btVector3 local_scaled_df = scale * kLST * (dx[id2] - dx[id1]); + df[id1] += local_scaled_df; + df[id2] -= local_scaled_df; + } + } + } + + virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) + { + // implicity damping force + for (int i = 0; i < m_softBodies.size(); ++i) + { + const btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_links.size(); ++j) + { + const auto& link = psb->m_links[j]; + const auto node1 = link.m_n[0]; + const auto node2 = link.m_n[1]; + btScalar k_damp = psb->m_dampingCoefficient; // TODO: FIX THIS HACK and set k_damp properly + size_t id1 = m_indices[node1]; + size_t id2 = m_indices[node2]; + btVector3 local_scaled_df = scale * k_damp * (dv[id2] - dv[id1]); + df[id1] += local_scaled_df; + df[id2] -= local_scaled_df; + } + } + } + + int getNumNodes() + { + int numNodes = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + numNodes += m_softBodies[i]->m_nodes.size(); + } + return numNodes; + } +}; + +#endif /* btMassSpring_h */ diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 58796a88d..066072426 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -110,6 +110,7 @@ void btSoftBody::initDefaults() m_windVelocity = btVector3(0, 0, 0); m_restLengthScale = btScalar(1.0); + m_dampingCoefficient = 1; } // diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index 9b35b799d..01cde89e3 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -704,6 +704,7 @@ public: btDbvt m_fdbvt; // Faces tree btDbvt m_cdbvt; // Clusters tree tClusterArray m_clusters; // Clusters + btScalar m_dampingCoefficient; // Damping Coefficient btAlignedObjectArray m_clusterConnectivity; //cluster connectivity, for self-collision @@ -735,6 +736,11 @@ public: { return m_worldInfo; } + + void setDampingCoefficient(btScalar damping_coeff) + { + m_dampingCoefficient = damping_coeff; + } ///@todo: avoid internal softbody shape hack and move collision code to collision library virtual void setCollisionShape(btCollisionShape* collisionShape) diff --git a/src/BulletSoftBody/btSoftBodySolvers.h b/src/BulletSoftBody/btSoftBodySolvers.h index dcf508265..405475529 100644 --- a/src/BulletSoftBody/btSoftBodySolvers.h +++ b/src/BulletSoftBody/btSoftBodySolvers.h @@ -35,7 +35,8 @@ public: CL_SOLVER, CL_SIMD_SOLVER, DX_SOLVER, - DX_SIMD_SOLVER + DX_SIMD_SOLVER, + DEFORMABLE_SOLVER }; protected: From 35ce2ae0e2dc5b28185fc90355f8033085b7b76a Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 4 Jul 2019 23:07:02 -0700 Subject: [PATCH 02/47] add contact constraint as projections in CG --- .../Dynamics/btDiscreteDynamicsWorld.h | 8 +- src/BulletSoftBody/btBackwardEulerObjective.h | 78 ++++------ src/BulletSoftBody/btCGProjection.h | 80 ++++++++++ src/BulletSoftBody/btConjugateGradient.h | 8 +- src/BulletSoftBody/btContactProjection.cpp | 142 ++++++++++++++++++ src/BulletSoftBody/btContactProjection.h | 56 +++++++ src/BulletSoftBody/btDeformableBodySolver.h | 116 ++++---------- .../btDeformableRigidDynamicsWorld.cpp | 42 +++++- .../btDeformableRigidDynamicsWorld.h | 3 +- 9 files changed, 392 insertions(+), 141 deletions(-) create mode 100644 src/BulletSoftBody/btCGProjection.h create mode 100644 src/BulletSoftBody/btContactProjection.cpp create mode 100644 src/BulletSoftBody/btContactProjection.h diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h index 7fe961921..51b3d906d 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -17,7 +17,6 @@ subject to the following restrictions: #define BT_DISCRETE_DYNAMICS_WORLD_H #include "btDynamicsWorld.h" - class btDispatcher; class btOverlappingPairCache; class btConstraintSolver; @@ -26,6 +25,7 @@ class btTypedConstraint; class btActionInterface; class btPersistentManifold; class btIDebugDraw; + struct InplaceSolverIslandCallback; #include "LinearMath/btAlignedObjectArray.h" @@ -76,7 +76,7 @@ protected: virtual void calculateSimulationIslands(); - virtual void solveConstraints(btContactSolverInfo & solverInfo); + virtual void updateActivationState(btScalar timeStep); @@ -95,7 +95,7 @@ protected: void serializeRigidBodies(btSerializer * serializer); void serializeDynamicsWorldInfo(btSerializer * serializer); - + public: BT_DECLARE_ALIGNED_ALLOCATOR(); @@ -107,6 +107,8 @@ public: ///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's virtual int stepSimulation(btScalar timeStep, int maxSubSteps = 1, btScalar fixedTimeStep = btScalar(1.) / btScalar(60.)); + virtual void solveConstraints(btContactSolverInfo & solverInfo); + virtual void synchronizeMotionStates(); ///this can be useful to synchronize a single rigid body -> graphics object diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h index 2dca39bb6..f8f0596b5 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -11,42 +11,14 @@ #include "btConjugateGradient.h" #include "btLagrangianForce.h" #include "btMassSpring.h" +#include "btContactProjection.h" +#include "btDeformableRigidDynamicsWorld.h" -struct DirichletDofProjection -{ - using TVStack = btAlignedObjectArray; - const btAlignedObjectArray& m_softBodies; - DirichletDofProjection(const btAlignedObjectArray& softBodies) - : m_softBodies(softBodies) - {} - - void operator()(TVStack& x) - { - size_t counter = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - const btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - if (psb->m_nodes[j].m_im == 0) - { - x[counter].setZero(); - } - ++counter; - } - } - } -}; - +class btDeformableRigidDynamicsWorld; class btBackwardEulerObjective { public: using TVStack = btAlignedObjectArray; - struct EmptyProjection - { - void operator()(TVStack& x) - {} - }; struct DefaultPreconditioner { void operator()(const TVStack& x, TVStack& b) @@ -58,19 +30,19 @@ public: }; btScalar m_dt; btConjugateGradient cg; - + btDeformableRigidDynamicsWorld* m_world; btAlignedObjectArray m_lf; btAlignedObjectArray& m_softBodies; - std::function project; std::function precondition; + btContactProjection projection; - btBackwardEulerObjective(btAlignedObjectArray& softBodies) + btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) : cg(20) , m_softBodies(softBodies) - , project(EmptyProjection()) , precondition(DefaultPreconditioner()) + , projection(m_softBodies, backup_v) { - // this should really be specified in initialization instead of here + // TODO: this should really be specified in initialization instead of here btMassSpring* mass_spring = new btMassSpring(m_softBodies); m_lf.push_back(mass_spring); } @@ -103,7 +75,6 @@ public: void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt) { m_dt = dt; - // TODO:figure out what the tolerance should be btScalar tolerance = std::numeric_limits::epsilon()*16 * computeNorm(residual); cg.solve(*this, dv, residual, tolerance); } @@ -133,24 +104,33 @@ public: } } + void updateProjection(const TVStack& dv) + { + projection.update(m_dt, dv); + } + void reinitialize(bool nodeUpdated) { + if(nodeUpdated) + { + projection.setSoftBodies(m_softBodies); + } for (int i = 0; i < m_lf.size(); ++i) { m_lf[i]->reinitialize(nodeUpdated); - } - - if(nodeUpdated) - { - DirichletDofProjection dirichlet(m_softBodies); - setProjection(dirichlet); + projection.reinitialize(nodeUpdated); } } - template - void setProjection(Func project_func) + void enforceConstraint(TVStack& x) { - project = project_func; + projection.enforceConstraint(x); + } + + void project(TVStack& r, const TVStack& dv) + { + updateProjection(dv); + projection(r); } template @@ -158,6 +138,12 @@ public: { precondition = preconditioner_func; } + + virtual void setWorld(btDeformableRigidDynamicsWorld* world) + { + m_world = world; + projection.setWorld(world); + } }; #endif /* btBackwardEulerObjective_h */ diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h new file mode 100644 index 000000000..89743ef27 --- /dev/null +++ b/src/BulletSoftBody/btCGProjection.h @@ -0,0 +1,80 @@ +// btCGProjection.h +// BulletSoftBody +// +// Created by Xuchen Han on 7/4/19. +// + +#ifndef BT_CG_PROJECTION_H +#define BT_CG_PROJECTION_H + +#include "btSoftBody.h" +#include + +class btDeformableRigidDynamicsWorld; +class btCGProjection +{ +public: +// static const int dim = 3; + using TVStack = btAlignedObjectArray; + using TVArrayStack = btAlignedObjectArray >; + using TArrayStack = btAlignedObjectArray >; + btAlignedObjectArray m_softBodies; + btDeformableRigidDynamicsWorld* m_world; + std::unordered_map m_indices; + TVArrayStack m_constrainedDirections; + TArrayStack m_constrainedValues; + const TVStack& m_backupVelocity; + + btCGProjection(btAlignedObjectArray& softBodies, const TVStack& backup_v) + : m_softBodies(softBodies) + , m_backupVelocity(backup_v) + { + + } + + virtual ~btCGProjection() + { + + } + + // apply the constraints + virtual void operator()(TVStack& x) = 0; + + // update the constraints + virtual void update(btScalar dt, const TVStack& dv) = 0; + + virtual void reinitialize(bool nodeUpdated) + { + if (nodeUpdated) + updateId(); + m_constrainedValues.resize(m_indices.size()); + m_constrainedDirections.resize(m_indices.size()); + } + + void updateId() + { + size_t index = 0; + m_indices.clear(); + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + m_indices[&(psb->m_nodes[j])] = index++; + } + } + } + + void setSoftBodies(btAlignedObjectArray softBodies) + { + m_softBodies.copyFromArray(softBodies); + } + + virtual void setWorld(btDeformableRigidDynamicsWorld* world) + { + m_world = world; + } +}; + + +#endif /* btCGProjection_h */ diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index 76297226d..2754a208d 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -89,7 +89,7 @@ public: // } // return the number of iterations taken - int solve(const TM& A, TVStack& x, const TVStack& b, btScalar tolerance) + int solve(TM& A, TVStack& x, const TVStack& b, btScalar tolerance) { btAssert(x.size() == b.size()); reinitialize(b); @@ -97,7 +97,8 @@ public: // r = b - A * x --with assigned dof zeroed out A.multiply(x, temp); r = sub(b, temp); - A.project(r); + A.project(r,x); + A.enforceConstraint(x); btScalar r_norm = std::sqrt(squaredNorm(r)); if (r_norm < tolerance) { @@ -124,7 +125,8 @@ public: multAndAddTo(-alpha, temp, r); // zero out the dofs of r - A.project(r); + A.project(r,x); + A.enforceConstraint(x); r_norm = std::sqrt(squaredNorm(r)); diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp new file mode 100644 index 000000000..b50918af4 --- /dev/null +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -0,0 +1,142 @@ +// +// btContactProjection.cpp +// BulletSoftBody +// +// Created by Xuchen Han on 7/4/19. +// + +#include "btContactProjection.h" +#include "btDeformableRigidDynamicsWorld.h" +void btContactProjection::update(btScalar dt, const TVStack& dv) +{ + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + psb->m_nodes[j].m_v = m_backupVelocity[counter] + dv[counter]; + ++counter; + } + } + + ///solve rigid body constraints + m_world->btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::solveConstraints(m_world->getSolverInfo()); + + // clear the old constraints + for (int i = 0; i < m_constrainedDirections.size(); ++i) + { + m_constrainedDirections[i].clear(); + m_constrainedValues[i].clear(); + } + + // Set dirichlet constraints + counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + const btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + if (psb->m_nodes[j].m_im == 0) + { + m_constrainedDirections[counter].push_back(btVector3(1,0,0)); + m_constrainedDirections[counter].push_back(btVector3(0,1,0)); + m_constrainedDirections[counter].push_back(btVector3(0,0,1)); + m_constrainedValues[counter].push_back(0); + m_constrainedValues[counter].push_back(0); + m_constrainedValues[counter].push_back(0); + } + ++counter; + } + } + + // loop through contacts to create contact constraints + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + btMultiBodyJacobianData jacobianData; + const btScalar mrg = psb->getCollisionShape()->getMargin(); + for (int i = 0, ni = psb->m_rcontacts.size(); i < ni; ++i) + { + const btSoftBody::RContact& c = psb->m_rcontacts[i]; + + // skip anchor points + if (c.m_node->m_im == 0) + continue; + + const btSoftBody::sCti& cti = c.m_cti; + if (cti.m_colObj->hasContactResponse()) + { + btVector3 va(0, 0, 0); + btRigidBody* rigidCol = 0; + btMultiBodyLinkCollider* multibodyLinkCol = 0; + btScalar* deltaV; + + // grab the velocity of the rigid body + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * dt : btVector3(0, 0, 0); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); + + btScalar vel = 0.0; + for (int j = 0; j < ndof; ++j) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + } + va = cti.m_normal * vel * dt; + } + } + + // TODO: rethink what the velocity of the soft body node should be + // const btVector3 vb = c.m_node->m_x - c.m_node->m_q; + const btVector3 vb = c.m_node->m_v * dt; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, cti.m_normal); + if (dn <= SIMD_EPSILON) + { + const btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); + const btVector3 fv = vr - (cti.m_normal * dn); + // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient +// const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3))); + const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3))+ (cti.m_normal * (dp * c.m_c4))); + + //c.m_node->m_v -= impulse * c.m_c2 / dt; + // TODO: only contact is considered here, add friction later + btVector3 normal = cti.m_normal.normalized(); + btVector3 dv = -impulse * c.m_c2; + btScalar dvn = dv.dot(normal); + m_constrainedDirections[m_indices[c.m_node]].push_back(normal); + m_constrainedValues[m_indices[c.m_node]].push_back(dvn); + + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + if (rigidCol) + rigidCol->applyImpulse(impulse, c.m_c1); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + if (multibodyLinkCol) + { + double multiplier = 0.5; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + } + } + } + } + } + } +} diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h new file mode 100644 index 000000000..dc2c8800e --- /dev/null +++ b/src/BulletSoftBody/btContactProjection.h @@ -0,0 +1,56 @@ +// +// btContactProjection.h +// BulletSoftBody +// +// Created by Xuchen Han on 7/4/19. +// + +#ifndef BT_CONTACT_PROJECTION_H +#define BT_CONTACT_PROJECTION_H +#include "btCGProjection.h" +#include "btSoftBody.h" +#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" +#include +class btContactProjection : public btCGProjection +{ +public: + btContactProjection(btAlignedObjectArray& softBodies, const btAlignedObjectArray& backup_v) + : btCGProjection(softBodies, backup_v) + { + + } + + virtual ~btContactProjection() + { + + } + + // apply the constraints + virtual void operator()(TVStack& x) + { + for (int i = 0; i < x.size(); ++i) + { + for (int j = 0; j < m_constrainedDirections[i].size(); ++j) + { + x[i] -= x[i].dot(m_constrainedDirections[i][j]) * m_constrainedDirections[i][j]; + } + } + } + + virtual void enforceConstraint(TVStack& x) + { + for (int i = 0; i < x.size(); ++i) + { + for (int j = 0; j < m_constrainedDirections[i].size(); ++j) + { + x[i] -= x[i].dot(m_constrainedDirections[i][j]) * m_constrainedDirections[i][j]; + x[i] += m_constrainedValues[i][j] * m_constrainedDirections[i][j]; + } + } + } + + // update the constraints + virtual void update(btScalar dt, const TVStack& dv); +}; +#endif /* btContactProjection_h */ diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 4e36a2112..85441a803 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -10,12 +10,14 @@ #include "btSoftBodySolvers.h" #include "btBackwardEulerObjective.h" - +#include "btDeformableRigidDynamicsWorld.h" #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" struct btCollisionObjectWrapper; +class btDeformableRigidDynamicsWorld; + class btDeformableBodySolver : public btSoftBodySolver { using TVStack = btAlignedObjectArray; @@ -29,13 +31,16 @@ protected: btBackwardEulerObjective m_objective; int m_solveIterations; int m_impulseIterations; + btDeformableRigidDynamicsWorld* m_world; + btAlignedObjectArray m_backupVelocity; public: btDeformableBodySolver() : m_numNodes(0) - , m_objective(m_softBodySet) + , m_objective(m_softBodySet, m_backupVelocity) , m_solveIterations(1) , m_impulseIterations(1) + , m_world(nullptr) { } @@ -76,23 +81,11 @@ public: { bool nodeUpdated = updateNodes(); reinitialize(nodeUpdated); - + backupVelocity(); for (int i = 0; i < m_solveIterations; ++i) { - // get the velocity after contact solve - // TODO: perform contact solve here - for (int j = 0; j < m_impulseIterations; ++j) - { - for (int s = 0; s < m_softBodySet.size(); ++s) - VSolve_RContacts(m_softBodySet[s], 0, solverdt); - } - - // advect with v_n+1 ** to update position based states - // where v_n+1 ** is the velocity after contact response - // only need to advect x here if elastic force is implicit // prepareSolve(solverdt); - m_objective.computeResidual(solverdt, m_residual); m_objective.computeStep(m_dv, m_residual, solverdt); @@ -107,7 +100,9 @@ public: { m_dv.resize(m_numNodes); m_residual.resize(m_numNodes); + m_backupVelocity.resize(m_numNodes); } + for (int i = 0; i < m_dv.size(); ++i) { m_dv[i].setZero(); @@ -151,7 +146,22 @@ public: btSoftBody* psb = m_softBodySet[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { - psb->m_nodes[j].m_v += m_dv[counter++]; + psb->m_nodes[j].m_v = m_backupVelocity[counter] + m_dv[counter]; + ++counter; + } + } + } + + void backupVelocity() + { + // serial implementation + int counter = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + m_backupVelocity[counter++] = psb->m_nodes[j].m_v; } } } @@ -168,6 +178,7 @@ public: } return false; } + virtual void predictMotion(float solverdt) { for (int i = 0; i < m_softBodySet.size(); ++i) @@ -192,78 +203,11 @@ public: // TODO } - void VSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar dt) + virtual void setWorld(btDeformableRigidDynamicsWorld* world) { - const btScalar mrg = psb->getCollisionShape()->getMargin(); - btMultiBodyJacobianData jacobianData; - for (int i = 0, ni = psb->m_rcontacts.size(); i < ni; ++i) - { - const btSoftBody::RContact& c = psb->m_rcontacts[i]; - const btSoftBody::sCti& cti = c.m_cti; - if (cti.m_colObj->hasContactResponse()) - { - btVector3 va(0, 0, 0); - btRigidBody* rigidCol = 0; - btMultiBodyLinkCollider* multibodyLinkCol = 0; - btScalar* deltaV; - - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? rigidCol->getVelocityInLocalPoint(c.m_c1) * dt : btVector3(0, 0, 0); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); - if (multibodyLinkCol) - { - const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - jacobianData.m_jacobians.resize(ndof); - jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); - btScalar* jac = &jacobianData.m_jacobians[0]; - - multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); - deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); - - btScalar vel = 0.0; - for (int j = 0; j < ndof; ++j) - { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; - } - va = cti.m_normal * vel * dt; - } - } - - const btVector3 vb = c.m_node->m_x - c.m_node->m_q; - const btVector3 vr = vb - va; - const btScalar dn = btDot(vr, cti.m_normal); - if (dn <= SIMD_EPSILON) - { - const btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); - const btVector3 fv = vr - (cti.m_normal * dn); - // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst); - c.m_node->m_v -= impulse * c.m_c2 / dt; - - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - if (rigidCol) - rigidCol->applyImpulse(impulse, c.m_c1); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - if (multibodyLinkCol) - { - double multiplier = 0.5; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); - } - } - } - } - } + m_world = world; + m_objective.setWorld(world); } - }; #endif /* btDeformableBodySolver_h */ diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 73d4f67f6..1b21ed5b3 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -18,12 +18,52 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS { btAssert("Solver initialization failed\n"); } + + // from btDiscreteDynamicsWorld singleStepSimulation + if (0 != m_internalPreTickCallback) + { + (*m_internalPreTickCallback)(this, timeStep); + } - btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep); + ///apply gravity, predict motion + btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); + + + btDispatcherInfo& dispatchInfo = btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::getDispatchInfo(); + + dispatchInfo.m_timeStep = timeStep; + dispatchInfo.m_stepCount = 0; + dispatchInfo.m_debugDraw = btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::getDebugDrawer(); + + // only used in CCD +// createPredictiveContacts(timeStep); + + ///perform collision detection + btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::performDiscreteCollisionDetection(); + + btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::calculateSimulationIslands(); + + btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::getSolverInfo().m_timeStep = timeStep; + + if (0 != m_internalTickCallback) + { + (*m_internalTickCallback)(this, timeStep); + } + + +// btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep); ///solve deformable bodies constraints solveDeformableBodiesConstraints(timeStep); + predictUnconstraintMotion(timeStep); + //integrate transforms + btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::integrateTransforms(timeStep); + + ///update vehicle simulation + btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::updateActions(timeStep); + + btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::updateActivationState(timeStep); ///update soft bodies m_deformableBodySolver->updateSoftBodies(); diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 55ed41d86..7f70fef56 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -31,7 +31,6 @@ class btDeformableRigidDynamicsWorld : public btSoftRigidDynamicsWorld ///Solver classes that encapsulate multiple deformable bodies for solving btDeformableBodySolver* m_deformableBodySolver; - protected: virtual void internalSingleStepSimulation(btScalar timeStep); @@ -65,7 +64,7 @@ public: virtual void predictUnconstraintMotion(btScalar timeStep) { - btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); +// btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); m_deformableBodySolver->predictMotion(float(timeStep)); } // virtual void internalStepSingleStepSimulation(btScalar timeStep); From b8997c36b2b1a25e2d3085ded367b65352a45e31 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Sat, 6 Jul 2019 20:55:41 -0700 Subject: [PATCH 03/47] update contact projection --- src/BulletSoftBody/btBackwardEulerObjective.h | 1 + src/BulletSoftBody/btContactProjection.cpp | 5 ++-- src/BulletSoftBody/btDeformableBodySolver.h | 27 +++++++++++++++++-- .../btDeformableRigidDynamicsWorld.cpp | 9 +++++-- .../btDeformableRigidDynamicsWorld.h | 2 +- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h index f8f0596b5..cef07aea1 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -101,6 +101,7 @@ public: { // damping force is implicit and elastic force is explicit m_lf[i]->addScaledDampingForceDifferential(-m_dt, x, b); +// m_lf[i]->addScaledElasticForceDifferential(-m_dt*m_dt, x, b); } } diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index b50918af4..2666ff789 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -76,7 +76,7 @@ void btContactProjection::update(btScalar dt, const TVStack& dv) if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * dt : btVector3(0, 0, 0); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1) + btVector3(0,-10,0)*dt) * dt : btVector3(0, 0, 0); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { @@ -117,7 +117,8 @@ void btContactProjection::update(btScalar dt, const TVStack& dv) //c.m_node->m_v -= impulse * c.m_c2 / dt; // TODO: only contact is considered here, add friction later btVector3 normal = cti.m_normal.normalized(); - btVector3 dv = -impulse * c.m_c2; + btVector3 diff = c.m_node->m_v - m_backupVelocity[m_indices[c.m_node]]; + btVector3 dv = -impulse * c.m_c2/dt + diff; btScalar dvn = dv.dot(normal); m_constrainedDirections[m_indices[c.m_node]].push_back(normal); m_constrainedValues[m_indices[c.m_node]].push_back(dvn); diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 85441a803..5a0a3a05a 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -8,6 +8,7 @@ #ifndef BT_DEFORMABLE_BODY_SOLVERS_H #define BT_DEFORMABLE_BODY_SOLVERS_H +#include #include "btSoftBodySolvers.h" #include "btBackwardEulerObjective.h" #include "btDeformableRigidDynamicsWorld.h" @@ -87,6 +88,7 @@ public: // only need to advect x here if elastic force is implicit // prepareSolve(solverdt); m_objective.computeResidual(solverdt, m_residual); + moveTempVelocity(solverdt, m_residual); m_objective.computeStep(m_dv, m_residual, solverdt); updateVelocity(); @@ -94,6 +96,20 @@ public: advect(solverdt); } + void moveTempVelocity(btScalar dt, const TVStack& f) + { + size_t counter = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + auto& node = psb->m_nodes[j]; + node.m_v += node.m_im * dt * f[counter++]; + } + } + } + void reinitialize(bool nodeUpdated) { if (nodeUpdated) @@ -119,7 +135,7 @@ public: for (int j = 0; j < psb->m_nodes.size(); ++j) { auto& node = psb->m_nodes[j]; - node.m_x = node.m_q + dt * node.m_v * psb->m_dampingCoefficient; + node.m_x = node.m_q + dt * node.m_v; } } } @@ -132,7 +148,13 @@ public: for (int j = 0; j < psb->m_nodes.size(); ++j) { auto& node = psb->m_nodes[j]; - node.m_x += dt * m_dv[counter++]; +// node.m_x += dt * m_dv[counter++]; + node.m_x += dt * node.m_v; + if (j == 4) + { + std::cout << "x " << psb->m_nodes[j].m_x.getY() << std::endl; + std::cout << "v " << psb->m_nodes[j].m_v.getY() << std::endl; + } } } } @@ -147,6 +169,7 @@ public: for (int j = 0; j < psb->m_nodes.size(); ++j) { psb->m_nodes[j].m_v = m_backupVelocity[counter] + m_dv[counter]; + ++counter; } } diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 1b21ed5b3..c0afc98d4 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -26,7 +26,7 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS } ///apply gravity, predict motion - btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); + predictUnconstraintMotion(timeStep); btDispatcherInfo& dispatchInfo = btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::getDispatchInfo(); @@ -56,7 +56,7 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS ///solve deformable bodies constraints solveDeformableBodiesConstraints(timeStep); - predictUnconstraintMotion(timeStep); +// predictUnconstraintMotion(timeStep); //integrate transforms btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::integrateTransforms(timeStep); @@ -68,6 +68,11 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS ///update soft bodies m_deformableBodySolver->updateSoftBodies(); + for (int i = 0; i < m_nonStaticRigidBodies.size(); i++) + { + btRigidBody* body = m_nonStaticRigidBodies[i]; + std::cout << "rb v = " << body->getLinearVelocity().getY() << std::endl; + } // End solver-wise simulation step // /////////////////////////////// } diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 7f70fef56..98dc4602c 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -64,7 +64,7 @@ public: virtual void predictUnconstraintMotion(btScalar timeStep) { -// btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); + btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); m_deformableBodySolver->predictMotion(float(timeStep)); } // virtual void internalStepSingleStepSimulation(btScalar timeStep); From 786b0436ec3eda6fd46066adfa34d35f8a346e9b Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Sun, 7 Jul 2019 14:31:19 -0700 Subject: [PATCH 04/47] fixed gravity issue in rigid body and deformable body contact solve --- examples/DeformableDemo/DeformableDemo.cpp | 125 ++++++++---------- src/BulletSoftBody/btBackwardEulerObjective.h | 2 +- src/BulletSoftBody/btCGProjection.h | 4 +- src/BulletSoftBody/btContactProjection.cpp | 19 +-- src/BulletSoftBody/btContactProjection.h | 4 +- src/BulletSoftBody/btDeformableBodySolver.h | 24 +--- .../btDeformableRigidDynamicsWorld.cpp | 15 ++- 7 files changed, 72 insertions(+), 121 deletions(-) diff --git a/examples/DeformableDemo/DeformableDemo.cpp b/examples/DeformableDemo/DeformableDemo.cpp index 7edc3c4a3..990bdd7b9 100644 --- a/examples/DeformableDemo/DeformableDemo.cpp +++ b/examples/DeformableDemo/DeformableDemo.cpp @@ -59,16 +59,45 @@ public: void resetCamera() { -// float dist = 30; -// float pitch = -14; -// float yaw = 0; -// float targetPos[3] = {0, 0, 0}; - float dist = 45; + float dist = 15; float pitch = -45; float yaw = 100; - float targetPos[3] = {0,0, 0}; + float targetPos[3] = {0, -5, 0}; m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } + + + void Ctor_RbUpStack(int count) + { + float mass = 1; + + btCompoundShape* cylinderCompound = new btCompoundShape; + btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(2, .5, .5)); + btCollisionShape* boxShape = new btBoxShape(btVector3(2, .5, .5)); + btTransform localTransform; + localTransform.setIdentity(); + cylinderCompound->addChildShape(localTransform, boxShape); + btQuaternion orn(SIMD_HALF_PI, 0, 0); + localTransform.setRotation(orn); + // localTransform.setOrigin(btVector3(1,1,1)); + cylinderCompound->addChildShape(localTransform, cylinderShape); + + btCollisionShape* shape[] = { + new btBoxShape(btVector3(1, 1, 1)), + cylinderCompound, + new btSphereShape(0.75) + + }; + static const int nshapes = sizeof(shape) / sizeof(shape[0]); + for (int i = 0; i < count; ++i) + { + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0, 3 + 3 * i, 0)); + createRigidBody(mass, startTransform, shape[i % nshapes]); + } + } + virtual const btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() const { ///just make it a btSoftRigidDynamicsWorld please @@ -105,7 +134,6 @@ void DeformableDemo::initPhysics() m_guiHelper->setUpAxis(1); ///collision configuration contains default setup for memory, collision setup -// m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) @@ -119,22 +147,22 @@ void DeformableDemo::initPhysics() m_solver = sol; m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration, deformableBodySolver); + deformableBodySolver->setWorld(getDeformableDynamicsWorld()); // m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); getDeformableDynamicsWorld()->getSoftDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); { - ///create a few basic rigid bodies -// btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.), btScalar(5.), btScalar(25.))); - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.), btScalar(25.), btScalar(50.))); + ///create a ground + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0, -30, 0)); -// groundTransform.setRotation(btQuaternion(btVector3(0, 1, 0), SIMD_PI * 0.03)); + groundTransform.setOrigin(btVector3(0, -50, 0)); + groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: btScalar mass(0.); @@ -151,76 +179,30 @@ void DeformableDemo::initPhysics() btRigidBody* body = new btRigidBody(rbInfo); body->setFriction(.5); - //add the body to the dynamics world + //add the ground to the dynamics world m_dynamicsWorld->addRigidBody(body); } -// -// { -// ///create a few basic rigid bodies -// btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(100.), btScalar(100.), btScalar(50.))); -// -// m_collisionShapes.push_back(groundShape); -// -// btTransform groundTransform; -// groundTransform.setIdentity(); -// groundTransform.setOrigin(btVector3(0, 0, -54)); -// //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: -// btScalar mass(0.); -// -// //rigidbody is dynamic if and only if mass is non zero, otherwise static -// bool isDynamic = (mass != 0.f); -// -// btVector3 localInertia(0, 0, 0); -// if (isDynamic) -// groundShape->calculateLocalInertia(mass, localInertia); -// -// //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects -// btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); -// btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); -// btRigidBody* body = new btRigidBody(rbInfo); -// body->setFriction(.1); -// //add the body to the dynamics world -// m_dynamicsWorld->addRigidBody(body); -// } -// -// { -// // add a simple deformable body -// const btVector3 s(3,2,1); // side length -// const btVector3 p(0,30,0); // origin; -// const btVector3 h = s * 0.5; -// const btVector3 c[] = {p + h * btVector3(-1, -1, -1), -// p + h * btVector3(+1, -1, -1), -// p + h * btVector3(-1, +1, -1), -// p + h * btVector3(+1, +1, -1), -// p + h * btVector3(-1, -1, +1), -// p + h * btVector3(+1, -1, +1), -// p + h * btVector3(-1, +1, +1), -// p + h * btVector3(+1, +1, +1)}; -// btSoftBody* psb = btSoftBodyHelpers::CreateFromConvexHull(getDeformableDynamicsWorld()->getSoftDynamicsWorld()->getWorldInfo(), c, 8); -// psb->generateBendingConstraints(2); -// psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS; -// psb->setTotalMass(150); -// getDeformableDynamicsWorld()->addSoftBody(psb); -// } + + // create a piece of cloth { - const btScalar s = 8; + const btScalar s = 4; btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getSoftDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), btVector3(+s, 0, -s), btVector3(-s, 0, +s), btVector3(+s, 0, +s), - 10, 10, - // 31,31, +// 3, 3, + 20,20, 1 + 2 + 4 + 8, true); // 0, true); - psb->getCollisionShape()->setMargin(0.5); -// btSoftBody::Material* pm = psb->appendMaterial(); -// pm->m_kLST = 0.4 * 1000; -// pm->m_flags -= btSoftBody::fMaterial::DebugDraw; + psb->getCollisionShape()->setMargin(0.25); psb->generateBendingConstraints(2); - psb->setTotalMass(1); - psb->setDampingCoefficient(0.01); + psb->setTotalMass(2); + psb->setDampingCoefficient(0.02); getDeformableDynamicsWorld()->addSoftBody(psb); + + // add a few rigid bodies + Ctor_RbUpStack(10); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } @@ -263,7 +245,10 @@ void DeformableDemo::exitPhysics() } + class CommonExampleInterface* DeformableCreateFunc(struct CommonExampleOptions& options) { return new DeformableDemo(options.m_guiHelper); } + + diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h index cef07aea1..5e81fc0f2 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -40,7 +40,7 @@ public: : cg(20) , m_softBodies(softBodies) , precondition(DefaultPreconditioner()) - , projection(m_softBodies, backup_v) + , projection(m_softBodies) { // TODO: this should really be specified in initialization instead of here btMassSpring* mass_spring = new btMassSpring(m_softBodies); diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 89743ef27..533e19c7a 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -23,11 +23,9 @@ public: std::unordered_map m_indices; TVArrayStack m_constrainedDirections; TArrayStack m_constrainedValues; - const TVStack& m_backupVelocity; - btCGProjection(btAlignedObjectArray& softBodies, const TVStack& backup_v) + btCGProjection(btAlignedObjectArray& softBodies) : m_softBodies(softBodies) - , m_backupVelocity(backup_v) { } diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 2666ff789..8f9f9225a 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -9,17 +9,6 @@ #include "btDeformableRigidDynamicsWorld.h" void btContactProjection::update(btScalar dt, const TVStack& dv) { - size_t counter = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - psb->m_nodes[j].m_v = m_backupVelocity[counter] + dv[counter]; - ++counter; - } - } - ///solve rigid body constraints m_world->btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::solveConstraints(m_world->getSolverInfo()); @@ -31,7 +20,7 @@ void btContactProjection::update(btScalar dt, const TVStack& dv) } // Set dirichlet constraints - counter = 0; + size_t counter = 0; for (int i = 0; i < m_softBodies.size(); ++i) { const btSoftBody* psb = m_softBodies[i]; @@ -76,7 +65,7 @@ void btContactProjection::update(btScalar dt, const TVStack& dv) if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1) + btVector3(0,-10,0)*dt) * dt : btVector3(0, 0, 0); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * dt : btVector3(0, 0, 0); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { @@ -114,11 +103,9 @@ void btContactProjection::update(btScalar dt, const TVStack& dv) // const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3))); const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3))+ (cti.m_normal * (dp * c.m_c4))); - //c.m_node->m_v -= impulse * c.m_c2 / dt; // TODO: only contact is considered here, add friction later btVector3 normal = cti.m_normal.normalized(); - btVector3 diff = c.m_node->m_v - m_backupVelocity[m_indices[c.m_node]]; - btVector3 dv = -impulse * c.m_c2/dt + diff; + btVector3 dv = -impulse * c.m_c2/dt; btScalar dvn = dv.dot(normal); m_constrainedDirections[m_indices[c.m_node]].push_back(normal); m_constrainedValues[m_indices[c.m_node]].push_back(dvn); diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index dc2c8800e..e1c3bc50d 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -15,8 +15,8 @@ class btContactProjection : public btCGProjection { public: - btContactProjection(btAlignedObjectArray& softBodies, const btAlignedObjectArray& backup_v) - : btCGProjection(softBodies, backup_v) + btContactProjection(btAlignedObjectArray& softBodies) + : btCGProjection(softBodies) { } diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 5a0a3a05a..9afec42dc 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -82,13 +82,11 @@ public: { bool nodeUpdated = updateNodes(); reinitialize(nodeUpdated); - backupVelocity(); for (int i = 0; i < m_solveIterations; ++i) { // only need to advect x here if elastic force is implicit // prepareSolve(solverdt); m_objective.computeResidual(solverdt, m_residual); - moveTempVelocity(solverdt, m_residual); m_objective.computeStep(m_dv, m_residual, solverdt); updateVelocity(); @@ -116,7 +114,6 @@ public: { m_dv.resize(m_numNodes); m_residual.resize(m_numNodes); - m_backupVelocity.resize(m_numNodes); } for (int i = 0; i < m_dv.size(); ++i) @@ -150,11 +147,6 @@ public: auto& node = psb->m_nodes[j]; // node.m_x += dt * m_dv[counter++]; node.m_x += dt * node.m_v; - if (j == 4) - { - std::cout << "x " << psb->m_nodes[j].m_x.getY() << std::endl; - std::cout << "v " << psb->m_nodes[j].m_v.getY() << std::endl; - } } } } @@ -168,27 +160,13 @@ public: btSoftBody* psb = m_softBodySet[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { - psb->m_nodes[j].m_v = m_backupVelocity[counter] + m_dv[counter]; + psb->m_nodes[j].m_v += m_dv[counter]; ++counter; } } } - void backupVelocity() - { - // serial implementation - int counter = 0; - for (int i = 0; i < m_softBodySet.size(); ++i) - { - btSoftBody* psb = m_softBodySet[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - m_backupVelocity[counter++] = psb->m_nodes[j].m_v; - } - } - } - bool updateNodes() { int numNodes = 0; diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index c0afc98d4..82b24ccb8 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -53,6 +53,14 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS // btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep); + // incorporate gravity into velocity and clear force + for (int i = 0; i < m_nonStaticRigidBodies.size(); ++i) + { + btRigidBody* rb = m_nonStaticRigidBodies[i]; + rb->integrateVelocities(timeStep); + } + clearForces(); + ///solve deformable bodies constraints solveDeformableBodiesConstraints(timeStep); @@ -67,12 +75,7 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS ///update soft bodies m_deformableBodySolver->updateSoftBodies(); - - for (int i = 0; i < m_nonStaticRigidBodies.size(); i++) - { - btRigidBody* body = m_nonStaticRigidBodies[i]; - std::cout << "rb v = " << body->getLinearVelocity().getY() << std::endl; - } + // End solver-wise simulation step // /////////////////////////////// } From 13d4e1cc2bb79e28e63990fbf77fb4c1eb8aeb10 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Tue, 9 Jul 2019 14:26:04 -0700 Subject: [PATCH 05/47] bug fixes in constraints projections; cpplized various functions --- .../btBackwardEulerObjective.cpp | 88 ++++++++++ src/BulletSoftBody/btBackwardEulerObjective.h | 68 ++------ src/BulletSoftBody/btCGProjection.h | 17 +- src/BulletSoftBody/btConjugateGradient.h | 68 +------- src/BulletSoftBody/btContactProjection.cpp | 151 ++++++++++++----- src/BulletSoftBody/btContactProjection.h | 8 +- src/BulletSoftBody/btDeformableBodySolver.cpp | 157 ++++++++++++++++++ src/BulletSoftBody/btDeformableBodySolver.h | 89 +++------- .../btDeformableRigidDynamicsWorld.cpp | 39 ++++- .../btDeformableRigidDynamicsWorld.h | 19 +-- src/BulletSoftBody/btMassSpring.h | 7 +- src/BulletSoftBody/btSoftBodyInternals.h | 2 +- 12 files changed, 450 insertions(+), 263 deletions(-) create mode 100644 src/BulletSoftBody/btBackwardEulerObjective.cpp create mode 100644 src/BulletSoftBody/btDeformableBodySolver.cpp diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp new file mode 100644 index 000000000..22614c994 --- /dev/null +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -0,0 +1,88 @@ +// +// btBackwardEulerObjective.cpp +// BulletSoftBody +// +// Created by Xuchen Han on 7/9/19. +// + +#include "btBackwardEulerObjective.h" + +btBackwardEulerObjective::btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) +: cg(20) +, m_softBodies(softBodies) +, precondition(DefaultPreconditioner()) +, projection(m_softBodies, m_dt) +, m_backupVelocity(backup_v) +{ + // TODO: this should really be specified in initialization instead of here + btMassSpring* mass_spring = new btMassSpring(m_softBodies); + m_lf.push_back(mass_spring); +} + +void btBackwardEulerObjective::reinitialize(bool nodeUpdated) +{ + if(nodeUpdated) + { + projection.setSoftBodies(m_softBodies); + } + for (int i = 0; i < m_lf.size(); ++i) + { + m_lf[i]->reinitialize(nodeUpdated); + projection.reinitialize(nodeUpdated); + } +} + + +void btBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const +{ + for (int i = 0; i < b.size(); ++i) + b[i].setZero(); + + // add in the mass term + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + const auto& node = psb->m_nodes[j]; + b[counter] += (node.m_im == 0) ? btVector3(0,0,0) : x[counter] / node.m_im; + ++counter; + } + } + + for (int i = 0; i < m_lf.size(); ++i) + { + // add damping matrix + m_lf[i]->addScaledDampingForceDifferential(-m_dt, x, b); + + // add stiffness matrix when fully implicity + m_lf[i]->addScaledElasticForceDifferential(-m_dt*m_dt, x, b); + } +} + +void btBackwardEulerObjective::computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt) +{ + m_dt = dt; + btScalar tolerance = std::numeric_limits::epsilon()* 16 * computeNorm(residual); + cg.solve(*this, dv, residual, tolerance); + } + +void btBackwardEulerObjective::updateVelocity(const TVStack& dv) +{ + for (int i = 0; i < m_softBodies.size(); ++i) + { + int counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + // only the velocity of the constrained nodes needs to be updated during CG solve + if (projection.m_constrainedDirections.size() > 0) + psb->m_nodes[j].m_v = m_backupVelocity[counter] + dv[counter]; + ++counter; + } + } + } +} diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h index 5e81fc0f2..424291700 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -35,17 +35,9 @@ public: btAlignedObjectArray& m_softBodies; std::function precondition; btContactProjection projection; + const TVStack& m_backupVelocity; - btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) - : cg(20) - , m_softBodies(softBodies) - , precondition(DefaultPreconditioner()) - , projection(m_softBodies) - { - // TODO: this should really be specified in initialization instead of here - btMassSpring* mass_spring = new btMassSpring(m_softBodies); - m_lf.push_back(mass_spring); - } + btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v); virtual ~btBackwardEulerObjective() {} @@ -54,7 +46,6 @@ public: void computeResidual(btScalar dt, TVStack& residual) const { // gravity is treated explicitly in predictUnconstraintMotion - // add force for (int i = 0; i < m_lf.size(); ++i) { @@ -72,62 +63,29 @@ public: return std::sqrt(norm_squared); } - void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt) - { - m_dt = dt; - btScalar tolerance = std::numeric_limits::epsilon()*16 * computeNorm(residual); - cg.solve(*this, dv, residual, tolerance); - } + void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt); - void multiply(const TVStack& x, TVStack& b) const - { - for (int i = 0; i < b.size(); ++i) - b[i].setZero(); - - // add in the mass term - size_t counter = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - const auto& node = psb->m_nodes[j]; - b[counter] += (node.m_im == 0) ? btVector3(0,0,0) : x[counter] / node.m_im; - ++counter; - } - } - - for (int i = 0; i < m_lf.size(); ++i) - { - // damping force is implicit and elastic force is explicit - m_lf[i]->addScaledDampingForceDifferential(-m_dt, x, b); -// m_lf[i]->addScaledElasticForceDifferential(-m_dt*m_dt, x, b); - } - } + void multiply(const TVStack& x, TVStack& b) const; void updateProjection(const TVStack& dv) { - projection.update(m_dt, dv); + projection.update(dv, m_backupVelocity); } - void reinitialize(bool nodeUpdated) - { - if(nodeUpdated) - { - projection.setSoftBodies(m_softBodies); - } - for (int i = 0; i < m_lf.size(); ++i) - { - m_lf[i]->reinitialize(nodeUpdated); - projection.reinitialize(nodeUpdated); - } - } + void reinitialize(bool nodeUpdated); void enforceConstraint(TVStack& x) { projection.enforceConstraint(x); + updateVelocity(x); } + void updateVelocity(const TVStack& dv); + + void setConstraintDirections() + { + projection.setConstraintDirections(); + } void project(TVStack& r, const TVStack& dv) { updateProjection(dv); diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 533e19c7a..8648e99f8 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -23,30 +23,39 @@ public: std::unordered_map m_indices; TVArrayStack m_constrainedDirections; TArrayStack m_constrainedValues; + const btScalar& m_dt; - btCGProjection(btAlignedObjectArray& softBodies) + btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : m_softBodies(softBodies) + , m_dt(dt) { - } virtual ~btCGProjection() { - } // apply the constraints virtual void operator()(TVStack& x) = 0; + virtual void setConstraintDirections() = 0; + // update the constraints - virtual void update(btScalar dt, const TVStack& dv) = 0; + virtual void update(const TVStack& dv, const TVStack& backup_v) = 0; virtual void reinitialize(bool nodeUpdated) { if (nodeUpdated) updateId(); + + // resize and clear the old constraints m_constrainedValues.resize(m_indices.size()); m_constrainedDirections.resize(m_indices.size()); + for (int i = 0; i < m_constrainedDirections.size(); ++i) + { + m_constrainedDirections[i].clear(); + m_constrainedValues[i].clear(); + } } void updateId() diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index 2754a208d..0a88e6b94 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -8,6 +8,10 @@ #ifndef BT_CONJUGATE_GRADIENT_H #define BT_CONJUGATE_GRADIENT_H #include +#include +#include +#include + template class btConjugateGradient { @@ -25,69 +29,6 @@ public: virtual ~btConjugateGradient(){} -// // return the number of iterations taken -// int solve(const TM& A, TVStack& x, const TVStack& b, btScalar tolerance) -// { -// btAssert(x.size() == b.size()); -// reinitialize(b); -// -// // r = M * (b - A * x) --with assigned dof zeroed out -// A.multiply(x, temp); -// temp = sub(b, temp); -// A.project(temp); -// A.precondition(temp, r); -// -// btScalar r_dot_r = squaredNorm(r), r_dot_r_new; -// btScalar r_norm = std::sqrt(r_dot_r); -// if (r_norm < tolerance) { -// std::cout << "Iteration = 0" << std::endl; -// std::cout << "Two norm of the residual = " << r_norm << std::endl; -// return 0; -// } -// -// p = r; -// // q = M * A * q; -// A.multiply(p, temp); -// A.precondition(temp, q); -// -// // alpha = |r|^2 / (p^T * A * p) -// btScalar alpha = r_dot_r / dot(p, q), beta; -// -// for (int k = 1; k < max_iterations; k++) { -//// x += alpha * p; -//// r -= alpha * q; -// multAndAddTo(alpha, p, x); -// multAndAddTo(-alpha, q, r); -// -// // zero out the dofs of r -// A.project(r); -// -// r_dot_r_new = squaredNorm(r); -// r_norm = std::sqrt(r_dot_r_new); -// -// if (r_norm < tolerance) { -// std::cout << "ConjugateGradient iterations " << k << std::endl; -// return k; -// -// beta = r_dot_r_new / r_dot_r; -// r_dot_r = r_dot_r_new; -//// p = r + beta * p; -// p = multAndAdd(beta, p, r); -// -// // q = M * A * q; -// A.multiply(p, temp); -// A.precondition(temp, q); -// -// alpha = r_dot_r / dot(p, q); -// } -// -// setZero(q); -// setZero(r); -// } -// std::cout << "ConjugateGradient max iterations reached " << max_iterations << std::endl; -// return max_iterations; -// } - // return the number of iterations taken int solve(TM& A, TVStack& x, const TVStack& b, btScalar tolerance) { @@ -109,7 +50,6 @@ public: // z = M^(-1) * r A.precondition(r, z); - // p = z; p = z; // temp = A*p A.multiply(p, temp); diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 8f9f9225a..4db3e019e 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -7,44 +7,16 @@ #include "btContactProjection.h" #include "btDeformableRigidDynamicsWorld.h" -void btContactProjection::update(btScalar dt, const TVStack& dv) +void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocity) { ///solve rigid body constraints m_world->btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::solveConstraints(m_world->getSolverInfo()); - - // clear the old constraints - for (int i = 0; i < m_constrainedDirections.size(); ++i) - { - m_constrainedDirections[i].clear(); - m_constrainedValues[i].clear(); - } - - // Set dirichlet constraints - size_t counter = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - const btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - if (psb->m_nodes[j].m_im == 0) - { - m_constrainedDirections[counter].push_back(btVector3(1,0,0)); - m_constrainedDirections[counter].push_back(btVector3(0,1,0)); - m_constrainedDirections[counter].push_back(btVector3(0,0,1)); - m_constrainedValues[counter].push_back(0); - m_constrainedValues[counter].push_back(0); - m_constrainedValues[counter].push_back(0); - } - ++counter; - } - } - + // loop through contacts to create contact constraints for (int i = 0; i < m_softBodies.size(); ++i) { btSoftBody* psb = m_softBodies[i]; btMultiBodyJacobianData jacobianData; - const btScalar mrg = psb->getCollisionShape()->getMargin(); for (int i = 0, ni = psb->m_rcontacts.size(); i < ni; ++i) { const btSoftBody::RContact& c = psb->m_rcontacts[i]; @@ -65,7 +37,7 @@ void btContactProjection::update(btScalar dt, const TVStack& dv) if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * dt : btVector3(0, 0, 0); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * m_dt : btVector3(0, 0, 0); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { @@ -86,29 +58,25 @@ void btContactProjection::update(btScalar dt, const TVStack& dv) { vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; } - va = cti.m_normal * vel * dt; + va = cti.m_normal * vel * m_dt; } } - // TODO: rethink what the velocity of the soft body node should be - // const btVector3 vb = c.m_node->m_x - c.m_node->m_q; - const btVector3 vb = c.m_node->m_v * dt; + const btVector3 vb = c.m_node->m_v * m_dt; const btVector3 vr = vb - va; const btScalar dn = btDot(vr, cti.m_normal); - if (dn <= SIMD_EPSILON) + if (1) // in the same CG solve, the set of constraits doesn't change +// if (dn <= SIMD_EPSILON) { - const btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); - const btVector3 fv = vr - (cti.m_normal * dn); // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient -// const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3))); - const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3))+ (cti.m_normal * (dp * c.m_c4))); - + const btVector3 impulse = c.m_c0 *(cti.m_normal * dn); // TODO: only contact is considered here, add friction later - btVector3 normal = cti.m_normal.normalized(); - btVector3 dv = -impulse * c.m_c2/dt; - btScalar dvn = dv.dot(normal); - m_constrainedDirections[m_indices[c.m_node]].push_back(normal); - m_constrainedValues[m_indices[c.m_node]].push_back(dvn); + + // dv = new_impulse + accumulated velocity change in previous CG iterations + // so we have the invariant node->m_v = backupVelocity + dv; + btVector3 dv = -impulse * c.m_c2/m_dt + c.m_node->m_v - backupVelocity[m_indices[c.m_node]]; + btScalar dvn = dv.dot(cti.m_normal); + m_constrainedValues[m_indices[c.m_node]][0]=(dvn); if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { @@ -128,3 +96,94 @@ void btContactProjection::update(btScalar dt, const TVStack& dv) } } } + +void btContactProjection::setConstraintDirections() +{ + // set Dirichlet constraint + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + const btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + if (psb->m_nodes[j].m_im == 0) + { + m_constrainedDirections[counter].push_back(btVector3(1,0,0)); + m_constrainedDirections[counter].push_back(btVector3(0,1,0)); + m_constrainedDirections[counter].push_back(btVector3(0,0,1)); + m_constrainedValues[counter].push_back(0); + m_constrainedValues[counter].push_back(0); + m_constrainedValues[counter].push_back(0); + } + ++counter; + } + } + + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + btMultiBodyJacobianData jacobianData; + + int j = 0; + while (j < psb->m_rcontacts.size()) + { + const btSoftBody::RContact& c = psb->m_rcontacts[j]; + // skip anchor points + if (c.m_node->m_im == 0) + { + psb->m_rcontacts.removeAtIndex(j); + continue; + } + + const btSoftBody::sCti& cti = c.m_cti; + if (cti.m_colObj->hasContactResponse()) + { + btVector3 va(0, 0, 0); + btRigidBody* rigidCol = 0; + btMultiBodyLinkCollider* multibodyLinkCol = 0; + btScalar* deltaV; + + // grab the velocity of the rigid body + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * m_dt : btVector3(0, 0, 0); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); + + btScalar vel = 0.0; + for (int j = 0; j < ndof; ++j) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + } + va = cti.m_normal * vel * m_dt; + } + } + + const btVector3 vb = c.m_node->m_v * m_dt; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, cti.m_normal); + if (dn < SIMD_EPSILON) + { + ++j; + m_constrainedDirections[m_indices[c.m_node]].push_back(cti.m_normal); + m_constrainedValues[m_indices[c.m_node]].resize(m_constrainedValues[m_indices[c.m_node]].size()+1); + continue; + } + } + psb->m_rcontacts.removeAtIndex(j); + } + } +} diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index e1c3bc50d..5598ada0a 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -15,8 +15,8 @@ class btContactProjection : public btCGProjection { public: - btContactProjection(btAlignedObjectArray& softBodies) - : btCGProjection(softBodies) + btContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt) + : btCGProjection(softBodies, dt) { } @@ -51,6 +51,8 @@ public: } // update the constraints - virtual void update(btScalar dt, const TVStack& dv); + virtual void update(const TVStack& dv, const TVStack& backupVelocity); + + virtual void setConstraintDirections(); }; #endif /* btContactProjection_h */ diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp new file mode 100644 index 000000000..d3d448db0 --- /dev/null +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -0,0 +1,157 @@ +// +// btDeformableBodySolver.cpp +// BulletSoftBody +// +// Created by Xuchen Han on 7/9/19. +// + +#include +#include "btDeformableBodySolver.h" + +void btDeformableBodySolver::postStabilize() +{ + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + btMultiBodyJacobianData jacobianData; + const btScalar mrg = psb->getCollisionShape()->getMargin(); + for (int j = 0; j < psb->m_rcontacts.size(); ++j) + { + const btSoftBody::RContact& c = psb->m_rcontacts[j]; + // skip anchor points + if (c.m_node->m_im == 0) + continue; + + const btSoftBody::sCti& cti = c.m_cti; + if (cti.m_colObj->hasContactResponse()) + { + btVector3 va(0, 0, 0); + btRigidBody* rigidCol = 0; + btMultiBodyLinkCollider* multibodyLinkCol = 0; + btScalar* deltaV; + + // grab the velocity of the rigid body + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * m_dt : btVector3(0, 0, 0); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); + + btScalar vel = 0.0; + for (int j = 0; j < ndof; ++j) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + } + va = cti.m_normal * vel * m_dt; + } + } + + const btVector3 vb = c.m_node->m_v * m_dt; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, cti.m_normal); + + const btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); + + // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient + + btScalar dvn = dn * c.m_c4; + const btVector3 impulse = c.m_c0 * ((cti.m_normal * (dn * c.m_c4))); + // TODO: only contact is considered here, add friction later + if (dp < 0) + { + c.m_node->m_x -= dp * cti.m_normal * c.m_c4; + + //// + // if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + // { + // if (rigidCol) + // rigidCol->applyImpulse(impulse, c.m_c1); + // } + } + // else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + // { + // if (multibodyLinkCol) + // { + // double multiplier = 0.5; + // multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + // } + // } + } + } + } +} + +void btDeformableBodySolver::solveConstraints(float solverdt) +{ + m_dt = solverdt; + bool nodeUpdated = updateNodes(); + reinitialize(nodeUpdated); + backupVelocity(); + postStabilize(); + for (int i = 0; i < m_solveIterations; ++i) + { + m_objective->computeResidual(solverdt, m_residual); + m_objective->computeStep(m_dv, m_residual, solverdt); + updateVelocity(); + } + advect(solverdt); +} + +void btDeformableBodySolver::reinitialize(bool nodeUpdated) +{ + if (nodeUpdated) + { + m_dv.resize(m_numNodes); + m_residual.resize(m_numNodes); + } + + for (int i = 0; i < m_dv.size(); ++i) + { + m_dv[i].setZero(); + m_residual[i].setZero(); + } + m_objective->reinitialize(nodeUpdated); + + // remove contact constraints with separating velocity + setConstraintDirections(); +} + +void btDeformableBodySolver::setConstraintDirections() +{ + m_objective->setConstraintDirections(); +} + +void btDeformableBodySolver::setWorld(btDeformableRigidDynamicsWorld* world) +{ + m_world = world; + m_objective->setWorld(world); +} + +void btDeformableBodySolver::updateVelocity() +{ + // serial implementation + int counter = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { +// psb->m_nodes[j].m_v += m_dv[counter]; + psb->m_nodes[j].m_v = m_backupVelocity[counter]+m_dv[counter]; + ++counter; + } + } +} diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 9afec42dc..540a2b6cb 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -16,7 +16,7 @@ #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" struct btCollisionObjectWrapper; - +class btBackwardEulerObjective; class btDeformableRigidDynamicsWorld; class btDeformableBodySolver : public btSoftBodySolver @@ -29,25 +29,17 @@ protected: TVStack m_dv; TVStack m_residual; btAlignedObjectArray m_softBodySet; - btBackwardEulerObjective m_objective; + btBackwardEulerObjective* m_objective; int m_solveIterations; int m_impulseIterations; btDeformableRigidDynamicsWorld* m_world; btAlignedObjectArray m_backupVelocity; + btScalar m_dt; public: - btDeformableBodySolver() - : m_numNodes(0) - , m_objective(m_softBodySet, m_backupVelocity) - , m_solveIterations(1) - , m_impulseIterations(1) - , m_world(nullptr) - { - } + btDeformableBodySolver(); - virtual ~btDeformableBodySolver() - { - } + virtual ~btDeformableBodySolver(); virtual SolverTypes getSolverType() const { @@ -78,21 +70,9 @@ public: virtual void copyBackToSoftBodies(bool bMove = true) {} - virtual void solveConstraints(float solverdt) - { - bool nodeUpdated = updateNodes(); - reinitialize(nodeUpdated); - for (int i = 0; i < m_solveIterations; ++i) - { - // only need to advect x here if elastic force is implicit -// prepareSolve(solverdt); - m_objective.computeResidual(solverdt, m_residual); - m_objective.computeStep(m_dv, m_residual, solverdt); - - updateVelocity(); - } - advect(solverdt); - } + virtual void solveConstraints(float solverdt); + + void postStabilize(); void moveTempVelocity(btScalar dt, const TVStack& f) { @@ -108,34 +88,10 @@ public: } } - void reinitialize(bool nodeUpdated) - { - if (nodeUpdated) - { - m_dv.resize(m_numNodes); - m_residual.resize(m_numNodes); - } - - for (int i = 0; i < m_dv.size(); ++i) - { - m_dv[i].setZero(); - m_residual[i].setZero(); - } - m_objective.reinitialize(nodeUpdated); - } + void reinitialize(bool nodeUpdated); + + void setConstraintDirections(); - void prepareSolve(btScalar dt) - { - for (int i = 0; i < m_softBodySet.size(); ++i) - { - btSoftBody* psb = m_softBodySet[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - auto& node = psb->m_nodes[j]; - node.m_x = node.m_q + dt * node.m_v; - } - } - } void advect(btScalar dt) { size_t counter = 0; @@ -145,13 +101,13 @@ public: for (int j = 0; j < psb->m_nodes.size(); ++j) { auto& node = psb->m_nodes[j]; -// node.m_x += dt * m_dv[counter++]; - node.m_x += dt * node.m_v; + node.m_x += dt * m_dv[counter++]; +// node.m_x = node.m_q + dt * node.m_v; } } } - void updateVelocity() + void backupVelocity() { // serial implementation int counter = 0; @@ -160,13 +116,13 @@ public: btSoftBody* psb = m_softBodySet[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { - psb->m_nodes[j].m_v += m_dv[counter]; - - ++counter; + m_backupVelocity[counter++] = psb->m_nodes[j].m_v; } } } + void updateVelocity(); + bool updateNodes() { int numNodes = 0; @@ -175,6 +131,7 @@ public: if (numNodes != m_numNodes) { m_numNodes = numNodes; + m_backupVelocity.resize(numNodes); return true; } return false; @@ -200,15 +157,11 @@ public: softBody->defaultCollisionHandler(collisionObjectWrap); } - virtual void processCollision(btSoftBody *, btSoftBody *) { - // TODO + virtual void processCollision(btSoftBody * softBody, btSoftBody * otherSoftBody) { + softBody->defaultCollisionHandler(otherSoftBody); } - virtual void setWorld(btDeformableRigidDynamicsWorld* world) - { - m_world = world; - m_objective.setWorld(world); - } + virtual void setWorld(btDeformableRigidDynamicsWorld* world); }; #endif /* btDeformableBodySolver_h */ diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 82b24ccb8..0bbb2e995 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -9,6 +9,20 @@ #include "btDeformableRigidDynamicsWorld.h" #include "btDeformableBodySolver.h" +btDeformableBodySolver::btDeformableBodySolver() +: m_numNodes(0) +, m_solveIterations(1) +, m_impulseIterations(1) +, m_world(nullptr) +{ + m_objective = new btBackwardEulerObjective(m_softBodySet, m_backupVelocity); +} + +btDeformableBodySolver::~btDeformableBodySolver() +{ + delete m_objective; +} + void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { // Let the solver grab the soft bodies and if necessary optimize for it @@ -50,9 +64,6 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS (*m_internalTickCallback)(this, timeStep); } - -// btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep); - // incorporate gravity into velocity and clear force for (int i = 0; i < m_nonStaticRigidBodies.size(); ++i) { @@ -64,7 +75,6 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS ///solve deformable bodies constraints solveDeformableBodiesConstraints(timeStep); -// predictUnconstraintMotion(timeStep); //integrate transforms btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::integrateTransforms(timeStep); @@ -76,6 +86,7 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS ///update soft bodies m_deformableBodySolver->updateSoftBodies(); + clearForces(); // End solver-wise simulation step // /////////////////////////////// } @@ -85,3 +96,23 @@ void btDeformableRigidDynamicsWorld::solveDeformableBodiesConstraints(btScalar t m_deformableBodySolver->solveConstraints(timeStep); } +void btDeformableRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask) +{ + getSoftDynamicsWorld()->getSoftBodyArray().push_back(body); + + // Set the soft body solver that will deal with this body + // to be the world's solver + body->setSoftBodySolver(m_deformableBodySolver); + + btCollisionWorld::addCollisionObject(body, + collisionFilterGroup, + collisionFilterMask); +} + +void btDeformableRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +{ + btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); + m_deformableBodySolver->predictMotion(float(timeStep)); +} + + diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 98dc4602c..11ad969a2 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -62,27 +62,12 @@ public: return BT_DEFORMABLE_RIGID_DYNAMICS_WORLD; } - virtual void predictUnconstraintMotion(btScalar timeStep) - { - btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); - m_deformableBodySolver->predictMotion(float(timeStep)); - } + virtual void predictUnconstraintMotion(btScalar timeStep); // virtual void internalStepSingleStepSimulation(btScalar timeStep); // virtual void solveDeformableBodiesConstraints(btScalar timeStep); - virtual void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter) - { - getSoftDynamicsWorld()->getSoftBodyArray().push_back(body); - - // Set the soft body solver that will deal with this body - // to be the world's solver - body->setSoftBodySolver(m_deformableBodySolver); - - btCollisionWorld::addCollisionObject(body, - collisionFilterGroup, - collisionFilterMask); - } + virtual void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter); }; #endif //BT_DEFORMABLE_RIGID_DYNAMICS_WORLD_H diff --git a/src/BulletSoftBody/btMassSpring.h b/src/BulletSoftBody/btMassSpring.h index ffe21c801..9fd3c405a 100644 --- a/src/BulletSoftBody/btMassSpring.h +++ b/src/BulletSoftBody/btMassSpring.h @@ -37,7 +37,12 @@ public: size_t id2 = m_indices[node2]; // elastic force + + // fully implicit btVector3 dir = (node2->m_x - node1->m_x); + + // explicit elastic force +// btVector3 dir = (node2->m_q - node1->m_q); btVector3 dir_normalized = dir.normalized(); btVector3 scaled_force = scale * kLST * (dir - dir_normalized * r); force[id1] += scaled_force; @@ -89,7 +94,7 @@ public: const auto& link = psb->m_links[j]; const auto node1 = link.m_n[0]; const auto node2 = link.m_n[1]; - btScalar k_damp = psb->m_dampingCoefficient; // TODO: FIX THIS HACK and set k_damp properly + btScalar k_damp = psb->m_dampingCoefficient; size_t id1 = m_indices[node1]; size_t id2 = m_indices[node2]; btVector3 local_scaled_df = scale * k_damp * (dv[id2] - dv[id1]); diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 7efe514f3..41911b2bc 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -880,7 +880,7 @@ struct btSoftColliders const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0); const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; - const btVector3 ra = n.m_x - wtr.getOrigin(); + const btVector3 ra = n.m_q - wtr.getOrigin(); const btVector3 va = m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra) * psb->m_sst.sdt : btVector3(0, 0, 0); const btVector3 vb = n.m_x - n.m_q; const btVector3 vr = vb - va; From c4e316f005f98ec8007a9278b4af93662a0631c7 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Tue, 9 Jul 2019 15:27:17 -0700 Subject: [PATCH 06/47] btDeformableRigidWorld now inherits from btMultiBodyDynamicsWorld instead of btSoftRigidDynamicsWorld --- src/BulletDynamics/Dynamics/btDynamicsWorld.h | 2 +- .../Featherstone/btMultiBodyDynamicsWorld.h | 5 +- src/BulletSoftBody/btContactProjection.cpp | 2 +- src/BulletSoftBody/btDeformableBodySolver.cpp | 14 ++++ .../btDeformableRigidDynamicsWorld.cpp | 34 +++------- .../btDeformableRigidDynamicsWorld.h | 67 ++++++++++++++++--- 6 files changed, 86 insertions(+), 38 deletions(-) diff --git a/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDynamicsWorld.h index 10853b761..3c55234a8 100644 --- a/src/BulletDynamics/Dynamics/btDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -35,7 +35,7 @@ enum btDynamicsWorldType BT_SOFT_RIGID_DYNAMICS_WORLD = 4, BT_GPU_DYNAMICS_WORLD = 5, BT_SOFT_MULTIBODY_DYNAMICS_WORLD = 6, - BT_DEFORMABLE_RIGID_DYNAMICS_WORLD = 7 + BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD = 7 }; ///The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc. diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h index e36c2f7aa..23641a37b 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h @@ -47,7 +47,7 @@ protected: virtual void calculateSimulationIslands(); virtual void updateActivationState(btScalar timeStep); - virtual void solveConstraints(btContactSolverInfo& solverInfo); + virtual void serializeMultiBodies(btSerializer* serializer); @@ -55,7 +55,8 @@ public: btMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration); virtual ~btMultiBodyDynamicsWorld(); - + + virtual void solveConstraints(btContactSolverInfo& solverInfo); virtual void addMultiBody(btMultiBody* body, int group = btBroadphaseProxy::DefaultFilter, int mask = btBroadphaseProxy::AllFilter); virtual void removeMultiBody(btMultiBody* body); diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 4db3e019e..c7a947fbe 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -10,7 +10,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocity) { ///solve rigid body constraints - m_world->btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::solveConstraints(m_world->getSolverInfo()); + m_world->btMultiBodyDynamicsWorld::solveConstraints(m_world->getSolverInfo()); // loop through contacts to create contact constraints for (int i = 0; i < m_softBodies.size(); ++i) diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index d3d448db0..9f94e9f6b 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -8,6 +8,20 @@ #include #include "btDeformableBodySolver.h" +btDeformableBodySolver::btDeformableBodySolver() +: m_numNodes(0) +, m_solveIterations(1) +, m_impulseIterations(1) +, m_world(nullptr) +{ + m_objective = new btBackwardEulerObjective(m_softBodySet, m_backupVelocity); +} + +btDeformableBodySolver::~btDeformableBodySolver() +{ + delete m_objective; +} + void btDeformableBodySolver::postStabilize() { for (int i = 0; i < m_softBodySet.size(); ++i) diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 0bbb2e995..ded4762e0 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -9,24 +9,11 @@ #include "btDeformableRigidDynamicsWorld.h" #include "btDeformableBodySolver.h" -btDeformableBodySolver::btDeformableBodySolver() -: m_numNodes(0) -, m_solveIterations(1) -, m_impulseIterations(1) -, m_world(nullptr) -{ - m_objective = new btBackwardEulerObjective(m_softBodySet, m_backupVelocity); -} - -btDeformableBodySolver::~btDeformableBodySolver() -{ - delete m_objective; -} void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { // Let the solver grab the soft bodies and if necessary optimize for it - m_deformableBodySolver->optimize(getSoftDynamicsWorld()->getSoftBodyArray()); + m_deformableBodySolver->optimize(m_softBodies); if (!m_deformableBodySolver->checkInitialized()) { @@ -42,22 +29,21 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS ///apply gravity, predict motion predictUnconstraintMotion(timeStep); - - btDispatcherInfo& dispatchInfo = btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::getDispatchInfo(); + btDispatcherInfo& dispatchInfo = btMultiBodyDynamicsWorld::getDispatchInfo(); dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_stepCount = 0; - dispatchInfo.m_debugDraw = btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::getDebugDrawer(); + dispatchInfo.m_debugDraw = btMultiBodyDynamicsWorld::getDebugDrawer(); // only used in CCD // createPredictiveContacts(timeStep); ///perform collision detection - btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::performDiscreteCollisionDetection(); + btMultiBodyDynamicsWorld::performDiscreteCollisionDetection(); - btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::calculateSimulationIslands(); + btMultiBodyDynamicsWorld::calculateSimulationIslands(); - btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::getSolverInfo().m_timeStep = timeStep; + btMultiBodyDynamicsWorld::getSolverInfo().m_timeStep = timeStep; if (0 != m_internalTickCallback) { @@ -76,12 +62,12 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS solveDeformableBodiesConstraints(timeStep); //integrate transforms - btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::integrateTransforms(timeStep); + btMultiBodyDynamicsWorld::integrateTransforms(timeStep); ///update vehicle simulation - btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::updateActions(timeStep); + btMultiBodyDynamicsWorld::updateActions(timeStep); - btSoftRigidDynamicsWorld::btDiscreteDynamicsWorld::updateActivationState(timeStep); + btMultiBodyDynamicsWorld::updateActivationState(timeStep); ///update soft bodies m_deformableBodySolver->updateSoftBodies(); @@ -98,7 +84,7 @@ void btDeformableRigidDynamicsWorld::solveDeformableBodiesConstraints(btScalar t void btDeformableRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask) { - getSoftDynamicsWorld()->getSoftBodyArray().push_back(body); + m_softBodies.push_back(body); // Set the soft body solver that will deal with this body // to be the world's solver diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 11ad969a2..ca1fff885 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -16,50 +16,76 @@ #ifndef BT_DEFORMABLE_RIGID_DYNAMICS_WORLD_H #define BT_DEFORMABLE_RIGID_DYNAMICS_WORLD_H -#include "btSoftRigidDynamicsWorld.h" +#include "btSoftMultiBodyDynamicsWorld.h" #include "btLagrangianForce.h" #include "btMassSpring.h" #include "btDeformableBodySolver.h" +#include "btSoftBodyHelpers.h" + typedef btAlignedObjectArray btSoftBodyArray; class btDeformableBodySolver; class btLagrangianForce; +typedef btAlignedObjectArray btSoftBodyArray; -class btDeformableRigidDynamicsWorld : public btSoftRigidDynamicsWorld +class btDeformableRigidDynamicsWorld : public btMultiBodyDynamicsWorld { using TVStack = btAlignedObjectArray; ///Solver classes that encapsulate multiple deformable bodies for solving btDeformableBodySolver* m_deformableBodySolver; - + btSoftBodyArray m_softBodies; + int m_drawFlags; + bool m_drawNodeTree; + bool m_drawFaceTree; + bool m_drawClusterTree; + btSoftBodyWorldInfo m_sbi; + bool m_ownsSolver; + protected: virtual void internalSingleStepSimulation(btScalar timeStep); void solveDeformableBodiesConstraints(btScalar timeStep); public: - btDeformableRigidDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btDeformableBodySolver* deformableBodySolver = 0) - : btSoftRigidDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration, 0), + btDeformableRigidDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btDeformableBodySolver* deformableBodySolver = 0) + : btMultiBodyDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration), m_deformableBodySolver(deformableBodySolver) { + m_drawFlags = fDrawFlags::Std; + m_drawNodeTree = true; + m_drawFaceTree = false; + m_drawClusterTree = false; + m_sbi.m_broadphase = pairCache; + m_sbi.m_dispatcher = dispatcher; + m_sbi.m_sparsesdf.Initialize(); + m_sbi.m_sparsesdf.Reset(); + + m_sbi.air_density = (btScalar)1.2; + m_sbi.water_density = 0; + m_sbi.water_offset = 0; + m_sbi.water_normal = btVector3(0, 0, 0); + m_sbi.m_gravity.setValue(0, -10, 0); + + m_sbi.m_sparsesdf.Initialize(); } virtual ~btDeformableRigidDynamicsWorld() { } - virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld() + virtual btMultiBodyDynamicsWorld* getMultiBodyDynamicsWorld() { - return (btSoftRigidDynamicsWorld*)(this); + return (btMultiBodyDynamicsWorld*)(this); } - virtual const btSoftRigidDynamicsWorld* getSoftDynamicsWorld() const + virtual const btMultiBodyDynamicsWorld* getMultiBodyDynamicsWorld() const { - return (const btSoftRigidDynamicsWorld*)(this); + return (const btMultiBodyDynamicsWorld*)(this); } virtual btDynamicsWorldType getWorldType() const { - return BT_DEFORMABLE_RIGID_DYNAMICS_WORLD; + return BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD; } virtual void predictUnconstraintMotion(btScalar timeStep); @@ -68,6 +94,27 @@ public: // virtual void solveDeformableBodiesConstraints(btScalar timeStep); virtual void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter); + + btSoftBodyArray& getSoftBodyArray() + { + return m_softBodies; + } + + const btSoftBodyArray& getSoftBodyArray() const + { + return m_softBodies; + } + + btSoftBodyWorldInfo& getWorldInfo() + { + return m_sbi; + } + const btSoftBodyWorldInfo& getWorldInfo() const + { + return m_sbi; + } + int getDrawFlags() const { return (m_drawFlags); } + void setDrawFlags(int f) { m_drawFlags = f; } }; #endif //BT_DEFORMABLE_RIGID_DYNAMICS_WORLD_H From 77d670ae416d77d078e09099e57f743afd239acb Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Wed, 10 Jul 2019 16:08:46 -0700 Subject: [PATCH 07/47] separate external force solve from constraint solve and eliminate damping in external force solve --- .../Featherstone/btMultiBodyDynamicsWorld.cpp | 575 +++++++++--------- .../Featherstone/btMultiBodyDynamicsWorld.h | 2 + 2 files changed, 295 insertions(+), 282 deletions(-) diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index 1131e5378..718106e77 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -421,288 +421,7 @@ void btMultiBodyDynamicsWorld::forwardKinematics() } void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { - forwardKinematics(); - - BT_PROFILE("solveConstraints"); - - clearMultiBodyConstraintForces(); - - m_sortedConstraints.resize(m_constraints.size()); - int i; - for (i = 0; i < getNumConstraints(); i++) - { - m_sortedConstraints[i] = m_constraints[i]; - } - m_sortedConstraints.quickSort(btSortConstraintOnIslandPredicate2()); - btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0; - - m_sortedMultiBodyConstraints.resize(m_multiBodyConstraints.size()); - for (i = 0; i < m_multiBodyConstraints.size(); i++) - { - m_sortedMultiBodyConstraints[i] = m_multiBodyConstraints[i]; - } - m_sortedMultiBodyConstraints.quickSort(btSortMultiBodyConstraintOnIslandPredicate()); - - btMultiBodyConstraint** sortedMultiBodyConstraints = m_sortedMultiBodyConstraints.size() ? &m_sortedMultiBodyConstraints[0] : 0; - - m_solverMultiBodyIslandCallback->setup(&solverInfo, constraintsPtr, m_sortedConstraints.size(), sortedMultiBodyConstraints, m_sortedMultiBodyConstraints.size(), getDebugDrawer()); - m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); - -#ifndef BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY - { - BT_PROFILE("btMultiBody addForce"); - for (int i = 0; i < this->m_multiBodies.size(); i++) - { - btMultiBody* bod = m_multiBodies[i]; - - bool isSleeping = false; - - if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) - { - isSleeping = true; - } - for (int b = 0; b < bod->getNumLinks(); b++) - { - if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) - isSleeping = true; - } - - if (!isSleeping) - { - //useless? they get resized in stepVelocities once again (AND DIFFERENTLY) - m_scratch_r.resize(bod->getNumLinks() + 1); //multidof? ("Y"s use it and it is used to store qdd) - m_scratch_v.resize(bod->getNumLinks() + 1); - m_scratch_m.resize(bod->getNumLinks() + 1); - - bod->addBaseForce(m_gravity * bod->getBaseMass()); - - for (int j = 0; j < bod->getNumLinks(); ++j) - { - bod->addLinkForce(j, m_gravity * bod->getLinkMass(j)); - } - } //if (!isSleeping) - } - } -#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY - - { - BT_PROFILE("btMultiBody stepVelocities"); - for (int i = 0; i < this->m_multiBodies.size(); i++) - { - btMultiBody* bod = m_multiBodies[i]; - - bool isSleeping = false; - - if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) - { - isSleeping = true; - } - for (int b = 0; b < bod->getNumLinks(); b++) - { - if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) - isSleeping = true; - } - - if (!isSleeping) - { - //useless? they get resized in stepVelocities once again (AND DIFFERENTLY) - m_scratch_r.resize(bod->getNumLinks() + 1); //multidof? ("Y"s use it and it is used to store qdd) - m_scratch_v.resize(bod->getNumLinks() + 1); - m_scratch_m.resize(bod->getNumLinks() + 1); - bool doNotUpdatePos = false; - bool isConstraintPass = false; - { - if (!bod->isUsingRK4Integration()) - { - bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, - m_scratch_r, m_scratch_v, m_scratch_m,isConstraintPass, - getSolverInfo().m_jointFeedbackInWorldSpace, - getSolverInfo().m_jointFeedbackInJointFrame); - } - else - { - // - int numDofs = bod->getNumDofs() + 6; - int numPosVars = bod->getNumPosVars() + 7; - btAlignedObjectArray scratch_r2; - scratch_r2.resize(2 * numPosVars + 8 * numDofs); - //convenience - btScalar* pMem = &scratch_r2[0]; - btScalar* scratch_q0 = pMem; - pMem += numPosVars; - btScalar* scratch_qx = pMem; - pMem += numPosVars; - btScalar* scratch_qd0 = pMem; - pMem += numDofs; - btScalar* scratch_qd1 = pMem; - pMem += numDofs; - btScalar* scratch_qd2 = pMem; - pMem += numDofs; - btScalar* scratch_qd3 = pMem; - pMem += numDofs; - btScalar* scratch_qdd0 = pMem; - pMem += numDofs; - btScalar* scratch_qdd1 = pMem; - pMem += numDofs; - btScalar* scratch_qdd2 = pMem; - pMem += numDofs; - btScalar* scratch_qdd3 = pMem; - pMem += numDofs; - btAssert((pMem - (2 * numPosVars + 8 * numDofs)) == &scratch_r2[0]); - - ///// - //copy q0 to scratch_q0 and qd0 to scratch_qd0 - scratch_q0[0] = bod->getWorldToBaseRot().x(); - scratch_q0[1] = bod->getWorldToBaseRot().y(); - scratch_q0[2] = bod->getWorldToBaseRot().z(); - scratch_q0[3] = bod->getWorldToBaseRot().w(); - scratch_q0[4] = bod->getBasePos().x(); - scratch_q0[5] = bod->getBasePos().y(); - scratch_q0[6] = bod->getBasePos().z(); - // - for (int link = 0; link < bod->getNumLinks(); ++link) - { - for (int dof = 0; dof < bod->getLink(link).m_posVarCount; ++dof) - scratch_q0[7 + bod->getLink(link).m_cfgOffset + dof] = bod->getLink(link).m_jointPos[dof]; - } - // - for (int dof = 0; dof < numDofs; ++dof) - scratch_qd0[dof] = bod->getVelocityVector()[dof]; - //// - struct - { - btMultiBody* bod; - btScalar *scratch_qx, *scratch_q0; - - void operator()() - { - for (int dof = 0; dof < bod->getNumPosVars() + 7; ++dof) - scratch_qx[dof] = scratch_q0[dof]; - } - } pResetQx = {bod, scratch_qx, scratch_q0}; - // - struct - { - void operator()(btScalar dt, const btScalar* pDer, const btScalar* pCurVal, btScalar* pVal, int size) - { - for (int i = 0; i < size; ++i) - pVal[i] = pCurVal[i] + dt * pDer[i]; - } - - } pEulerIntegrate; - // - struct - { - void operator()(btMultiBody* pBody, const btScalar* pData) - { - btScalar* pVel = const_cast(pBody->getVelocityVector()); - - for (int i = 0; i < pBody->getNumDofs() + 6; ++i) - pVel[i] = pData[i]; - } - } pCopyToVelocityVector; - // - struct - { - void operator()(const btScalar* pSrc, btScalar* pDst, int start, int size) - { - for (int i = 0; i < size; ++i) - pDst[i] = pSrc[start + i]; - } - } pCopy; - // - - btScalar h = solverInfo.m_timeStep; -#define output &m_scratch_r[bod->getNumDofs()] - //calc qdd0 from: q0 & qd0 - bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m, - isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, - getSolverInfo().m_jointFeedbackInJointFrame); - pCopy(output, scratch_qdd0, 0, numDofs); - //calc q1 = q0 + h/2 * qd0 - pResetQx(); - bod->stepPositionsMultiDof(btScalar(.5) * h, scratch_qx, scratch_qd0); - //calc qd1 = qd0 + h/2 * qdd0 - pEulerIntegrate(btScalar(.5) * h, scratch_qdd0, scratch_qd0, scratch_qd1, numDofs); - // - //calc qdd1 from: q1 & qd1 - pCopyToVelocityVector(bod, scratch_qd1); - bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m, - isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, - getSolverInfo().m_jointFeedbackInJointFrame); - pCopy(output, scratch_qdd1, 0, numDofs); - //calc q2 = q0 + h/2 * qd1 - pResetQx(); - bod->stepPositionsMultiDof(btScalar(.5) * h, scratch_qx, scratch_qd1); - //calc qd2 = qd0 + h/2 * qdd1 - pEulerIntegrate(btScalar(.5) * h, scratch_qdd1, scratch_qd0, scratch_qd2, numDofs); - // - //calc qdd2 from: q2 & qd2 - pCopyToVelocityVector(bod, scratch_qd2); - bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m, - isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, - getSolverInfo().m_jointFeedbackInJointFrame); - pCopy(output, scratch_qdd2, 0, numDofs); - //calc q3 = q0 + h * qd2 - pResetQx(); - bod->stepPositionsMultiDof(h, scratch_qx, scratch_qd2); - //calc qd3 = qd0 + h * qdd2 - pEulerIntegrate(h, scratch_qdd2, scratch_qd0, scratch_qd3, numDofs); - // - //calc qdd3 from: q3 & qd3 - pCopyToVelocityVector(bod, scratch_qd3); - bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m, - isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, - getSolverInfo().m_jointFeedbackInJointFrame); - pCopy(output, scratch_qdd3, 0, numDofs); - - // - //calc q = q0 + h/6(qd0 + 2*(qd1 + qd2) + qd3) - //calc qd = qd0 + h/6(qdd0 + 2*(qdd1 + qdd2) + qdd3) - btAlignedObjectArray delta_q; - delta_q.resize(numDofs); - btAlignedObjectArray delta_qd; - delta_qd.resize(numDofs); - for (int i = 0; i < numDofs; ++i) - { - delta_q[i] = h / btScalar(6.) * (scratch_qd0[i] + 2 * scratch_qd1[i] + 2 * scratch_qd2[i] + scratch_qd3[i]); - delta_qd[i] = h / btScalar(6.) * (scratch_qdd0[i] + 2 * scratch_qdd1[i] + 2 * scratch_qdd2[i] + scratch_qdd3[i]); - //delta_q[i] = h*scratch_qd0[i]; - //delta_qd[i] = h*scratch_qdd0[i]; - } - // - pCopyToVelocityVector(bod, scratch_qd0); - bod->applyDeltaVeeMultiDof(&delta_qd[0], 1); - // - if (!doNotUpdatePos) - { - btScalar* pRealBuf = const_cast(bod->getVelocityVector()); - pRealBuf += 6 + bod->getNumDofs() + bod->getNumDofs() * bod->getNumDofs(); - - for (int i = 0; i < numDofs; ++i) - pRealBuf[i] = delta_q[i]; - - //bod->stepPositionsMultiDof(1, 0, &delta_q[0]); - bod->setPosUpdated(true); - } - - //ugly hack which resets the cached data to t0 (needed for constraint solver) - { - for (int link = 0; link < bod->getNumLinks(); ++link) - bod->getLink(link).updateCacheMultiDof(); - bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0, m_scratch_r, m_scratch_v, m_scratch_m, - isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, - getSolverInfo().m_jointFeedbackInJointFrame); - } - } - } - -#ifndef BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY - bod->clearForcesAndTorques(); -#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY - } //if (!isSleeping) - } - } + solveExternalForces(solverInfo); /// solve all the constraints for this island m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_solverMultiBodyIslandCallback); @@ -760,6 +479,298 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) } } +void btMultiBodyDynamicsWorld::solveExternalForces(btContactSolverInfo& solverInfo) +{ + forwardKinematics(); + + BT_PROFILE("solveConstraints"); + + clearMultiBodyConstraintForces(); + + m_sortedConstraints.resize(m_constraints.size()); + int i; + for (i = 0; i < getNumConstraints(); i++) + { + m_sortedConstraints[i] = m_constraints[i]; + } + m_sortedConstraints.quickSort(btSortConstraintOnIslandPredicate2()); + btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0; + + m_sortedMultiBodyConstraints.resize(m_multiBodyConstraints.size()); + for (i = 0; i < m_multiBodyConstraints.size(); i++) + { + m_sortedMultiBodyConstraints[i] = m_multiBodyConstraints[i]; + } + m_sortedMultiBodyConstraints.quickSort(btSortMultiBodyConstraintOnIslandPredicate()); + + btMultiBodyConstraint** sortedMultiBodyConstraints = m_sortedMultiBodyConstraints.size() ? &m_sortedMultiBodyConstraints[0] : 0; + + m_solverMultiBodyIslandCallback->setup(&solverInfo, constraintsPtr, m_sortedConstraints.size(), sortedMultiBodyConstraints, m_sortedMultiBodyConstraints.size(), getDebugDrawer()); + m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); + +#ifndef BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY + { + BT_PROFILE("btMultiBody addForce"); + for (int i = 0; i < this->m_multiBodies.size(); i++) + { + btMultiBody* bod = m_multiBodies[i]; + + bool isSleeping = false; + + if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) + { + isSleeping = true; + } + for (int b = 0; b < bod->getNumLinks(); b++) + { + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) + isSleeping = true; + } + + if (!isSleeping) + { + //useless? they get resized in stepVelocities once again (AND DIFFERENTLY) + m_scratch_r.resize(bod->getNumLinks() + 1); //multidof? ("Y"s use it and it is used to store qdd) + m_scratch_v.resize(bod->getNumLinks() + 1); + m_scratch_m.resize(bod->getNumLinks() + 1); + + bod->addBaseForce(m_gravity * bod->getBaseMass()); + + for (int j = 0; j < bod->getNumLinks(); ++j) + { + bod->addLinkForce(j, m_gravity * bod->getLinkMass(j)); + } + } //if (!isSleeping) + } + } +#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY + + { + BT_PROFILE("btMultiBody stepVelocities"); + for (int i = 0; i < this->m_multiBodies.size(); i++) + { + btMultiBody* bod = m_multiBodies[i]; + + bool isSleeping = false; + + if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) + { + isSleeping = true; + } + for (int b = 0; b < bod->getNumLinks(); b++) + { + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) + isSleeping = true; + } + + if (!isSleeping) + { + //useless? they get resized in stepVelocities once again (AND DIFFERENTLY) + m_scratch_r.resize(bod->getNumLinks() + 1); //multidof? ("Y"s use it and it is used to store qdd) + m_scratch_v.resize(bod->getNumLinks() + 1); + m_scratch_m.resize(bod->getNumLinks() + 1); + bool doNotUpdatePos = false; + bool isConstraintPass = false; + { + if (!bod->isUsingRK4Integration()) + { + const btScalar linearDamp = bod->getLinearDamping(); +// const btScalar angularDamp = bod->getAngularDamping(); + bod->setLinearDamping(0); + bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, + m_scratch_r, m_scratch_v, m_scratch_m,isConstraintPass, + getSolverInfo().m_jointFeedbackInWorldSpace, + getSolverInfo().m_jointFeedbackInJointFrame); + bod->setLinearDamping(linearDamp); +// bod->setAngularDamping(angularDamp); + } + else + { + // + int numDofs = bod->getNumDofs() + 6; + int numPosVars = bod->getNumPosVars() + 7; + btAlignedObjectArray scratch_r2; + scratch_r2.resize(2 * numPosVars + 8 * numDofs); + //convenience + btScalar* pMem = &scratch_r2[0]; + btScalar* scratch_q0 = pMem; + pMem += numPosVars; + btScalar* scratch_qx = pMem; + pMem += numPosVars; + btScalar* scratch_qd0 = pMem; + pMem += numDofs; + btScalar* scratch_qd1 = pMem; + pMem += numDofs; + btScalar* scratch_qd2 = pMem; + pMem += numDofs; + btScalar* scratch_qd3 = pMem; + pMem += numDofs; + btScalar* scratch_qdd0 = pMem; + pMem += numDofs; + btScalar* scratch_qdd1 = pMem; + pMem += numDofs; + btScalar* scratch_qdd2 = pMem; + pMem += numDofs; + btScalar* scratch_qdd3 = pMem; + pMem += numDofs; + btAssert((pMem - (2 * numPosVars + 8 * numDofs)) == &scratch_r2[0]); + + ///// + //copy q0 to scratch_q0 and qd0 to scratch_qd0 + scratch_q0[0] = bod->getWorldToBaseRot().x(); + scratch_q0[1] = bod->getWorldToBaseRot().y(); + scratch_q0[2] = bod->getWorldToBaseRot().z(); + scratch_q0[3] = bod->getWorldToBaseRot().w(); + scratch_q0[4] = bod->getBasePos().x(); + scratch_q0[5] = bod->getBasePos().y(); + scratch_q0[6] = bod->getBasePos().z(); + // + for (int link = 0; link < bod->getNumLinks(); ++link) + { + for (int dof = 0; dof < bod->getLink(link).m_posVarCount; ++dof) + scratch_q0[7 + bod->getLink(link).m_cfgOffset + dof] = bod->getLink(link).m_jointPos[dof]; + } + // + for (int dof = 0; dof < numDofs; ++dof) + scratch_qd0[dof] = bod->getVelocityVector()[dof]; + //// + struct + { + btMultiBody* bod; + btScalar *scratch_qx, *scratch_q0; + + void operator()() + { + for (int dof = 0; dof < bod->getNumPosVars() + 7; ++dof) + scratch_qx[dof] = scratch_q0[dof]; + } + } pResetQx = {bod, scratch_qx, scratch_q0}; + // + struct + { + void operator()(btScalar dt, const btScalar* pDer, const btScalar* pCurVal, btScalar* pVal, int size) + { + for (int i = 0; i < size; ++i) + pVal[i] = pCurVal[i] + dt * pDer[i]; + } + + } pEulerIntegrate; + // + struct + { + void operator()(btMultiBody* pBody, const btScalar* pData) + { + btScalar* pVel = const_cast(pBody->getVelocityVector()); + + for (int i = 0; i < pBody->getNumDofs() + 6; ++i) + pVel[i] = pData[i]; + } + } pCopyToVelocityVector; + // + struct + { + void operator()(const btScalar* pSrc, btScalar* pDst, int start, int size) + { + for (int i = 0; i < size; ++i) + pDst[i] = pSrc[start + i]; + } + } pCopy; + // + + btScalar h = solverInfo.m_timeStep; +#define output &m_scratch_r[bod->getNumDofs()] + //calc qdd0 from: q0 & qd0 + bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m, + isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, + getSolverInfo().m_jointFeedbackInJointFrame); + pCopy(output, scratch_qdd0, 0, numDofs); + //calc q1 = q0 + h/2 * qd0 + pResetQx(); + bod->stepPositionsMultiDof(btScalar(.5) * h, scratch_qx, scratch_qd0); + //calc qd1 = qd0 + h/2 * qdd0 + pEulerIntegrate(btScalar(.5) * h, scratch_qdd0, scratch_qd0, scratch_qd1, numDofs); + // + //calc qdd1 from: q1 & qd1 + pCopyToVelocityVector(bod, scratch_qd1); + bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m, + isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, + getSolverInfo().m_jointFeedbackInJointFrame); + pCopy(output, scratch_qdd1, 0, numDofs); + //calc q2 = q0 + h/2 * qd1 + pResetQx(); + bod->stepPositionsMultiDof(btScalar(.5) * h, scratch_qx, scratch_qd1); + //calc qd2 = qd0 + h/2 * qdd1 + pEulerIntegrate(btScalar(.5) * h, scratch_qdd1, scratch_qd0, scratch_qd2, numDofs); + // + //calc qdd2 from: q2 & qd2 + pCopyToVelocityVector(bod, scratch_qd2); + bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m, + isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, + getSolverInfo().m_jointFeedbackInJointFrame); + pCopy(output, scratch_qdd2, 0, numDofs); + //calc q3 = q0 + h * qd2 + pResetQx(); + bod->stepPositionsMultiDof(h, scratch_qx, scratch_qd2); + //calc qd3 = qd0 + h * qdd2 + pEulerIntegrate(h, scratch_qdd2, scratch_qd0, scratch_qd3, numDofs); + // + //calc qdd3 from: q3 & qd3 + pCopyToVelocityVector(bod, scratch_qd3); + bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m, + isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, + getSolverInfo().m_jointFeedbackInJointFrame); + pCopy(output, scratch_qdd3, 0, numDofs); + + // + //calc q = q0 + h/6(qd0 + 2*(qd1 + qd2) + qd3) + //calc qd = qd0 + h/6(qdd0 + 2*(qdd1 + qdd2) + qdd3) + btAlignedObjectArray delta_q; + delta_q.resize(numDofs); + btAlignedObjectArray delta_qd; + delta_qd.resize(numDofs); + for (int i = 0; i < numDofs; ++i) + { + delta_q[i] = h / btScalar(6.) * (scratch_qd0[i] + 2 * scratch_qd1[i] + 2 * scratch_qd2[i] + scratch_qd3[i]); + delta_qd[i] = h / btScalar(6.) * (scratch_qdd0[i] + 2 * scratch_qdd1[i] + 2 * scratch_qdd2[i] + scratch_qdd3[i]); + //delta_q[i] = h*scratch_qd0[i]; + //delta_qd[i] = h*scratch_qdd0[i]; + } + // + pCopyToVelocityVector(bod, scratch_qd0); + bod->applyDeltaVeeMultiDof(&delta_qd[0], 1); + // + if (!doNotUpdatePos) + { + btScalar* pRealBuf = const_cast(bod->getVelocityVector()); + pRealBuf += 6 + bod->getNumDofs() + bod->getNumDofs() * bod->getNumDofs(); + + for (int i = 0; i < numDofs; ++i) + pRealBuf[i] = delta_q[i]; + + //bod->stepPositionsMultiDof(1, 0, &delta_q[0]); + bod->setPosUpdated(true); + } + + //ugly hack which resets the cached data to t0 (needed for constraint solver) + { + for (int link = 0; link < bod->getNumLinks(); ++link) + bod->getLink(link).updateCacheMultiDof(); + bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0, m_scratch_r, m_scratch_v, m_scratch_m, + isConstraintPass,getSolverInfo().m_jointFeedbackInWorldSpace, + getSolverInfo().m_jointFeedbackInJointFrame); + } + } + } + +#ifndef BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY + bod->clearForcesAndTorques(); +#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY + } //if (!isSleeping) + } + } +} + + void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) { btDiscreteDynamicsWorld::integrateTransforms(timeStep); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h index 23641a37b..019d1bd87 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h @@ -111,6 +111,8 @@ public: virtual void setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver); virtual void setConstraintSolver(btConstraintSolver* solver); virtual void getAnalyticsData(btAlignedObjectArray& m_islandAnalyticsData) const; + + virtual void solveExternalForces(btContactSolverInfo& solverInfo); }; #endif //BT_MULTIBODY_DYNAMICS_WORLD_H From b7e512a5f9e099c3aefaf5a5ffb79a37ababde29 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Wed, 10 Jul 2019 16:09:38 -0700 Subject: [PATCH 08/47] sync gravity with substeps --- .../btDeformableRigidDynamicsWorld.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index ded4762e0..5fdf01a18 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -50,13 +50,24 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS (*m_internalTickCallback)(this, timeStep); } - // incorporate gravity into velocity and clear force + // TODO: This is an ugly hack to get the desired gravity behavior. + // gravity is applied in stepSimulation and then cleared here and then applied here and then cleared here again + // so that 1) gravity is applied to velocity before constraint solve and 2) gravity is applied in each substep + // when there are multiple substeps + + clearForces(); + clearMultiBodyForces(); + btMultiBodyDynamicsWorld::applyGravity(); + // integrate rigid body gravity for (int i = 0; i < m_nonStaticRigidBodies.size(); ++i) { btRigidBody* rb = m_nonStaticRigidBodies[i]; rb->integrateVelocities(timeStep); } + // integrate multibody gravity + btMultiBodyDynamicsWorld::solveExternalForces(btMultiBodyDynamicsWorld::getSolverInfo()); clearForces(); + clearMultiBodyForces(); ///solve deformable bodies constraints solveDeformableBodiesConstraints(timeStep); From b28f1fdac3d38171d37d1f938df8a0dff3afd8af Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 11 Jul 2019 10:14:58 -0700 Subject: [PATCH 09/47] add support for more than one constraint for a single deformable node --- .../btBackwardEulerObjective.cpp | 4 +- src/BulletSoftBody/btCGProjection.h | 3 + src/BulletSoftBody/btContactProjection.cpp | 56 +++++++++++++++++++ src/BulletSoftBody/btContactProjection.h | 42 +++++++++++--- 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp index 22614c994..69f5cd6ac 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -8,7 +8,7 @@ #include "btBackwardEulerObjective.h" btBackwardEulerObjective::btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) -: cg(20) +: cg(50) , m_softBodies(softBodies) , precondition(DefaultPreconditioner()) , projection(m_softBodies, m_dt) @@ -66,7 +66,7 @@ void btBackwardEulerObjective::computeStep(TVStack& dv, const TVStack& residual, m_dt = dt; btScalar tolerance = std::numeric_limits::epsilon()* 16 * computeNorm(residual); cg.solve(*this, dv, residual, tolerance); - } +} void btBackwardEulerObjective::updateVelocity(const TVStack& dv) { diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 8648e99f8..ff1d6cbdd 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -23,6 +23,8 @@ public: std::unordered_map m_indices; TVArrayStack m_constrainedDirections; TArrayStack m_constrainedValues; + btAlignedObjectArray m_constrainedId; + const btScalar& m_dt; btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) @@ -56,6 +58,7 @@ public: m_constrainedDirections[i].clear(); m_constrainedValues[i].clear(); } + m_constrainedId.clear(); } void updateId() diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index c7a947fbe..c45cccf5d 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -114,6 +114,7 @@ void btContactProjection::setConstraintDirections() m_constrainedValues[counter].push_back(0); m_constrainedValues[counter].push_back(0); m_constrainedValues[counter].push_back(0); + m_constrainedId.push_back(counter); } ++counter; } @@ -180,10 +181,65 @@ void btContactProjection::setConstraintDirections() ++j; m_constrainedDirections[m_indices[c.m_node]].push_back(cti.m_normal); m_constrainedValues[m_indices[c.m_node]].resize(m_constrainedValues[m_indices[c.m_node]].size()+1); + m_constrainedId.push_back(m_indices[c.m_node]); continue; } } psb->m_rcontacts.removeAtIndex(j); } } + + // for particles with more than three constrained directions, prune constrained directions so that there are at most three constrained directions + counter = 0; + const int dim = 3; + for (int i = 0; i < m_softBodies.size(); ++i) + { + const btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + if (m_constrainedDirections[counter].size() > dim) + { + btAlignedObjectArray prunedConstraints; + // always keep the first constrained direction + prunedConstraints.push_back(m_constrainedDirections[counter][0]); + // find the direction most orthogonal to the first direction and keep it + size_t selected = 1; + btScalar min_dotProductAbs = std::abs(prunedConstraints[0].dot(m_constrainedDirections[counter][selected])); + for (int j = 2; j < m_constrainedDirections[counter].size(); ++j) + { + btScalar dotProductAbs =std::abs(prunedConstraints[0].dot(m_constrainedDirections[counter][j])); + if (dotProductAbs < min_dotProductAbs) + { + selected = j; + min_dotProductAbs = dotProductAbs; + } + } + if (std::abs(min_dotProductAbs-1) < SIMD_EPSILON) + { + m_constrainedDirections[counter++] = prunedConstraints; + continue; + } + prunedConstraints.push_back(m_constrainedDirections[counter][selected]); + + // find the direction most orthogonal to the previous two directions and keep it + size_t selected2 = (selected == 1) ? 2 : 1; + btVector3 normal = btCross(prunedConstraints[0], prunedConstraints[1]); + normal.normalize(); + btScalar max_dotProductAbs = std::abs(normal.dot(m_constrainedDirections[counter][selected2])); + for (int j = 3; j < m_constrainedDirections[counter].size(); ++j) + { + btScalar dotProductAbs = std::abs(normal.dot(m_constrainedDirections[counter][j])); + if (dotProductAbs > min_dotProductAbs) + { + selected2 = j; + max_dotProductAbs = dotProductAbs; + } + } + prunedConstraints.push_back(m_constrainedDirections[counter][selected2]); + m_constrainedDirections[counter] = prunedConstraints; + m_constrainedValues[counter].resize(dim); + } + ++counter; + } + } } diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index 5598ada0a..c0897e9bf 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -29,24 +29,52 @@ public: // apply the constraints virtual void operator()(TVStack& x) { - for (int i = 0; i < x.size(); ++i) + const int dim = 3; + for (int j = 0; j < m_constrainedId.size(); ++j) { - for (int j = 0; j < m_constrainedDirections[i].size(); ++j) + int i = m_constrainedId[j]; + btAssert(m_constrainedDirections[i].size() <= dim); + if (m_constrainedDirections[i].size() <= 1) { - x[i] -= x[i].dot(m_constrainedDirections[i][j]) * m_constrainedDirections[i][j]; + for (int j = 0; j < m_constrainedDirections[i].size(); ++j) + { + x[i] -= x[i].dot(m_constrainedDirections[i][j]) * m_constrainedDirections[i][j]; + } } + else if (m_constrainedDirections[i].size() == 2) + { + btVector3 free_dir = btCross(m_constrainedDirections[i][0], m_constrainedDirections[i][1]); + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; + } + else + x[i].setZero(); } } virtual void enforceConstraint(TVStack& x) { - for (int i = 0; i < x.size(); ++i) + const int dim = 3; + for (int j = 0; j < m_constrainedId.size(); ++j) { - for (int j = 0; j < m_constrainedDirections[i].size(); ++j) + int i = m_constrainedId[j]; + btAssert(m_constrainedDirections[i].size() <= dim); + if (m_constrainedDirections[i].size() <= 1) { - x[i] -= x[i].dot(m_constrainedDirections[i][j]) * m_constrainedDirections[i][j]; - x[i] += m_constrainedValues[i][j] * m_constrainedDirections[i][j]; + for (int j = 0; j < m_constrainedDirections[i].size(); ++j) + { + x[i] -= x[i].dot(m_constrainedDirections[i][j]) * m_constrainedDirections[i][j]; + x[i] += m_constrainedValues[i][j] * m_constrainedDirections[i][j]; + } } + else if (m_constrainedDirections[i].size() == 2) + { + btVector3 free_dir = btCross(m_constrainedDirections[i][0], m_constrainedDirections[i][1]); + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir + m_constrainedDirections[i][0] * m_constrainedValues[i][0] + m_constrainedDirections[i][1] * m_constrainedValues[i][1]; + } + else + x[i] = m_constrainedDirections[i][0] * m_constrainedValues[i][0] + m_constrainedDirections[i][1] * m_constrainedValues[i][1] + m_constrainedDirections[i][2] * m_constrainedValues[i][2]; } } From 4e5f4b9fe98ac7631f9ca4cce8a713e23f0cc892 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 11 Jul 2019 11:26:30 -0700 Subject: [PATCH 10/47] reformulate how constraints are managed in the projection class --- .../btBackwardEulerObjective.cpp | 34 ++-- src/BulletSoftBody/btCGProjection.h | 53 ++++-- src/BulletSoftBody/btContactProjection.cpp | 153 +++++++++--------- src/BulletSoftBody/btContactProjection.h | 45 +++--- src/BulletSoftBody/btDeformableBodySolver.cpp | 26 +-- 5 files changed, 173 insertions(+), 138 deletions(-) diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp index 69f5cd6ac..bdb781897 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -70,19 +70,27 @@ void btBackwardEulerObjective::computeStep(TVStack& dv, const TVStack& residual, void btBackwardEulerObjective::updateVelocity(const TVStack& dv) { - for (int i = 0; i < m_softBodies.size(); ++i) + // only the velocity of the constrained nodes needs to be updated during CG solve + for (auto it : projection.m_constraints) { - int counter = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - // only the velocity of the constrained nodes needs to be updated during CG solve - if (projection.m_constrainedDirections.size() > 0) - psb->m_nodes[j].m_v = m_backupVelocity[counter] + dv[counter]; - ++counter; - } - } + int i = projection.m_indices[it.first]; + it.first->m_v = m_backupVelocity[i] + dv[i]; } } + +// for (int i = 0; i < m_softBodies.size(); ++i) +// { +// int counter = 0; +// for (int i = 0; i < m_softBodies.size(); ++i) +// { +// btSoftBody* psb = m_softBodies[i]; +// for (int j = 0; j < psb->m_nodes.size(); ++j) +// { +// // only the velocity of the constrained nodes needs to be updated during CG solve +// if (projection.m_constraints[&(psb->m_nodes[j])].size() > 0) +// psb->m_nodes[j].m_v = m_backupVelocity[counter] + dv[counter]; +// ++counter; +// } +// } +// } + diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index ff1d6cbdd..a238e998b 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -11,6 +11,34 @@ #include class btDeformableRigidDynamicsWorld; + +struct Constraint +{ + const btSoftBody::RContact* m_contact; + const btVector3 m_direction; + btScalar m_value; + + Constraint(const btSoftBody::RContact& rcontact) + : m_contact(&rcontact) + , m_direction(rcontact.m_cti.m_normal) + , m_value(0) + { + } + + Constraint(const btVector3 dir) + : m_contact(nullptr) + , m_direction(dir) + , m_value(0) + {} + + Constraint() + : m_contact(nullptr) + { + + } + +}; + class btCGProjection { public: @@ -21,11 +49,11 @@ public: btAlignedObjectArray m_softBodies; btDeformableRigidDynamicsWorld* m_world; std::unordered_map m_indices; - TVArrayStack m_constrainedDirections; - TArrayStack m_constrainedValues; - btAlignedObjectArray m_constrainedId; - +// TVArrayStack m_constrainedDirections; +// TArrayStack m_constrainedValues; +// btAlignedObjectArray m_constrainedId; const btScalar& m_dt; + std::unordered_map > m_constraints; btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : m_softBodies(softBodies) @@ -51,14 +79,15 @@ public: updateId(); // resize and clear the old constraints - m_constrainedValues.resize(m_indices.size()); - m_constrainedDirections.resize(m_indices.size()); - for (int i = 0; i < m_constrainedDirections.size(); ++i) - { - m_constrainedDirections[i].clear(); - m_constrainedValues[i].clear(); - } - m_constrainedId.clear(); +// m_constrainedValues.resize(m_indices.size()); +// m_constrainedDirections.resize(m_indices.size()); +// for (int i = 0; i < m_constrainedDirections.size(); ++i) +// { +// m_constrainedDirections[i].clear(); +// m_constrainedValues[i].clear(); +// } +// m_constrainedId.clear(); + m_constraints.clear(); } void updateId() diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index c45cccf5d..3016a9e85 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -12,20 +12,21 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit ///solve rigid body constraints m_world->btMultiBodyDynamicsWorld::solveConstraints(m_world->getSolverInfo()); - // loop through contacts to create contact constraints - for (int i = 0; i < m_softBodies.size(); ++i) + // loop through constraints to set constrained values + for (auto it : m_constraints) { - btSoftBody* psb = m_softBodies[i]; - btMultiBodyJacobianData jacobianData; - for (int i = 0, ni = psb->m_rcontacts.size(); i < ni; ++i) + btAlignedObjectArray& constraints = it.second; + for (int i = 0; i < constraints.size(); ++i) { - const btSoftBody::RContact& c = psb->m_rcontacts[i]; - - // skip anchor points - if (c.m_node->m_im == 0) + Constraint& constraint = constraints[i]; + if (constraint.m_contact == nullptr) + { + // nothing needs to be done for dirichelet constraints continue; - - const btSoftBody::sCti& cti = c.m_cti; + } + const btSoftBody::RContact* c = constraint.m_contact; + const btSoftBody::sCti& cti = c->m_cti; + btMultiBodyJacobianData jacobianData; if (cti.m_colObj->hasContactResponse()) { btVector3 va(0, 0, 0); @@ -37,7 +38,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * m_dt : btVector3(0, 0, 0); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c->m_c1)) * m_dt : btVector3(0, 0, 0); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { @@ -49,7 +50,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); btScalar* jac = &jacobianData.m_jacobians[0]; - multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c->m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); @@ -62,26 +63,26 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit } } - const btVector3 vb = c.m_node->m_v * m_dt; + const btVector3 vb = c->m_node->m_v * m_dt; const btVector3 vr = vb - va; const btScalar dn = btDot(vr, cti.m_normal); if (1) // in the same CG solve, the set of constraits doesn't change -// if (dn <= SIMD_EPSILON) + // if (dn <= SIMD_EPSILON) { // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - const btVector3 impulse = c.m_c0 *(cti.m_normal * dn); + const btVector3 impulse = c->m_c0 *(cti.m_normal * dn); // TODO: only contact is considered here, add friction later // dv = new_impulse + accumulated velocity change in previous CG iterations // so we have the invariant node->m_v = backupVelocity + dv; - btVector3 dv = -impulse * c.m_c2/m_dt + c.m_node->m_v - backupVelocity[m_indices[c.m_node]]; + btVector3 dv = -impulse * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; btScalar dvn = dv.dot(cti.m_normal); - m_constrainedValues[m_indices[c.m_node]][0]=(dvn); + constraint.m_value = dvn; if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { if (rigidCol) - rigidCol->applyImpulse(impulse, c.m_c1); + rigidCol->applyImpulse(impulse, c->m_c1); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { @@ -97,24 +98,23 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit } } + void btContactProjection::setConstraintDirections() { // set Dirichlet constraint size_t counter = 0; for (int i = 0; i < m_softBodies.size(); ++i) { - const btSoftBody* psb = m_softBodies[i]; + btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { if (psb->m_nodes[j].m_im == 0) { - m_constrainedDirections[counter].push_back(btVector3(1,0,0)); - m_constrainedDirections[counter].push_back(btVector3(0,1,0)); - m_constrainedDirections[counter].push_back(btVector3(0,0,1)); - m_constrainedValues[counter].push_back(0); - m_constrainedValues[counter].push_back(0); - m_constrainedValues[counter].push_back(0); - m_constrainedId.push_back(counter); + btAlignedObjectArray c; + c.push_back(Constraint(btVector3(1,0,0))); + c.push_back(Constraint(btVector3(0,1,0))); + c.push_back(Constraint(btVector3(0,0,1))); + m_constraints[&(psb->m_nodes[j])] = c; } ++counter; } @@ -125,14 +125,12 @@ void btContactProjection::setConstraintDirections() btSoftBody* psb = m_softBodies[i]; btMultiBodyJacobianData jacobianData; - int j = 0; - while (j < psb->m_rcontacts.size()) + for (int j = 0; j < psb->m_rcontacts.size(); ++j) { const btSoftBody::RContact& c = psb->m_rcontacts[j]; // skip anchor points if (c.m_node->m_im == 0) { - psb->m_rcontacts.removeAtIndex(j); continue; } @@ -178,68 +176,69 @@ void btContactProjection::setConstraintDirections() const btScalar dn = btDot(vr, cti.m_normal); if (dn < SIMD_EPSILON) { - ++j; - m_constrainedDirections[m_indices[c.m_node]].push_back(cti.m_normal); - m_constrainedValues[m_indices[c.m_node]].resize(m_constrainedValues[m_indices[c.m_node]].size()+1); - m_constrainedId.push_back(m_indices[c.m_node]); + if (m_constraints.find(c.m_node) == m_constraints.end()) + { + btAlignedObjectArray constraints; + constraints.push_back(Constraint(c)); + m_constraints[c.m_node] = constraints; + } + else + { + m_constraints[c.m_node].push_back(Constraint(c)); + } continue; } } - psb->m_rcontacts.removeAtIndex(j); } } // for particles with more than three constrained directions, prune constrained directions so that there are at most three constrained directions counter = 0; const int dim = 3; - for (int i = 0; i < m_softBodies.size(); ++i) + for (auto it : m_constraints) { - const btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) + const btAlignedObjectArray& c = it.second; + if (c.size() > dim) { - if (m_constrainedDirections[counter].size() > dim) + btAlignedObjectArray prunedConstraints; + // always keep the first constrained direction + prunedConstraints.push_back(c[0]); + + // find the direction most orthogonal to the first direction and keep it + size_t selected = 1; + btScalar min_dotProductAbs = std::abs(prunedConstraints[0].m_direction.dot(c[selected].m_direction)); + for (int j = 2; j < c.size(); ++j) { - btAlignedObjectArray prunedConstraints; - // always keep the first constrained direction - prunedConstraints.push_back(m_constrainedDirections[counter][0]); - // find the direction most orthogonal to the first direction and keep it - size_t selected = 1; - btScalar min_dotProductAbs = std::abs(prunedConstraints[0].dot(m_constrainedDirections[counter][selected])); - for (int j = 2; j < m_constrainedDirections[counter].size(); ++j) + btScalar dotProductAbs =std::abs(prunedConstraints[0].m_direction.dot(c[j].m_direction)); + if (dotProductAbs < min_dotProductAbs) { - btScalar dotProductAbs =std::abs(prunedConstraints[0].dot(m_constrainedDirections[counter][j])); - if (dotProductAbs < min_dotProductAbs) - { - selected = j; - min_dotProductAbs = dotProductAbs; - } + selected = j; + min_dotProductAbs = dotProductAbs; } - if (std::abs(min_dotProductAbs-1) < SIMD_EPSILON) - { - m_constrainedDirections[counter++] = prunedConstraints; - continue; - } - prunedConstraints.push_back(m_constrainedDirections[counter][selected]); - - // find the direction most orthogonal to the previous two directions and keep it - size_t selected2 = (selected == 1) ? 2 : 1; - btVector3 normal = btCross(prunedConstraints[0], prunedConstraints[1]); - normal.normalize(); - btScalar max_dotProductAbs = std::abs(normal.dot(m_constrainedDirections[counter][selected2])); - for (int j = 3; j < m_constrainedDirections[counter].size(); ++j) - { - btScalar dotProductAbs = std::abs(normal.dot(m_constrainedDirections[counter][j])); - if (dotProductAbs > min_dotProductAbs) - { - selected2 = j; - max_dotProductAbs = dotProductAbs; - } - } - prunedConstraints.push_back(m_constrainedDirections[counter][selected2]); - m_constrainedDirections[counter] = prunedConstraints; - m_constrainedValues[counter].resize(dim); } - ++counter; + if (std::abs(min_dotProductAbs-1) < SIMD_EPSILON) + { + it.second = prunedConstraints; + continue; + } + prunedConstraints.push_back(c[selected]); + + // find the direction most orthogonal to the previous two directions and keep it + size_t selected2 = (selected == 1) ? 2 : 1; + btVector3 normal = btCross(prunedConstraints[0].m_direction, prunedConstraints[1].m_direction); + normal.normalize(); + btScalar max_dotProductAbs = std::abs(normal.dot(c[selected2].m_direction)); + for (int j = 3; j < c.size(); ++j) + { + btScalar dotProductAbs = std::abs(normal.dot(c[j].m_direction)); + if (dotProductAbs > min_dotProductAbs) + { + selected2 = j; + max_dotProductAbs = dotProductAbs; + } + } + prunedConstraints.push_back(c[selected2]); + it.second = prunedConstraints; } } } diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index c0897e9bf..a497c933c 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -30,20 +30,19 @@ public: virtual void operator()(TVStack& x) { const int dim = 3; - for (int j = 0; j < m_constrainedId.size(); ++j) + for (auto it : m_constraints) { - int i = m_constrainedId[j]; - btAssert(m_constrainedDirections[i].size() <= dim); - if (m_constrainedDirections[i].size() <= 1) + const btAlignedObjectArray& constraints = it.second; + size_t i = m_indices[it.first]; + btAssert(constraints.size() <= dim); + btAssert(constraints.size() > 0); + if (constraints.size() == 1) { - for (int j = 0; j < m_constrainedDirections[i].size(); ++j) - { - x[i] -= x[i].dot(m_constrainedDirections[i][j]) * m_constrainedDirections[i][j]; - } + x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; } - else if (m_constrainedDirections[i].size() == 2) + else if (constraints.size() == 2) { - btVector3 free_dir = btCross(m_constrainedDirections[i][0], m_constrainedDirections[i][1]); + btVector3 free_dir = btCross(constraints[0].m_direction, constraints[1].m_direction); free_dir.normalize(); x[i] = x[i].dot(free_dir) * free_dir; } @@ -51,30 +50,30 @@ public: x[i].setZero(); } } + virtual void enforceConstraint(TVStack& x) { const int dim = 3; - for (int j = 0; j < m_constrainedId.size(); ++j) + for (auto it : m_constraints) { - int i = m_constrainedId[j]; - btAssert(m_constrainedDirections[i].size() <= dim); - if (m_constrainedDirections[i].size() <= 1) + const btAlignedObjectArray& constraints = it.second; + size_t i = m_indices[it.first]; + btAssert(constraints.size() <= dim); + btAssert(constraints.size() > 0); + if (constraints.size() == 1) { - for (int j = 0; j < m_constrainedDirections[i].size(); ++j) - { - x[i] -= x[i].dot(m_constrainedDirections[i][j]) * m_constrainedDirections[i][j]; - x[i] += m_constrainedValues[i][j] * m_constrainedDirections[i][j]; - } + x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; + x[i] += constraints[0].m_value * constraints[0].m_direction; } - else if (m_constrainedDirections[i].size() == 2) + else if (constraints.size() == 2) { - btVector3 free_dir = btCross(m_constrainedDirections[i][0], m_constrainedDirections[i][1]); + btVector3 free_dir = btCross(constraints[0].m_direction, constraints[1].m_direction); free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir + m_constrainedDirections[i][0] * m_constrainedValues[i][0] + m_constrainedDirections[i][1] * m_constrainedValues[i][1]; + x[i] = x[i].dot(free_dir) * free_dir + constraints[0].m_direction * constraints[0].m_value + constraints[1].m_direction * constraints[1].m_value; } else - x[i] = m_constrainedDirections[i][0] * m_constrainedValues[i][0] + m_constrainedDirections[i][1] * m_constrainedValues[i][1] + m_constrainedDirections[i][2] * m_constrainedValues[i][2]; + x[i] = constraints[0].m_value * constraints[0].m_direction + constraints[1].m_value * constraints[1].m_direction + constraints[2].m_value * constraints[2].m_direction; } } diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index 9f94e9f6b..b457a262f 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -89,20 +89,20 @@ void btDeformableBodySolver::postStabilize() c.m_node->m_x -= dp * cti.m_normal * c.m_c4; //// - // if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - // { - // if (rigidCol) - // rigidCol->applyImpulse(impulse, c.m_c1); - // } +// if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) +// { +// if (rigidCol) +// rigidCol->applyImpulse(impulse, c.m_c1); +// } +// else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) +// { +// if (multibodyLinkCol) +// { +// double multiplier = 0.5; +// multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); +// } +// } } - // else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - // { - // if (multibodyLinkCol) - // { - // double multiplier = 0.5; - // multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); - // } - // } } } } From 696c96f392f41ee41045d345082032d6bfcebcd8 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 12 Jul 2019 10:03:38 -0700 Subject: [PATCH 11/47] bug fix in projection; start friction --- .../btBackwardEulerObjective.cpp | 2 +- src/BulletSoftBody/btCGProjection.h | 29 +++++----- src/BulletSoftBody/btContactProjection.cpp | 56 +++++++++++++++---- src/BulletSoftBody/btContactProjection.h | 14 ++++- src/BulletSoftBody/btDeformableBodySolver.cpp | 1 + src/BulletSoftBody/btSoftBodyInternals.h | 3 +- 6 files changed, 75 insertions(+), 30 deletions(-) diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp index bdb781897..8801e68df 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -8,7 +8,7 @@ #include "btBackwardEulerObjective.h" btBackwardEulerObjective::btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) -: cg(50) +: cg(20) , m_softBodies(softBodies) , precondition(DefaultPreconditioner()) , projection(m_softBodies, m_dt) diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index a238e998b..6c104ef2f 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -15,7 +15,7 @@ class btDeformableRigidDynamicsWorld; struct Constraint { const btSoftBody::RContact* m_contact; - const btVector3 m_direction; + btVector3 m_direction; btScalar m_value; Constraint(const btSoftBody::RContact& rcontact) @@ -36,7 +36,17 @@ struct Constraint { } - +}; + +struct Friction +{ + btVector3 m_dv; + btVector3 m_direction; + Friction() + { + m_dv.setZero(); + m_direction.setZero(); + } }; class btCGProjection @@ -49,11 +59,9 @@ public: btAlignedObjectArray m_softBodies; btDeformableRigidDynamicsWorld* m_world; std::unordered_map m_indices; -// TVArrayStack m_constrainedDirections; -// TArrayStack m_constrainedValues; -// btAlignedObjectArray m_constrainedId; const btScalar& m_dt; std::unordered_map > m_constraints; + std::unordered_map m_frictions; btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : m_softBodies(softBodies) @@ -77,17 +85,8 @@ public: { if (nodeUpdated) updateId(); - - // resize and clear the old constraints -// m_constrainedValues.resize(m_indices.size()); -// m_constrainedDirections.resize(m_indices.size()); -// for (int i = 0; i < m_constrainedDirections.size(); ++i) -// { -// m_constrainedDirections[i].clear(); -// m_constrainedValues[i].clear(); -// } -// m_constrainedId.clear(); m_constraints.clear(); + m_frictions.clear(); } void updateId() diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 3016a9e85..b90c749f3 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -7,14 +7,16 @@ #include "btContactProjection.h" #include "btDeformableRigidDynamicsWorld.h" +#include void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocity) { ///solve rigid body constraints m_world->btMultiBodyDynamicsWorld::solveConstraints(m_world->getSolverInfo()); // loop through constraints to set constrained values - for (auto it : m_constraints) + for (auto& it : m_constraints) { + Friction& friction = m_frictions[it.first]; btAlignedObjectArray& constraints = it.second; for (int i = 0; i < constraints.size(); ++i) { @@ -66,11 +68,27 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit const btVector3 vb = c->m_node->m_v * m_dt; const btVector3 vr = vb - va; const btScalar dn = btDot(vr, cti.m_normal); - if (1) // in the same CG solve, the set of constraits doesn't change - // if (dn <= SIMD_EPSILON) + btVector3 impulse = c->m_c0 * vr; + const btVector3 impulse_normal = c->m_c0 *(cti.m_normal * dn); + btVector3 impulse_tangent = impulse - impulse_normal; + + if (dn < 0 && impulse_tangent.norm() > SIMD_EPSILON) + { + btScalar impulse_tangent_magnitude = std::min(impulse_normal.norm()*c->m_c3, impulse_tangent.norm()); + + impulse_tangent_magnitude = 0; + + const btVector3 tangent_dir = impulse_tangent.normalized(); + impulse_tangent = impulse_tangent_magnitude * tangent_dir; + friction.m_direction = impulse_tangent; + friction.m_dv = -impulse_tangent * c->m_c2/m_dt + (c->m_node->m_v - backupVelocity[m_indices[c->m_node]]).dot(tangent_dir)*tangent_dir; + } + impulse = impulse_normal + impulse_tangent; +// if (1) // in the same CG solve, the set of constraits doesn't change + if (dn <= SIMD_EPSILON) { // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - const btVector3 impulse = c->m_c0 *(cti.m_normal * dn); + // TODO: only contact is considered here, add friction later // dv = new_impulse + accumulated velocity change in previous CG iterations @@ -82,7 +100,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { if (rigidCol) - rigidCol->applyImpulse(impulse, c->m_c1); + rigidCol->applyImpulse(impulse_normal, c->m_c1); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { @@ -102,7 +120,6 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit void btContactProjection::setConstraintDirections() { // set Dirichlet constraint - size_t counter = 0; for (int i = 0; i < m_softBodies.size(); ++i) { btSoftBody* psb = m_softBodies[i]; @@ -116,7 +133,6 @@ void btContactProjection::setConstraintDirections() c.push_back(Constraint(btVector3(0,0,1))); m_constraints[&(psb->m_nodes[j])] = c; } - ++counter; } } @@ -181,6 +197,7 @@ void btContactProjection::setConstraintDirections() btAlignedObjectArray constraints; constraints.push_back(Constraint(c)); m_constraints[c.m_node] = constraints; + m_frictions[c.m_node] = Friction(); } else { @@ -193,11 +210,10 @@ void btContactProjection::setConstraintDirections() } // for particles with more than three constrained directions, prune constrained directions so that there are at most three constrained directions - counter = 0; const int dim = 3; - for (auto it : m_constraints) + for (auto& it : m_constraints) { - const btAlignedObjectArray& c = it.second; + btAlignedObjectArray& c = it.second; if (c.size() > dim) { btAlignedObjectArray prunedConstraints; @@ -216,7 +232,7 @@ void btContactProjection::setConstraintDirections() min_dotProductAbs = dotProductAbs; } } - if (std::abs(min_dotProductAbs-1) < SIMD_EPSILON) + if (std::abs(std::abs(min_dotProductAbs)-1) < SIMD_EPSILON) { it.second = prunedConstraints; continue; @@ -240,5 +256,23 @@ void btContactProjection::setConstraintDirections() prunedConstraints.push_back(c[selected2]); it.second = prunedConstraints; } + else + { + // prune out collinear constraints + const btVector3& first_dir = c[0].m_direction; + int i = 1; + while (i < c.size()) + { + if (std::abs(std::abs(first_dir.dot(c[i].m_direction)) - 1) < 4*SIMD_EPSILON) + c.removeAtIndex(i); + else + ++i; + } + if (c.size() == 3) + { + if (std::abs(std::abs(c[1].m_direction.dot(c[2].m_direction)) - 1) < 4*SIMD_EPSILON) + c.removeAtIndex(2); + } + } } } diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index a497c933c..29d0e6632 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -30,18 +30,22 @@ public: virtual void operator()(TVStack& x) { const int dim = 3; - for (auto it : m_constraints) + for (auto& it : m_constraints) { const btAlignedObjectArray& constraints = it.second; size_t i = m_indices[it.first]; + const Friction& friction = m_frictions[it.first]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); if (constraints.size() == 1) { x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; + if (friction.m_direction.norm() > SIMD_EPSILON) + x[i] -= x[i].dot(friction.m_direction) * friction.m_direction; } else if (constraints.size() == 2) { + // TODO : friction btVector3 free_dir = btCross(constraints[0].m_direction, constraints[1].m_direction); free_dir.normalize(); x[i] = x[i].dot(free_dir) * free_dir; @@ -55,16 +59,22 @@ public: virtual void enforceConstraint(TVStack& x) { const int dim = 3; - for (auto it : m_constraints) + for (auto& it : m_constraints) { const btAlignedObjectArray& constraints = it.second; size_t i = m_indices[it.first]; + const Friction& friction = m_frictions[it.first]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); if (constraints.size() == 1) { x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; x[i] += constraints[0].m_value * constraints[0].m_direction; + if (friction.m_direction.norm() > SIMD_EPSILON) + { + x[i] -= x[i].dot(friction.m_direction) * friction.m_direction; + x[i] += friction.m_dv; + } } else if (constraints.size() == 2) { diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index b457a262f..b7c531385 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -122,6 +122,7 @@ void btDeformableBodySolver::solveConstraints(float solverdt) updateVelocity(); } advect(solverdt); +// postStabilize(); } void btDeformableBodySolver::reinitialize(bool nodeUpdated) diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 41911b2bc..12d96171f 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -891,7 +891,8 @@ struct btSoftColliders c.m_c0 = ImpulseMatrix(psb->m_sst.sdt, ima, imb, iwi, ra); c.m_c1 = ra; c.m_c2 = ima * psb->m_sst.sdt; - c.m_c3 = fv.length2() < (dn * fc * dn * fc) ? 0 : 1 - fc; +// c.m_c3 = fv.length2() < (dn * fc * dn * fc) ? 0 : 1 - fc; + c.m_c3 = fc; c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR; psb->m_rcontacts.push_back(c); if (m_rigidBody) From 98cd9a85e4416686e099969332691c91b60a3468 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 12 Jul 2019 10:35:50 -0700 Subject: [PATCH 12/47] generalize preconditioner, now supports mass preconditioning --- .../btBackwardEulerObjective.cpp | 10 ++- src/BulletSoftBody/btBackwardEulerObjective.h | 82 ++++++++++++++++--- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp index 8801e68df..12c7a7add 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -8,14 +8,15 @@ #include "btBackwardEulerObjective.h" btBackwardEulerObjective::btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) -: cg(20) +: cg(50) , m_softBodies(softBodies) -, precondition(DefaultPreconditioner()) , projection(m_softBodies, m_dt) , m_backupVelocity(backup_v) { // TODO: this should really be specified in initialization instead of here btMassSpring* mass_spring = new btMassSpring(m_softBodies); +// m_preconditioner = new MassPreconditioner(m_softBodies); + m_preconditioner = new DefaultPreconditioner(); m_lf.push_back(mass_spring); } @@ -28,8 +29,9 @@ void btBackwardEulerObjective::reinitialize(bool nodeUpdated) for (int i = 0; i < m_lf.size(); ++i) { m_lf[i]->reinitialize(nodeUpdated); - projection.reinitialize(nodeUpdated); } + projection.reinitialize(nodeUpdated); + m_preconditioner->reinitialize(nodeUpdated); } @@ -64,7 +66,7 @@ void btBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const void btBackwardEulerObjective::computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt) { m_dt = dt; - btScalar tolerance = std::numeric_limits::epsilon()* 16 * computeNorm(residual); + btScalar tolerance = std::numeric_limits::epsilon()* 1024 * computeNorm(residual); cg.solve(*this, dv, residual, tolerance); } diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h index 424291700..9b94341b7 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -15,25 +15,82 @@ #include "btDeformableRigidDynamicsWorld.h" class btDeformableRigidDynamicsWorld; + +class Preconditioner +{ +public: + using TVStack = btAlignedObjectArray; + virtual void operator()(const TVStack& x, TVStack& b) = 0; + virtual void reinitialize(bool nodeUpdated) = 0; +}; + +class DefaultPreconditioner : public Preconditioner +{ +public: + virtual void operator()(const TVStack& x, TVStack& b) + { + btAssert(b.size() == x.size()); + for (int i = 0; i < b.size(); ++i) + b[i] = x[i]; + } + virtual void reinitialize(bool nodeUpdated) + { + + } +}; + +class MassPreconditioner : public Preconditioner +{ + btAlignedObjectArray m_inv_mass; + const btAlignedObjectArray& m_softBodies; +public: + MassPreconditioner(const btAlignedObjectArray& softBodies) + : m_softBodies(softBodies) + { + } + + virtual void reinitialize(bool nodeUpdated) + { + if (nodeUpdated) + { + m_inv_mass.clear(); + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + m_inv_mass.push_back(psb->m_nodes[j].m_im); + } + } + } + + virtual void operator()(const TVStack& x, TVStack& b) + { + btAssert(b.size() == x.size()); + btAssert(m_inv_mass.size() == x.size()); + for (int i = 0; i < b.size(); ++i) + b[i] = x[i] * m_inv_mass[i]; + } +}; + class btBackwardEulerObjective { public: using TVStack = btAlignedObjectArray; - struct DefaultPreconditioner - { - void operator()(const TVStack& x, TVStack& b) - { - btAssert(b.size() == x.size()); - for (int i = 0; i < b.size(); ++i) - b[i] = x[i]; - } - }; +// struct DefaultPreconditioner +// { +// void operator()(const TVStack& x, TVStack& b) +// { +// btAssert(b.size() == x.size()); +// for (int i = 0; i < b.size(); ++i) +// b[i] = x[i]; +// } +// }; btScalar m_dt; btConjugateGradient cg; btDeformableRigidDynamicsWorld* m_world; btAlignedObjectArray m_lf; btAlignedObjectArray& m_softBodies; - std::function precondition; + Preconditioner* m_preconditioner; btContactProjection projection; const TVStack& m_backupVelocity; @@ -92,10 +149,9 @@ public: projection(r); } - template - void setPreconditioner(Func preconditioner_func) + void precondition(const TVStack& x, TVStack& b) { - precondition = preconditioner_func; + m_preconditioner->operator()(x,b); } virtual void setWorld(btDeformableRigidDynamicsWorld* world) From ac628f4d394f39d10cd178e005b63ad7dda0e1f0 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 12 Jul 2019 13:26:58 -0700 Subject: [PATCH 13/47] add two way coupled penetration resolution; not momentum conserving, but seem to work fine --- src/BulletSoftBody/btDeformableBodySolver.cpp | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index b7c531385..41a5df70d 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -87,21 +87,22 @@ void btDeformableBodySolver::postStabilize() if (dp < 0) { c.m_node->m_x -= dp * cti.m_normal * c.m_c4; +// c.m_node->m_x -= impulse * c.m_c2; //// -// if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) -// { -// if (rigidCol) -// rigidCol->applyImpulse(impulse, c.m_c1); -// } -// else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) -// { -// if (multibodyLinkCol) -// { -// double multiplier = 0.5; -// multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); -// } -// } + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + if (rigidCol) + rigidCol->applyImpulse(impulse, c.m_c1); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + if (multibodyLinkCol) + { + double multiplier = 0.5; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + } + } } } } From bac7d461c5a9d318a04b9741cccf7f1759132bf3 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Mon, 15 Jul 2019 10:48:20 -0700 Subject: [PATCH 14/47] fix bugs in poststablize and projection of colinear constraints --- src/BulletSoftBody/btContactProjection.cpp | 31 +++++----- src/BulletSoftBody/btContactProjection.h | 25 ++++++-- src/BulletSoftBody/btDeformableBodySolver.cpp | 37 ++++++------ src/BulletSoftBody/btDeformableBodySolver.h | 5 +- src/BulletSoftBody/btSoftBodyInternals.h | 60 ++++++++++--------- 5 files changed, 89 insertions(+), 69 deletions(-) diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index b90c749f3..6082f4dad 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -11,6 +11,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocity) { ///solve rigid body constraints + m_world->getSolverInfo().m_numIterations = 5; m_world->btMultiBodyDynamicsWorld::solveConstraints(m_world->getSolverInfo()); // loop through constraints to set constrained values @@ -258,21 +259,21 @@ void btContactProjection::setConstraintDirections() } else { - // prune out collinear constraints - const btVector3& first_dir = c[0].m_direction; - int i = 1; - while (i < c.size()) - { - if (std::abs(std::abs(first_dir.dot(c[i].m_direction)) - 1) < 4*SIMD_EPSILON) - c.removeAtIndex(i); - else - ++i; - } - if (c.size() == 3) - { - if (std::abs(std::abs(c[1].m_direction.dot(c[2].m_direction)) - 1) < 4*SIMD_EPSILON) - c.removeAtIndex(2); - } +// // prune out collinear constraints +// const btVector3& first_dir = c[0].m_direction; +// int i = 1; +// while (i < c.size()) +// { +// if (std::abs(std::abs(first_dir.dot(c[i].m_direction)) - 1) < 4*SIMD_EPSILON) +// c.removeAtIndex(i); +// else +// ++i; +// } +// if (c.size() == 3) +// { +// if (std::abs(std::abs(c[1].m_direction.dot(c[2].m_direction)) - 1) < 4*SIMD_EPSILON) +// c.removeAtIndex(2); +// } } } } diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index 29d0e6632..8ce3cb578 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -47,8 +47,13 @@ public: { // TODO : friction btVector3 free_dir = btCross(constraints[0].m_direction, constraints[1].m_direction); - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir; + if (free_dir.norm() < SIMD_EPSILON) + x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; + else + { + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; + } } else x[i].setZero(); @@ -69,7 +74,8 @@ public: if (constraints.size() == 1) { x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; - x[i] += constraints[0].m_value * constraints[0].m_direction; + btVector3 diff = constraints[0].m_value * constraints[0].m_direction; + x[i] += diff; if (friction.m_direction.norm() > SIMD_EPSILON) { x[i] -= x[i].dot(friction.m_direction) * friction.m_direction; @@ -79,8 +85,17 @@ public: else if (constraints.size() == 2) { btVector3 free_dir = btCross(constraints[0].m_direction, constraints[1].m_direction); - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir + constraints[0].m_direction * constraints[0].m_value + constraints[1].m_direction * constraints[1].m_value; + if (free_dir.norm() < SIMD_EPSILON) + { + x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; + btVector3 diff = constraints[0].m_value * constraints[0].m_direction + constraints[1].m_value * constraints[1].m_direction; + x[i] += diff; + } + else + { + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir + constraints[0].m_direction * constraints[0].m_value + constraints[1].m_direction * constraints[1].m_value; + } } else x[i] = constraints[0].m_value * constraints[0].m_direction + constraints[1].m_value * constraints[1].m_direction + constraints[2].m_value * constraints[2].m_direction; diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index 41a5df70d..e9bcf226a 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -77,8 +77,8 @@ void btDeformableBodySolver::postStabilize() const btVector3 vr = vb - va; const btScalar dn = btDot(vr, cti.m_normal); - const btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); - + btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); +// dp += mrg; // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient btScalar dvn = dn * c.m_c4; @@ -86,23 +86,27 @@ void btDeformableBodySolver::postStabilize() // TODO: only contact is considered here, add friction later if (dp < 0) { - c.m_node->m_x -= dp * cti.m_normal * c.m_c4; -// c.m_node->m_x -= impulse * c.m_c2; - - //// - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + bool two_way = false; + if (two_way) { - if (rigidCol) - rigidCol->applyImpulse(impulse, c.m_c1); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - if (multibodyLinkCol) + c.m_node->m_x -= impulse * c.m_c2; + + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { - double multiplier = 0.5; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + if (rigidCol) + rigidCol->applyImpulse(impulse, c.m_c1); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + if (multibodyLinkCol) + { + double multiplier = 0.5; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + } } } + else + c.m_node->m_x -= dp * cti.m_normal * c.m_c4; } } } @@ -115,7 +119,6 @@ void btDeformableBodySolver::solveConstraints(float solverdt) bool nodeUpdated = updateNodes(); reinitialize(nodeUpdated); backupVelocity(); - postStabilize(); for (int i = 0; i < m_solveIterations; ++i) { m_objective->computeResidual(solverdt, m_residual); @@ -123,7 +126,7 @@ void btDeformableBodySolver::solveConstraints(float solverdt) updateVelocity(); } advect(solverdt); -// postStabilize(); + postStabilize(); } void btDeformableBodySolver::reinitialize(bool nodeUpdated) diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 540a2b6cb..3fac0743d 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -2,7 +2,7 @@ // btDeformableBodySolver.h // BulletSoftBody // -// Created by Chuyuan Fu on 7/1/19. +// Created by Xuchen Han on 7/1/19. // #ifndef BT_DEFORMABLE_BODY_SOLVERS_H @@ -101,8 +101,7 @@ public: for (int j = 0; j < psb->m_nodes.size(); ++j) { auto& node = psb->m_nodes[j]; - node.m_x += dt * m_dv[counter++]; -// node.m_x = node.m_q + dt * node.m_v; + node.m_x = node.m_q + dt * node.m_v; } } } diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 12d96171f..b892498ea 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -869,35 +869,37 @@ struct btSoftColliders const btScalar m = n.m_im > 0 ? dynmargin : stamargin; btSoftBody::RContact c; - if ((!n.m_battach) && - psb->checkContact(m_colObj1Wrap, n.m_x, m, c.m_cti)) - { - const btScalar ima = n.m_im; - const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f; - const btScalar ms = ima + imb; - if (ms > 0) - { - const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); - static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0); - const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; - const btVector3 ra = n.m_q - wtr.getOrigin(); - const btVector3 va = m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra) * psb->m_sst.sdt : btVector3(0, 0, 0); - const btVector3 vb = n.m_x - n.m_q; - const btVector3 vr = vb - va; - const btScalar dn = btDot(vr, c.m_cti.m_normal); - const btVector3 fv = vr - c.m_cti.m_normal * dn; - const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); - c.m_node = &n; - c.m_c0 = ImpulseMatrix(psb->m_sst.sdt, ima, imb, iwi, ra); - c.m_c1 = ra; - c.m_c2 = ima * psb->m_sst.sdt; -// c.m_c3 = fv.length2() < (dn * fc * dn * fc) ? 0 : 1 - fc; - c.m_c3 = fc; - c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR; - psb->m_rcontacts.push_back(c); - if (m_rigidBody) - m_rigidBody->activate(); - } + if (!n.m_battach) + { + if (psb->checkContact(m_colObj1Wrap, n.m_x, m, c.m_cti)) + { + const btScalar ima = n.m_im; + const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f; + const btScalar ms = ima + imb; + if (ms > 0) + { + const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); + static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0); + const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; + const btVector3 ra = n.m_x - wtr.getOrigin(); + const btVector3 va = m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra) * psb->m_sst.sdt : btVector3(0, 0, 0); + const btVector3 vb = n.m_x - n.m_q; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, c.m_cti.m_normal); + const btVector3 fv = vr - c.m_cti.m_normal * dn; + const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); + c.m_node = &n; + c.m_c0 = ImpulseMatrix(psb->m_sst.sdt, ima, imb, iwi, ra); + c.m_c1 = ra; + c.m_c2 = ima * psb->m_sst.sdt; + // c.m_c3 = fv.length2() < (dn * fc * dn * fc) ? 0 : 1 - fc; + c.m_c3 = fc; + c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR; + psb->m_rcontacts.push_back(c); + if (m_rigidBody) + m_rigidBody->activate(); + } + } } } btSoftBody* psb; From befab4eab6ac8ef8aea141d8e89a463648e9de41 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Mon, 15 Jul 2019 14:52:24 -0700 Subject: [PATCH 15/47] reorganize the contact constraints --- src/BulletSoftBody/btCGProjection.h | 32 +-- src/BulletSoftBody/btContactProjection.cpp | 244 +++++++++------------ src/BulletSoftBody/btContactProjection.h | 58 ++--- 3 files changed, 151 insertions(+), 183 deletions(-) diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 6c104ef2f..91621e49b 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -14,37 +14,41 @@ class btDeformableRigidDynamicsWorld; struct Constraint { - const btSoftBody::RContact* m_contact; - btVector3 m_direction; - btScalar m_value; + btAlignedObjectArray m_contact; + btAlignedObjectArray m_direction; + btAlignedObjectArray m_value; Constraint(const btSoftBody::RContact& rcontact) - : m_contact(&rcontact) - , m_direction(rcontact.m_cti.m_normal) - , m_value(0) { + m_contact.push_back(&rcontact); + m_direction.push_back(rcontact.m_cti.m_normal); + m_value.push_back(0); } Constraint(const btVector3 dir) - : m_contact(nullptr) - , m_direction(dir) - , m_value(0) - {} + { + m_contact.push_back(nullptr); + m_direction.push_back(dir); + m_value.push_back(0); + } Constraint() - : m_contact(nullptr) { - } }; struct Friction { - btVector3 m_dv; + bool m_static; + btScalar m_value; btVector3 m_direction; + + bool m_static_prev; + btScalar m_value_prev; + btVector3 m_direction_prev; Friction() { - m_dv.setZero(); + m_direction_prev.setZero(); m_direction.setZero(); } }; diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 6082f4dad..9388ac7e4 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -22,93 +22,97 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit for (int i = 0; i < constraints.size(); ++i) { Constraint& constraint = constraints[i]; - if (constraint.m_contact == nullptr) + for (int j = 0; j < constraint.m_contact.size(); ++j) { - // nothing needs to be done for dirichelet constraints - continue; - } - const btSoftBody::RContact* c = constraint.m_contact; - const btSoftBody::sCti& cti = c->m_cti; - btMultiBodyJacobianData jacobianData; - if (cti.m_colObj->hasContactResponse()) - { - btVector3 va(0, 0, 0); - btRigidBody* rigidCol = 0; - btMultiBodyLinkCollider* multibodyLinkCol = 0; - btScalar* deltaV; - - // grab the velocity of the rigid body - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + if (constraint.m_contact[j] == nullptr) { - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c->m_c1)) * m_dt : btVector3(0, 0, 0); + // nothing needs to be done for dirichelet constraints + continue; } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + const btSoftBody::RContact* c = constraint.m_contact[j]; + const btSoftBody::sCti& cti = c->m_cti; + btMultiBodyJacobianData jacobianData; + if (cti.m_colObj->hasContactResponse()) { - multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); - if (multibodyLinkCol) - { - const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - jacobianData.m_jacobians.resize(ndof); - jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); - btScalar* jac = &jacobianData.m_jacobians[0]; - - multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c->m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); - deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); - - btScalar vel = 0.0; - for (int j = 0; j < ndof; ++j) - { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; - } - va = cti.m_normal * vel * m_dt; - } - } - - const btVector3 vb = c->m_node->m_v * m_dt; - const btVector3 vr = vb - va; - const btScalar dn = btDot(vr, cti.m_normal); - btVector3 impulse = c->m_c0 * vr; - const btVector3 impulse_normal = c->m_c0 *(cti.m_normal * dn); - btVector3 impulse_tangent = impulse - impulse_normal; - - if (dn < 0 && impulse_tangent.norm() > SIMD_EPSILON) - { - btScalar impulse_tangent_magnitude = std::min(impulse_normal.norm()*c->m_c3, impulse_tangent.norm()); - - impulse_tangent_magnitude = 0; - - const btVector3 tangent_dir = impulse_tangent.normalized(); - impulse_tangent = impulse_tangent_magnitude * tangent_dir; - friction.m_direction = impulse_tangent; - friction.m_dv = -impulse_tangent * c->m_c2/m_dt + (c->m_node->m_v - backupVelocity[m_indices[c->m_node]]).dot(tangent_dir)*tangent_dir; - } - impulse = impulse_normal + impulse_tangent; -// if (1) // in the same CG solve, the set of constraits doesn't change - if (dn <= SIMD_EPSILON) - { - // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - - // TODO: only contact is considered here, add friction later - - // dv = new_impulse + accumulated velocity change in previous CG iterations - // so we have the invariant node->m_v = backupVelocity + dv; - btVector3 dv = -impulse * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; - btScalar dvn = dv.dot(cti.m_normal); - constraint.m_value = dvn; + btVector3 va(0, 0, 0); + btRigidBody* rigidCol = 0; + btMultiBodyLinkCollider* multibodyLinkCol = 0; + btScalar* deltaV; + // grab the velocity of the rigid body if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { - if (rigidCol) - rigidCol->applyImpulse(impulse_normal, c->m_c1); + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c->m_c1)) * m_dt : btVector3(0, 0, 0); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); if (multibodyLinkCol) { - double multiplier = 0.5; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c->m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); + + btScalar vel = 0.0; + for (int j = 0; j < ndof; ++j) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + } + va = cti.m_normal * vel * m_dt; + } + } + + const btVector3 vb = c->m_node->m_v * m_dt; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, cti.m_normal); + btVector3 impulse = c->m_c0 * vr; + const btVector3 impulse_normal = c->m_c0 *(cti.m_normal * dn); + btVector3 impulse_tangent = impulse - impulse_normal; + + if (dn < 0 && impulse_tangent.norm() > SIMD_EPSILON) + { + btScalar impulse_tangent_magnitude = std::min(impulse_normal.norm()*c->m_c3*1000, impulse_tangent.norm()); + +// impulse_tangent_magnitude = 0; + + const btVector3 tangent_dir = impulse_tangent.normalized(); + impulse_tangent = impulse_tangent_magnitude * tangent_dir; + friction.m_direction = impulse_tangent; + friction.m_dv = -impulse_tangent * c->m_c2/m_dt + (c->m_node->m_v - backupVelocity[m_indices[c->m_node]]); + } + impulse = impulse_normal + impulse_tangent; + + // if (1) // in the same CG solve, the set of constraits doesn't change + if (dn <= SIMD_EPSILON) + { + // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient + + // TODO: only contact is considered here, add friction later + + // dv = new_impulse + accumulated velocity change in previous CG iterations + // so we have the invariant node->m_v = backupVelocity + dv; + btVector3 dv = -impulse * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; + btScalar dvn = dv.dot(cti.m_normal); + constraint.m_value[j] = dvn; + + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + if (rigidCol) + rigidCol->applyImpulse(impulse_normal, c->m_c1); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + if (multibodyLinkCol) + { + double multiplier = 0.5; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + } } } } @@ -202,78 +206,30 @@ void btContactProjection::setConstraintDirections() } else { - m_constraints[c.m_node].push_back(Constraint(c)); + // group colinear constraints into one + const btScalar angle_epsilon = 0.015192247; // less than 10 degree + bool merged = false; + btAlignedObjectArray& constraints = m_constraints[c.m_node]; + for (int j = 0; j < constraints.size(); ++j) + { + const btAlignedObjectArray& dirs = constraints[j].m_direction; + btScalar dot_prod = dirs[0].dot(cti.m_normal); + if (std::abs(std::abs(dot_prod) - 1) < angle_epsilon) + { + constraints[j].m_contact.push_back(&c); + constraints[j].m_direction.push_back(cti.m_normal); + constraints[j].m_value.push_back(0); + merged = true; + break; + } + } + const int dim = 3; + // hard coded no more than 3 constraint directions + if (!merged && constraints.size() < dim) + constraints.push_back(Constraint(c)); } - continue; } } } } - - // for particles with more than three constrained directions, prune constrained directions so that there are at most three constrained directions - const int dim = 3; - for (auto& it : m_constraints) - { - btAlignedObjectArray& c = it.second; - if (c.size() > dim) - { - btAlignedObjectArray prunedConstraints; - // always keep the first constrained direction - prunedConstraints.push_back(c[0]); - - // find the direction most orthogonal to the first direction and keep it - size_t selected = 1; - btScalar min_dotProductAbs = std::abs(prunedConstraints[0].m_direction.dot(c[selected].m_direction)); - for (int j = 2; j < c.size(); ++j) - { - btScalar dotProductAbs =std::abs(prunedConstraints[0].m_direction.dot(c[j].m_direction)); - if (dotProductAbs < min_dotProductAbs) - { - selected = j; - min_dotProductAbs = dotProductAbs; - } - } - if (std::abs(std::abs(min_dotProductAbs)-1) < SIMD_EPSILON) - { - it.second = prunedConstraints; - continue; - } - prunedConstraints.push_back(c[selected]); - - // find the direction most orthogonal to the previous two directions and keep it - size_t selected2 = (selected == 1) ? 2 : 1; - btVector3 normal = btCross(prunedConstraints[0].m_direction, prunedConstraints[1].m_direction); - normal.normalize(); - btScalar max_dotProductAbs = std::abs(normal.dot(c[selected2].m_direction)); - for (int j = 3; j < c.size(); ++j) - { - btScalar dotProductAbs = std::abs(normal.dot(c[j].m_direction)); - if (dotProductAbs > min_dotProductAbs) - { - selected2 = j; - max_dotProductAbs = dotProductAbs; - } - } - prunedConstraints.push_back(c[selected2]); - it.second = prunedConstraints; - } - else - { -// // prune out collinear constraints -// const btVector3& first_dir = c[0].m_direction; -// int i = 1; -// while (i < c.size()) -// { -// if (std::abs(std::abs(first_dir.dot(c[i].m_direction)) - 1) < 4*SIMD_EPSILON) -// c.removeAtIndex(i); -// else -// ++i; -// } -// if (c.size() == 3) -// { -// if (std::abs(std::abs(c[1].m_direction.dot(c[2].m_direction)) - 1) < 4*SIMD_EPSILON) -// c.removeAtIndex(2); -// } - } - } } diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index 8ce3cb578..1e5c52a60 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -39,21 +39,20 @@ public: btAssert(constraints.size() > 0); if (constraints.size() == 1) { - x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; + x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; if (friction.m_direction.norm() > SIMD_EPSILON) - x[i] -= x[i].dot(friction.m_direction) * friction.m_direction; + { + btVector3 dir = friction.m_direction.normalized(); + x[i] -= x[i].dot(dir) * dir; + } } else if (constraints.size() == 2) { // TODO : friction - btVector3 free_dir = btCross(constraints[0].m_direction, constraints[1].m_direction); - if (free_dir.norm() < SIMD_EPSILON) - x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; - else - { - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir; - } + btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); + btAssert(free_dir.norm() > SIMD_EPSILON) + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; } else x[i].setZero(); @@ -73,32 +72,41 @@ public: btAssert(constraints.size() > 0); if (constraints.size() == 1) { - x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; - btVector3 diff = constraints[0].m_value * constraints[0].m_direction; - x[i] += diff; + x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; + for (int j = 0; j < constraints[0].m_direction.size(); ++j) + x[i] += constraints[0].m_value[j] * constraints[0].m_direction[j]; if (friction.m_direction.norm() > SIMD_EPSILON) { - x[i] -= x[i].dot(friction.m_direction) * friction.m_direction; + btVector3 dir = friction.m_direction.normalized(); + x[i] -= x[i].dot(dir) * dir; x[i] += friction.m_dv; } } else if (constraints.size() == 2) { - btVector3 free_dir = btCross(constraints[0].m_direction, constraints[1].m_direction); - if (free_dir.norm() < SIMD_EPSILON) + btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); + btAssert(free_dir.norm() > SIMD_EPSILON) + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; + for (int j = 0; j < constraints.size(); ++j) { - x[i] -= x[i].dot(constraints[0].m_direction) * constraints[0].m_direction; - btVector3 diff = constraints[0].m_value * constraints[0].m_direction + constraints[1].m_value * constraints[1].m_direction; - x[i] += diff; - } - else - { - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir + constraints[0].m_direction * constraints[0].m_value + constraints[1].m_direction * constraints[1].m_value; + for (int k = 0; k < constraints[j].m_direction.size(); ++k) + { + x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; + } } } else - x[i] = constraints[0].m_value * constraints[0].m_direction + constraints[1].m_value * constraints[1].m_direction + constraints[2].m_value * constraints[2].m_direction; + { + x[i].setZero(); + for (int j = 0; j < constraints.size(); ++j) + { + for (int k = 0; k < constraints[j].m_direction.size(); ++k) + { + x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; + } + } + } } } From 2fc376e8f58fbf983b79c73da8ea2fd86cc9a170 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Tue, 16 Jul 2019 15:28:33 -0700 Subject: [PATCH 16/47] bug fix in friction; accumulate friction impulses in cg; forbid switching from static to dynamic friction --- .../btBackwardEulerObjective.cpp | 18 +--- src/BulletSoftBody/btCGProjection.h | 28 ++++-- src/BulletSoftBody/btConjugateGradient.h | 2 - src/BulletSoftBody/btContactProjection.cpp | 89 +++++++++++++++---- src/BulletSoftBody/btContactProjection.h | 43 +++++++-- 5 files changed, 124 insertions(+), 56 deletions(-) diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp index 12c7a7add..e8c4c3edc 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -8,7 +8,7 @@ #include "btBackwardEulerObjective.h" btBackwardEulerObjective::btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) -: cg(50) +: cg(20) , m_softBodies(softBodies) , projection(m_softBodies, m_dt) , m_backupVelocity(backup_v) @@ -79,20 +79,4 @@ void btBackwardEulerObjective::updateVelocity(const TVStack& dv) it.first->m_v = m_backupVelocity[i] + dv[i]; } } - -// for (int i = 0; i < m_softBodies.size(); ++i) -// { -// int counter = 0; -// for (int i = 0; i < m_softBodies.size(); ++i) -// { -// btSoftBody* psb = m_softBodies[i]; -// for (int j = 0; j < psb->m_nodes.size(); ++j) -// { -// // only the velocity of the constrained nodes needs to be updated during CG solve -// if (projection.m_constraints[&(psb->m_nodes[j])].size() > 0) -// psb->m_nodes[j].m_v = m_backupVelocity[counter] + dv[counter]; -// ++counter; -// } -// } -// } diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 91621e49b..b0f798dad 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -39,17 +39,27 @@ struct Constraint struct Friction { - bool m_static; - btScalar m_value; - btVector3 m_direction; + btAlignedObjectArray m_static; + btAlignedObjectArray m_value; + btAlignedObjectArray m_direction; - bool m_static_prev; - btScalar m_value_prev; - btVector3 m_direction_prev; + btAlignedObjectArray m_static_prev; + btAlignedObjectArray m_value_prev; + btAlignedObjectArray m_direction_prev; + + btAlignedObjectArray m_accumulated_impulse; Friction() { - m_direction_prev.setZero(); - m_direction.setZero(); + m_static.push_back(false); + m_static_prev.push_back(false); + + m_direction.push_back(btVector3(0,0,0)); + m_direction_prev.push_back(btVector3(0,0,0)); + + m_value.push_back(0); + m_value_prev.push_back(0); + + m_accumulated_impulse.push_back(btVector3(0,0,0)); } }; @@ -65,7 +75,7 @@ public: std::unordered_map m_indices; const btScalar& m_dt; std::unordered_map > m_constraints; - std::unordered_map m_frictions; + std::unordered_map > m_frictions; btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : m_softBodies(softBodies) diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index 0a88e6b94..a2b69f48d 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -63,11 +63,9 @@ public: // r -= alpha * temp; multAndAddTo(alpha, p, x); multAndAddTo(-alpha, temp, r); - // zero out the dofs of r A.project(r,x); A.enforceConstraint(x); - r_norm = std::sqrt(squaredNorm(r)); if (r_norm < tolerance) { diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 9388ac7e4..e356da264 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -17,11 +17,12 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit // loop through constraints to set constrained values for (auto& it : m_constraints) { - Friction& friction = m_frictions[it.first]; + btAlignedObjectArray& frictions = m_frictions[it.first]; btAlignedObjectArray& constraints = it.second; for (int i = 0; i < constraints.size(); ++i) { Constraint& constraint = constraints[i]; + Friction& friction = frictions[i]; for (int j = 0; j < constraint.m_contact.size(); ++j) { if (constraint.m_contact[j] == nullptr) @@ -75,36 +76,64 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit const btVector3 impulse_normal = c->m_c0 *(cti.m_normal * dn); btVector3 impulse_tangent = impulse - impulse_normal; - if (dn < 0 && impulse_tangent.norm() > SIMD_EPSILON) - { - btScalar impulse_tangent_magnitude = std::min(impulse_normal.norm()*c->m_c3*1000, impulse_tangent.norm()); - -// impulse_tangent_magnitude = 0; - - const btVector3 tangent_dir = impulse_tangent.normalized(); - impulse_tangent = impulse_tangent_magnitude * tangent_dir; - friction.m_direction = impulse_tangent; - friction.m_dv = -impulse_tangent * c->m_c2/m_dt + (c->m_node->m_v - backupVelocity[m_indices[c->m_node]]); - } - impulse = impulse_normal + impulse_tangent; + + // accumulated impulse on the rb in this and all prev cg iterations + friction.m_accumulated_impulse[j] += impulse; + btScalar accumulated_normal = friction.m_accumulated_impulse[j].dot(cti.m_normal); + btVector3 accumulated_tangent = friction.m_accumulated_impulse[j] - accumulated_normal * cti.m_normal; - // if (1) // in the same CG solve, the set of constraits doesn't change - if (dn <= SIMD_EPSILON) + // start friction handling + // copy old data + friction.m_direction_prev[j] = friction.m_direction[j]; + friction.m_value_prev[j] = friction.m_value[j]; + friction.m_static_prev[j] = friction.m_static[j]; + if (accumulated_normal < 0 && accumulated_tangent.norm() > SIMD_EPSILON) + { + // do not allow switching from static friction to dynamic friction + // it causes cg to explode + if (-accumulated_normal*c->m_c3 < accumulated_tangent.norm() && friction.m_static_prev[j] == false) + { + friction.m_static[j] = false; + friction.m_value[j] = -accumulated_normal*c->m_c3; + } + else + { + friction.m_static[j] = true; + friction.m_value[j] = accumulated_tangent.norm(); + } + + const btVector3 tangent_dir = accumulated_tangent.normalized(); + impulse_tangent = friction.m_value[j] * tangent_dir; + friction.m_direction[j] = -tangent_dir; + } + else + { + friction.m_static[j] = false; + friction.m_value[j] = 0; + impulse_tangent.setZero(); + } + + + if (1) // in the same CG solve, the set of constraits doesn't change +// if (dn <= SIMD_EPSILON) { // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - // TODO: only contact is considered here, add friction later - // dv = new_impulse + accumulated velocity change in previous CG iterations // so we have the invariant node->m_v = backupVelocity + dv; btVector3 dv = -impulse * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; btScalar dvn = dv.dot(cti.m_normal); constraint.m_value[j] = dvn; + // the incremental impulse: + // in the normal direction it's the normal component of "impulse" + // in the tangent direction it's the difference between the frictional impulse in the iteration and the previous iteration + impulse = impulse_normal + (friction.m_value_prev[j] * friction.m_direction_prev[j]) - (friction.m_value[j] * friction.m_direction[j]); + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { if (rigidCol) - rigidCol->applyImpulse(impulse_normal, c->m_c1); + rigidCol->applyImpulse(impulse, c->m_c1); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { @@ -137,6 +166,13 @@ void btContactProjection::setConstraintDirections() c.push_back(Constraint(btVector3(0,1,0))); c.push_back(Constraint(btVector3(0,0,1))); m_constraints[&(psb->m_nodes[j])] = c; + + btAlignedObjectArray f; + f.push_back(Friction()); + f.push_back(Friction()); + f.push_back(Friction()); + m_frictions[&(psb->m_nodes[j])] = f; + // no friction constraints for dirichlet } } } @@ -202,7 +238,9 @@ void btContactProjection::setConstraintDirections() btAlignedObjectArray constraints; constraints.push_back(Constraint(c)); m_constraints[c.m_node] = constraints; - m_frictions[c.m_node] = Friction(); + btAlignedObjectArray frictions; + frictions.push_back(Friction()); + m_frictions[c.m_node] = frictions; } else { @@ -210,6 +248,7 @@ void btContactProjection::setConstraintDirections() const btScalar angle_epsilon = 0.015192247; // less than 10 degree bool merged = false; btAlignedObjectArray& constraints = m_constraints[c.m_node]; + btAlignedObjectArray& frictions = m_frictions[c.m_node]; for (int j = 0; j < constraints.size(); ++j) { const btAlignedObjectArray& dirs = constraints[j].m_direction; @@ -219,6 +258,15 @@ void btContactProjection::setConstraintDirections() constraints[j].m_contact.push_back(&c); constraints[j].m_direction.push_back(cti.m_normal); constraints[j].m_value.push_back(0); + + // push in an empty friction + frictions[j].m_direction.push_back(btVector3(0,0,0)); + frictions[j].m_direction_prev.push_back(btVector3(0,0,0)); + frictions[j].m_value.push_back(0); + frictions[j].m_value_prev.push_back(0); + frictions[j].m_static.push_back(false); + frictions[j].m_static_prev.push_back(false); + frictions[j].m_accumulated_impulse.push_back(btVector3(0,0,0)); merged = true; break; } @@ -226,7 +274,10 @@ void btContactProjection::setConstraintDirections() const int dim = 3; // hard coded no more than 3 constraint directions if (!merged && constraints.size() < dim) + { constraints.push_back(Constraint(c)); + frictions.push_back(Friction()); + } } } } diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index 1e5c52a60..b52bb2d72 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -34,16 +34,31 @@ public: { const btAlignedObjectArray& constraints = it.second; size_t i = m_indices[it.first]; - const Friction& friction = m_frictions[it.first]; + btAlignedObjectArray& frictions = m_frictions[it.first]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); if (constraints.size() == 1) { x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; - if (friction.m_direction.norm() > SIMD_EPSILON) + Friction& friction= frictions[0]; + + bool has_static_constraint = false; + for (int j = 0; j < friction.m_static.size(); ++j) + has_static_constraint = has_static_constraint || friction.m_static[j]; + + for (int j = 0; j < friction.m_direction.size(); ++j) { - btVector3 dir = friction.m_direction.normalized(); - x[i] -= x[i].dot(dir) * dir; + // clear the old friction force + if (friction.m_static_prev[j] == false) + { + x[i] -= friction.m_direction_prev[j] * friction.m_value_prev[j]; + } + + // only add to the rhs if there is no static friction constraint on the node + if (friction.m_static[j] == false && !has_static_constraint) + { + x[i] += friction.m_direction[j] * friction.m_value[j]; + } } } else if (constraints.size() == 2) @@ -67,7 +82,7 @@ public: { const btAlignedObjectArray& constraints = it.second; size_t i = m_indices[it.first]; - const Friction& friction = m_frictions[it.first]; + const btAlignedObjectArray& frictions = m_frictions[it.first]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); if (constraints.size() == 1) @@ -75,15 +90,25 @@ public: x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; for (int j = 0; j < constraints[0].m_direction.size(); ++j) x[i] += constraints[0].m_value[j] * constraints[0].m_direction[j]; - if (friction.m_direction.norm() > SIMD_EPSILON) + + const Friction& friction= frictions[0]; + for (int j = 0; j < friction.m_direction.size(); ++j) { - btVector3 dir = friction.m_direction.normalized(); - x[i] -= x[i].dot(dir) * dir; - x[i] += friction.m_dv; + // clear the old constraint + if (friction.m_static_prev[j] == true) + { + x[i] -= friction.m_direction_prev[j] * friction.m_value_prev[j]; + } + // add the new constraint + if (friction.m_static[j] == true) + { + x[i] += friction.m_direction[j] * friction.m_value[j]; + } } } else if (constraints.size() == 2) { + // TODO: friction btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); btAssert(free_dir.norm() > SIMD_EPSILON) free_dir.normalize(); From 7846dd38dd5172d3b2876a95fa4a515755195668 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Wed, 17 Jul 2019 15:58:55 -0700 Subject: [PATCH 17/47] switch explicit elastic force --- .../btBackwardEulerObjective.cpp | 16 +++++- src/BulletSoftBody/btBackwardEulerObjective.h | 36 +++++++----- src/BulletSoftBody/btCGProjection.h | 16 ++++-- src/BulletSoftBody/btContactProjection.cpp | 34 +++++++----- src/BulletSoftBody/btContactProjection.h | 53 ++++++++++++++++-- src/BulletSoftBody/btDeformableBodySolver.cpp | 11 +++- src/BulletSoftBody/btDeformableBodySolver.h | 14 ----- .../btDeformableRigidDynamicsWorld.cpp | 7 ++- .../btDeformableRigidDynamicsWorld.h | 9 ++- src/BulletSoftBody/btLagrangianForce.h | 4 +- src/BulletSoftBody/btMassSpring.h | 55 ++++++++++++++----- src/BulletSoftBody/btSoftBody.cpp | 12 +++- src/BulletSoftBody/btSoftBody.h | 3 +- 13 files changed, 193 insertions(+), 77 deletions(-) diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp index e8c4c3edc..3f27df5a9 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -57,9 +57,6 @@ void btBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const { // add damping matrix m_lf[i]->addScaledDampingForceDifferential(-m_dt, x, b); - - // add stiffness matrix when fully implicity - m_lf[i]->addScaledElasticForceDifferential(-m_dt*m_dt, x, b); } } @@ -80,3 +77,16 @@ void btBackwardEulerObjective::updateVelocity(const TVStack& dv) } } +void btBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack& residual) +{ + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + dv[counter] = psb->m_nodes[j].m_im * residual[counter] * 1; + ++counter; + } + } +} diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h index 9b94341b7..e9642f6ae 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -76,15 +76,6 @@ class btBackwardEulerObjective { public: using TVStack = btAlignedObjectArray; -// struct DefaultPreconditioner -// { -// void operator()(const TVStack& x, TVStack& b) -// { -// btAssert(b.size() == x.size()); -// for (int i = 0; i < b.size(); ++i) -// b[i] = x[i]; -// } -// }; btScalar m_dt; btConjugateGradient cg; btDeformableRigidDynamicsWorld* m_world; @@ -102,11 +93,29 @@ public: void computeResidual(btScalar dt, TVStack& residual) const { - // gravity is treated explicitly in predictUnconstraintMotion - // add force + // add implicit force for (int i = 0; i < m_lf.size(); ++i) { - m_lf[i]->addScaledForce(dt, residual); + m_lf[i]->addScaledImplicitForce(dt, residual); + } + } + + void applyExplicitForce(TVStack& force) + { + for (int i = 0; i < m_lf.size(); ++i) + m_lf[i]->addScaledExplicitForce(m_dt, force); + + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + btScalar one_over_mass = (psb->m_nodes[j].m_im == 0) ? 0 : psb->m_nodes[j].m_im; + psb->m_nodes[j].m_v += one_over_mass * force[counter]; + force[counter].setZero(); + counter++; + } } } @@ -117,7 +126,7 @@ public: { norm_squared += residual[i].length2(); } - return std::sqrt(norm_squared); + return std::sqrt(norm_squared+SIMD_EPSILON); } void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt); @@ -128,6 +137,7 @@ public: { projection.update(dv, m_backupVelocity); } + void initialGuess(TVStack& dv, const TVStack& residual); void reinitialize(bool nodeUpdated); diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index b0f798dad..a00fe384b 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -40,13 +40,17 @@ struct Constraint struct Friction { btAlignedObjectArray m_static; - btAlignedObjectArray m_value; + btAlignedObjectArray m_impulse; + btAlignedObjectArray m_dv; btAlignedObjectArray m_direction; btAlignedObjectArray m_static_prev; - btAlignedObjectArray m_value_prev; + btAlignedObjectArray m_impulse_prev; + btAlignedObjectArray m_dv_prev; btAlignedObjectArray m_direction_prev; + btAlignedObjectArray m_released; + btAlignedObjectArray m_accumulated_impulse; Friction() { @@ -56,10 +60,14 @@ struct Friction m_direction.push_back(btVector3(0,0,0)); m_direction_prev.push_back(btVector3(0,0,0)); - m_value.push_back(0); - m_value_prev.push_back(0); + m_impulse.push_back(0); + m_impulse_prev.push_back(0); + + m_dv.push_back(0); + m_dv_prev.push_back(0); m_accumulated_impulse.push_back(btVector3(0,0,0)); + m_released.push_back(false); } }; diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index e356da264..3250e010b 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -85,35 +85,41 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit // start friction handling // copy old data friction.m_direction_prev[j] = friction.m_direction[j]; - friction.m_value_prev[j] = friction.m_value[j]; + friction.m_impulse_prev[j] = friction.m_impulse[j]; + friction.m_dv_prev[j] = friction.m_dv[j]; friction.m_static_prev[j] = friction.m_static[j]; if (accumulated_normal < 0 && accumulated_tangent.norm() > SIMD_EPSILON) { + + btScalar compare1 = -accumulated_normal*c->m_c3; + btScalar compare2 = accumulated_tangent.norm(); // do not allow switching from static friction to dynamic friction // it causes cg to explode - if (-accumulated_normal*c->m_c3 < accumulated_tangent.norm() && friction.m_static_prev[j] == false) + if (-accumulated_normal*c->m_c3 < accumulated_tangent.norm() && friction.m_static_prev[j] == false && friction.m_released[j] == false) { friction.m_static[j] = false; - friction.m_value[j] = -accumulated_normal*c->m_c3; + friction.m_impulse[j] = -accumulated_normal*c->m_c3; + friction.m_dv[j] = -accumulated_normal*c->m_c3 *c->m_c2/m_dt ; } else { friction.m_static[j] = true; - friction.m_value[j] = accumulated_tangent.norm(); + friction.m_impulse[j] = accumulated_tangent.norm(); + friction.m_dv[j] = accumulated_tangent.norm() * c->m_c2/m_dt; } const btVector3 tangent_dir = accumulated_tangent.normalized(); - impulse_tangent = friction.m_value[j] * tangent_dir; friction.m_direction[j] = -tangent_dir; } else { + friction.m_released[j] = true; friction.m_static[j] = false; - friction.m_value[j] = 0; - impulse_tangent.setZero(); + friction.m_impulse[j] = 0; + friction.m_dv[j] = 0; } - + friction.m_accumulated_impulse[j] = accumulated_normal * cti.m_normal - friction.m_impulse[j] * friction.m_direction[j]; if (1) // in the same CG solve, the set of constraits doesn't change // if (dn <= SIMD_EPSILON) { @@ -128,8 +134,8 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit // the incremental impulse: // in the normal direction it's the normal component of "impulse" // in the tangent direction it's the difference between the frictional impulse in the iteration and the previous iteration - impulse = impulse_normal + (friction.m_value_prev[j] * friction.m_direction_prev[j]) - (friction.m_value[j] * friction.m_direction[j]); - + impulse = impulse_normal + (friction.m_impulse_prev[j] * friction.m_direction_prev[j]) - (friction.m_impulse[j] * friction.m_direction[j]); +// impulse = impulse_normal; if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { if (rigidCol) @@ -172,7 +178,6 @@ void btContactProjection::setConstraintDirections() f.push_back(Friction()); f.push_back(Friction()); m_frictions[&(psb->m_nodes[j])] = f; - // no friction constraints for dirichlet } } } @@ -262,11 +267,14 @@ void btContactProjection::setConstraintDirections() // push in an empty friction frictions[j].m_direction.push_back(btVector3(0,0,0)); frictions[j].m_direction_prev.push_back(btVector3(0,0,0)); - frictions[j].m_value.push_back(0); - frictions[j].m_value_prev.push_back(0); + frictions[j].m_impulse.push_back(0); + frictions[j].m_impulse_prev.push_back(0); + frictions[j].m_dv.push_back(0); + frictions[j].m_dv_prev.push_back(0); frictions[j].m_static.push_back(false); frictions[j].m_static_prev.push_back(false); frictions[j].m_accumulated_impulse.push_back(btVector3(0,0,0)); + frictions[j].m_released.push_back(false); merged = true; break; } diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index b52bb2d72..969745d93 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -51,13 +51,13 @@ public: // clear the old friction force if (friction.m_static_prev[j] == false) { - x[i] -= friction.m_direction_prev[j] * friction.m_value_prev[j]; + x[i] -= friction.m_direction_prev[j] * friction.m_impulse_prev[j]; } // only add to the rhs if there is no static friction constraint on the node if (friction.m_static[j] == false && !has_static_constraint) { - x[i] += friction.m_direction[j] * friction.m_value[j]; + x[i] += friction.m_direction[j] * friction.m_impulse[j]; } } } @@ -68,6 +68,33 @@ public: btAssert(free_dir.norm() > SIMD_EPSILON) free_dir.normalize(); x[i] = x[i].dot(free_dir) * free_dir; + + bool has_static_constraint = false; + for (int f = 0; f < 2; ++f) + { + Friction& friction= frictions[f]; + for (int j = 0; j < friction.m_static.size(); ++j) + has_static_constraint = has_static_constraint || friction.m_static[j]; + } + + for (int f = 0; f < 2; ++f) + { + Friction& friction= frictions[f]; + for (int j = 0; j < friction.m_direction.size(); ++j) + { + // clear the old friction force + if (friction.m_static_prev[j] == false) + { + x[i] -= friction.m_direction_prev[j] * friction.m_impulse_prev[j]; + } + + // only add to the rhs if there is no static friction constraint on the node + if (friction.m_static[j] == false && !has_static_constraint) + { + x[i] += friction.m_direction[j] * friction.m_impulse[j]; + } + } + } } else x[i].setZero(); @@ -97,12 +124,12 @@ public: // clear the old constraint if (friction.m_static_prev[j] == true) { - x[i] -= friction.m_direction_prev[j] * friction.m_value_prev[j]; + x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; } // add the new constraint if (friction.m_static[j] == true) { - x[i] += friction.m_direction[j] * friction.m_value[j]; + x[i] += friction.m_direction[j] * friction.m_dv[j]; } } } @@ -120,6 +147,24 @@ public: x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; } } + + for (int f = 0; f < 2; ++f) + { + const Friction& friction= frictions[f]; + for (int j = 0; j < friction.m_direction.size(); ++j) + { + // clear the old constraint + if (friction.m_static_prev[j] == true) + { + x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; + } + // add the new constraint + if (friction.m_static[j] == true) + { + x[i] += friction.m_direction[j] * friction.m_dv[j]; + } + } + } } else { diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index e9bcf226a..a8e1e5cd5 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -118,7 +118,15 @@ void btDeformableBodySolver::solveConstraints(float solverdt) m_dt = solverdt; bool nodeUpdated = updateNodes(); reinitialize(nodeUpdated); + + // apply explicit force + m_objective->applyExplicitForce(m_residual); + + // remove contact constraints with separating velocity + setConstraintDirections(); + backupVelocity(); + for (int i = 0; i < m_solveIterations; ++i) { m_objective->computeResidual(solverdt, m_residual); @@ -143,9 +151,6 @@ void btDeformableBodySolver::reinitialize(bool nodeUpdated) m_residual[i].setZero(); } m_objective->reinitialize(nodeUpdated); - - // remove contact constraints with separating velocity - setConstraintDirections(); } void btDeformableBodySolver::setConstraintDirections() diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 3fac0743d..17f088c72 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -74,20 +74,6 @@ public: void postStabilize(); - void moveTempVelocity(btScalar dt, const TVStack& f) - { - size_t counter = 0; - for (int i = 0; i < m_softBodySet.size(); ++i) - { - btSoftBody* psb = m_softBodySet[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - auto& node = psb->m_nodes[j]; - node.m_v += node.m_im * dt * f[counter++]; - } - } - } - void reinitialize(bool nodeUpdated); void setConstraintDirections(); diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 5fdf01a18..173f71206 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -12,6 +12,7 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { + m_internalTime += timeStep; // Let the solver grab the soft bodies and if necessary optimize for it m_deformableBodySolver->optimize(m_softBodies); @@ -54,7 +55,6 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS // gravity is applied in stepSimulation and then cleared here and then applied here and then cleared here again // so that 1) gravity is applied to velocity before constraint solve and 2) gravity is applied in each substep // when there are multiple substeps - clearForces(); clearMultiBodyForces(); btMultiBodyDynamicsWorld::applyGravity(); @@ -69,9 +69,14 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS clearForces(); clearMultiBodyForces(); + + for (int i = 0; i < before_solver_callbacks.size(); ++i) + before_solver_callbacks[i](m_internalTime, this); ///solve deformable bodies constraints solveDeformableBodiesConstraints(timeStep); + + //integrate transforms btMultiBodyDynamicsWorld::integrateTransforms(timeStep); diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index ca1fff885..5bbebeda3 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -21,7 +21,7 @@ #include "btMassSpring.h" #include "btDeformableBodySolver.h" #include "btSoftBodyHelpers.h" - +#include typedef btAlignedObjectArray btSoftBodyArray; class btDeformableBodySolver; @@ -40,6 +40,7 @@ class btDeformableRigidDynamicsWorld : public btMultiBodyDynamicsWorld bool m_drawClusterTree; btSoftBodyWorldInfo m_sbi; bool m_ownsSolver; + btScalar m_internalTime; protected: virtual void internalSingleStepSimulation(btScalar timeStep); @@ -67,8 +68,9 @@ public: m_sbi.m_gravity.setValue(0, -10, 0); m_sbi.m_sparsesdf.Initialize(); + m_internalTime = 0.0; } - + btAlignedObjectArray > before_solver_callbacks; virtual ~btDeformableRigidDynamicsWorld() { } @@ -89,9 +91,6 @@ public: } virtual void predictUnconstraintMotion(btScalar timeStep); - // virtual void internalStepSingleStepSimulation(btScalar timeStep); - - // virtual void solveDeformableBodiesConstraints(btScalar timeStep); virtual void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter); diff --git a/src/BulletSoftBody/btLagrangianForce.h b/src/BulletSoftBody/btLagrangianForce.h index 40e63207e..b95a30ce9 100644 --- a/src/BulletSoftBody/btLagrangianForce.h +++ b/src/BulletSoftBody/btLagrangianForce.h @@ -25,12 +25,14 @@ public: virtual ~btLagrangianForce(){} - virtual void addScaledForce(btScalar scale, TVStack& force) = 0; + virtual void addScaledImplicitForce(btScalar scale, TVStack& force) = 0; virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) = 0; virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) = 0; + virtual void addScaledExplicitForce(btScalar scale, TVStack& force) = 0; + virtual void reinitialize(bool nodeUpdated) { if (nodeUpdated) diff --git a/src/BulletSoftBody/btMassSpring.h b/src/BulletSoftBody/btMassSpring.h index 9fd3c405a..78cdcf7e6 100644 --- a/src/BulletSoftBody/btMassSpring.h +++ b/src/BulletSoftBody/btMassSpring.h @@ -19,7 +19,17 @@ public: } - virtual void addScaledForce(btScalar scale, TVStack& force) + virtual void addScaledImplicitForce(btScalar scale, TVStack& force) + { + addScaledDampingForce(scale, force); + } + + virtual void addScaledExplicitForce(btScalar scale, TVStack& force) + { + addScaledElasticForce(scale, force); + } + + virtual void addScaledDampingForce(btScalar scale, TVStack& force) { int numNodes = getNumNodes(); btAssert(numNodes == force.size()) @@ -31,7 +41,32 @@ public: const auto& link = psb->m_links[j]; const auto node1 = link.m_n[0]; const auto node2 = link.m_n[1]; - btScalar kLST = link.Feature::m_material->m_kLST; // this is probly wrong, TODO: figure out how to get stiffness + size_t id1 = m_indices[node1]; + size_t id2 = m_indices[node2]; + + // damping force + btVector3 v_diff = (node2->m_v - node1->m_v); + btScalar k_damp = psb->m_dampingCoefficient; + btVector3 scaled_force = scale * v_diff * k_damp; + force[id1] += scaled_force; + force[id2] -= scaled_force; + } + } + } + + virtual void addScaledElasticForce(btScalar scale, TVStack& force) + { + int numNodes = getNumNodes(); + btAssert(numNodes == force.size()) + for (int i = 0; i < m_softBodies.size(); ++i) + { + const btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_links.size(); ++j) + { + const auto& link = psb->m_links[j]; + const auto node1 = link.m_n[0]; + const auto node2 = link.m_n[1]; + btScalar kLST = link.Feature::m_material->m_kLST; btScalar r = link.m_rl; size_t id1 = m_indices[node1]; size_t id2 = m_indices[node2]; @@ -39,21 +74,14 @@ public: // elastic force // fully implicit - btVector3 dir = (node2->m_x - node1->m_x); +// btVector3 dir = (node2->m_x - node1->m_x); // explicit elastic force -// btVector3 dir = (node2->m_q - node1->m_q); + btVector3 dir = (node2->m_q - node1->m_q); btVector3 dir_normalized = dir.normalized(); btVector3 scaled_force = scale * kLST * (dir - dir_normalized * r); force[id1] += scaled_force; force[id2] -= scaled_force; - - // damping force - btVector3 v_diff = (node2->m_v - node1->m_v); - btScalar k_damp = psb->m_dampingCoefficient; // TODO: FIX THIS HACK and set k_damp properly - scaled_force = scale * v_diff * k_damp; - force[id1] += scaled_force; - force[id2] -= scaled_force; } } } @@ -64,7 +92,7 @@ public: btAssert(numNodes == dx.size()); btAssert(numNodes == df.size()); - // implicit elastic force + // implicit elastic force differential for (int i = 0; i < m_softBodies.size(); ++i) { const btSoftBody* psb = m_softBodies[i]; @@ -83,9 +111,10 @@ public: } } + virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) { - // implicity damping force + // implicit damping force differential for (int i = 0; i < m_softBodies.size(); ++i) { const btSoftBody* psb = m_softBodies[i]; diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 066072426..974246448 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -1782,7 +1782,7 @@ void btSoftBody::predictMotion(btScalar dt) m_sst.radmrg = getCollisionShape()->getMargin(); m_sst.updmrg = m_sst.radmrg * (btScalar)0.25; /* Forces */ - addVelocity(m_worldInfo->m_gravity * m_sst.sdt); + addVelocity(m_worldInfo->m_gravity * m_sst.sdt); applyForces(); /* Integrate */ for (i = 0, ni = m_nodes.size(); i < ni; ++i) @@ -1805,7 +1805,7 @@ void btSoftBody::predictMotion(btScalar dt) } } } - n.m_v += deltaV; + n.m_v += deltaV; n.m_x += n.m_v * m_sst.sdt; n.m_f = btVector3(0, 0, 0); } @@ -2775,6 +2775,14 @@ void btSoftBody::dampClusters() } } +void btSoftBody::setSpringStiffness(btScalar k) +{ + for (int i = 0; i < m_links.size(); ++i) + { + m_links[i].Feature::m_material->m_kLST = k; + } +} + // void btSoftBody::Joint::Prepare(btScalar dt, int) { diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index 01cde89e3..e8fd3da39 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -1011,6 +1011,7 @@ public: void solveClusters(btScalar sor); void applyClusters(bool drift); void dampClusters(); + void setSpringStiffness(btScalar k); void applyForces(); static void PSolve_Anchors(btSoftBody* psb, btScalar kst, btScalar ti); static void PSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar ti); @@ -1021,7 +1022,7 @@ public: static vsolver_t getSolver(eVSolver::_ solver); virtual int calculateSerializeBufferSize() const; - + ///fills the dataBuffer and returns the struct name (and 0 on failure) virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; From 3430192db798c773036d247a460da520d0c26762 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 18 Jul 2019 09:16:01 -0700 Subject: [PATCH 18/47] reformulate friction --- .../btBackwardEulerObjective.cpp | 2 +- src/BulletSoftBody/btCGProjection.h | 10 ++-- src/BulletSoftBody/btContactProjection.cpp | 51 ++++++++++--------- src/BulletSoftBody/btContactProjection.h | 4 +- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp index 3f27df5a9..9174107ba 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -8,7 +8,7 @@ #include "btBackwardEulerObjective.h" btBackwardEulerObjective::btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) -: cg(20) +: cg(10) , m_softBodies(softBodies) , projection(m_softBodies, m_dt) , m_backupVelocity(backup_v) diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index a00fe384b..46979c8f0 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -43,22 +43,23 @@ struct Friction btAlignedObjectArray m_impulse; btAlignedObjectArray m_dv; btAlignedObjectArray m_direction; + btAlignedObjectArray m_direction_prev; btAlignedObjectArray m_static_prev; btAlignedObjectArray m_impulse_prev; btAlignedObjectArray m_dv_prev; - btAlignedObjectArray m_direction_prev; btAlignedObjectArray m_released; - btAlignedObjectArray m_accumulated_impulse; + btAlignedObjectArray m_accumulated_normal_impulse; + btAlignedObjectArray m_accumulated_tangent_impulse; Friction() { m_static.push_back(false); m_static_prev.push_back(false); - m_direction.push_back(btVector3(0,0,0)); m_direction_prev.push_back(btVector3(0,0,0)); + m_direction.push_back(btVector3(0,0,0)); m_impulse.push_back(0); m_impulse_prev.push_back(0); @@ -66,7 +67,8 @@ struct Friction m_dv.push_back(0); m_dv_prev.push_back(0); - m_accumulated_impulse.push_back(btVector3(0,0,0)); + m_accumulated_normal_impulse.push_back(0); + m_accumulated_tangent_impulse.push_back(btVector3(0,0,0)); m_released.push_back(false); } }; diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 3250e010b..041792d08 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -11,7 +11,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocity) { ///solve rigid body constraints - m_world->getSolverInfo().m_numIterations = 5; + m_world->getSolverInfo().m_numIterations = 10; m_world->btMultiBodyDynamicsWorld::solveConstraints(m_world->getSolverInfo()); // loop through constraints to set constrained values @@ -73,43 +73,44 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit const btVector3 vr = vb - va; const btScalar dn = btDot(vr, cti.m_normal); btVector3 impulse = c->m_c0 * vr; - const btVector3 impulse_normal = c->m_c0 *(cti.m_normal * dn); - btVector3 impulse_tangent = impulse - impulse_normal; - + const btVector3 impulse_normal = c->m_c0 * (cti.m_normal * dn); + const btVector3 impulse_tangent = impulse - impulse_normal; + btScalar local_tangent_norm = impulse_tangent.norm(); + btVector3 local_tangent_dir = btVector3(0,0,0); + if (local_tangent_norm > SIMD_EPSILON) + local_tangent_dir = impulse_tangent.normalized(); // accumulated impulse on the rb in this and all prev cg iterations - friction.m_accumulated_impulse[j] += impulse; - btScalar accumulated_normal = friction.m_accumulated_impulse[j].dot(cti.m_normal); - btVector3 accumulated_tangent = friction.m_accumulated_impulse[j] - accumulated_normal * cti.m_normal; - + friction.m_accumulated_normal_impulse[j] += impulse_normal.dot(cti.m_normal); + btScalar accumulated_normal = friction.m_accumulated_normal_impulse[j]; + btVector3 tangent = friction.m_accumulated_tangent_impulse[j] + impulse_tangent; + btScalar tangent_norm = tangent.norm(); // start friction handling // copy old data - friction.m_direction_prev[j] = friction.m_direction[j]; friction.m_impulse_prev[j] = friction.m_impulse[j]; friction.m_dv_prev[j] = friction.m_dv[j]; friction.m_static_prev[j] = friction.m_static[j]; - if (accumulated_normal < 0 && accumulated_tangent.norm() > SIMD_EPSILON) + if (accumulated_normal < 0 && tangent_norm > SIMD_EPSILON) { - + friction.m_direction[j] = -local_tangent_dir; btScalar compare1 = -accumulated_normal*c->m_c3; - btScalar compare2 = accumulated_tangent.norm(); + btScalar compare2 = tangent_norm; // do not allow switching from static friction to dynamic friction // it causes cg to explode - if (-accumulated_normal*c->m_c3 < accumulated_tangent.norm() && friction.m_static_prev[j] == false && friction.m_released[j] == false) + if (-accumulated_normal*c->m_c3 < tangent_norm && friction.m_static_prev[j] == false && friction.m_released[j] == false) { friction.m_static[j] = false; friction.m_impulse[j] = -accumulated_normal*c->m_c3; - friction.m_dv[j] = -accumulated_normal*c->m_c3 *c->m_c2/m_dt ; + friction.m_dv[j] = 0; + impulse = impulse_normal + (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); } else { friction.m_static[j] = true; - friction.m_impulse[j] = accumulated_tangent.norm(); - friction.m_dv[j] = accumulated_tangent.norm() * c->m_c2/m_dt; + friction.m_impulse[j] = 0; + friction.m_dv[j] = local_tangent_norm * c->m_c2/m_dt; + impulse = impulse_normal + impulse_tangent; } - - const btVector3 tangent_dir = accumulated_tangent.normalized(); - friction.m_direction[j] = -tangent_dir; } else { @@ -117,9 +118,10 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit friction.m_static[j] = false; friction.m_impulse[j] = 0; friction.m_dv[j] = 0; + friction.m_direction[j] = btVector3(0,0,0); + impulse = impulse_normal; } - - friction.m_accumulated_impulse[j] = accumulated_normal * cti.m_normal - friction.m_impulse[j] * friction.m_direction[j]; + friction.m_accumulated_tangent_impulse[j] = -friction.m_impulse[j] * friction.m_direction[j]; if (1) // in the same CG solve, the set of constraits doesn't change // if (dn <= SIMD_EPSILON) { @@ -134,7 +136,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit // the incremental impulse: // in the normal direction it's the normal component of "impulse" // in the tangent direction it's the difference between the frictional impulse in the iteration and the previous iteration - impulse = impulse_normal + (friction.m_impulse_prev[j] * friction.m_direction_prev[j]) - (friction.m_impulse[j] * friction.m_direction[j]); + impulse = impulse_normal + (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); // impulse = impulse_normal; if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { @@ -145,7 +147,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit { if (multibodyLinkCol) { - double multiplier = 0.5; + double multiplier = 1; multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); } } @@ -273,7 +275,8 @@ void btContactProjection::setConstraintDirections() frictions[j].m_dv_prev.push_back(0); frictions[j].m_static.push_back(false); frictions[j].m_static_prev.push_back(false); - frictions[j].m_accumulated_impulse.push_back(btVector3(0,0,0)); + frictions[j].m_accumulated_normal_impulse.push_back(0); + frictions[j].m_accumulated_tangent_impulse.push_back(btVector3(0,0,0)); frictions[j].m_released.push_back(false); merged = true; break; diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index 969745d93..566fd9f92 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -124,7 +124,7 @@ public: // clear the old constraint if (friction.m_static_prev[j] == true) { - x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; +// x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; } // add the new constraint if (friction.m_static[j] == true) @@ -156,7 +156,7 @@ public: // clear the old constraint if (friction.m_static_prev[j] == true) { - x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; +// x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; } // add the new constraint if (friction.m_static[j] == true) From dc10336d45eeaf5d06de4bdabd7df3bc4d990d6f Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 18 Jul 2019 11:34:06 -0700 Subject: [PATCH 19/47] code clean up + check in examples --- examples/BasicDemo/BasicExample.cpp | 6 +- .../DeformableContact/DeformableContact.cpp | 412 ++++++++++++++++++ .../DeformableContact/DeformableContact.h | 20 + examples/DeformableDemo/DeformableDemo.cpp | 90 ++-- examples/ExampleBrowser/ExampleEntries.cpp | 8 +- examples/Pinch/Pinch.cpp | 297 +++++++++++++ examples/Pinch/Pinch.h | 20 + .../VolumetricDeformable.cpp | 294 +++++++++++++ .../VolumetricDeformable.h | 20 + .../btBackwardEulerObjective.cpp | 47 +- src/BulletSoftBody/btBackwardEulerObjective.h | 118 +---- src/BulletSoftBody/btCGProjection.h | 49 ++- src/BulletSoftBody/btConjugateGradient.h | 8 - src/BulletSoftBody/btContactProjection.cpp | 201 +++++++-- src/BulletSoftBody/btContactProjection.h | 160 +------ src/BulletSoftBody/btDeformableBodySolver.cpp | 78 +++- src/BulletSoftBody/btDeformableBodySolver.h | 69 +-- src/BulletSoftBody/btPreconditioner.h | 67 +++ 18 files changed, 1552 insertions(+), 412 deletions(-) create mode 100644 examples/DeformableContact/DeformableContact.cpp create mode 100644 examples/DeformableContact/DeformableContact.h create mode 100644 examples/Pinch/Pinch.cpp create mode 100644 examples/Pinch/Pinch.h create mode 100644 examples/VolumetricDeformable/VolumetricDeformable.cpp create mode 100644 examples/VolumetricDeformable/VolumetricDeformable.h create mode 100644 src/BulletSoftBody/btPreconditioner.h diff --git a/examples/BasicDemo/BasicExample.cpp b/examples/BasicDemo/BasicExample.cpp index 67f670d07..136aefb20 100644 --- a/examples/BasicDemo/BasicExample.cpp +++ b/examples/BasicDemo/BasicExample.cpp @@ -16,9 +16,9 @@ subject to the following restrictions: #include "BasicExample.h" #include "btBulletDynamicsCommon.h" -#define ARRAY_SIZE_Y 5 -#define ARRAY_SIZE_X 5 -#define ARRAY_SIZE_Z 5 +#define ARRAY_SIZE_Y 1 +#define ARRAY_SIZE_X 1 +#define ARRAY_SIZE_Z 1 #include "LinearMath/btVector3.h" #include "LinearMath/btAlignedObjectArray.h" diff --git a/examples/DeformableContact/DeformableContact.cpp b/examples/DeformableContact/DeformableContact.cpp new file mode 100644 index 000000000..b70751e2f --- /dev/null +++ b/examples/DeformableContact/DeformableContact.cpp @@ -0,0 +1,412 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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. +*/ + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_Z 5 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X * ARRAY_SIZE_Y * ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "DeformableContact.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "BulletSoftBody/btDeformableRigidDynamicsWorld.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "BulletSoftBody/btDeformableBodySolver.h" +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h" +#include //printf debugging + +#include "../CommonInterfaces/CommonRigidBodyBase.h" +#include "../Utils/b3ResourcePath.h" +#include "../SoftDemo/BunnyMesh.h" +#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" +#include "BulletDynamics/Featherstone/btMultiBodyJointFeedback.h" + +#include "../CommonInterfaces/CommonMultiBodyBase.h" +#include "../Utils/b3ResourcePath.h" +///The DeformableContact demo deformable bodies self-collision +static bool g_floatingBase = true; +static float friction = 1.; +class DeformableContact : public CommonMultiBodyBase +{ + btMultiBody* m_multiBody; + btAlignedObjectArray m_jointFeedbacks; +public: + + struct TetraBunny + { + #include "../SoftDemo/bunny.inl" + }; + + + DeformableContact(struct GUIHelperInterface* helper) + : CommonMultiBodyBase(helper) + { + } + + virtual ~DeformableContact() + { + } + + void initPhysics(); + + void exitPhysics(); + + void resetCamera() + { + float dist = 15; + float pitch = -30; + float yaw = 100; + float targetPos[3] = {0, -3, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); + } + + virtual void stepSimulation(float deltaTime); + + btMultiBody* createFeatherstoneMultiBody_testMultiDof(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical = false, bool floating = false); + + void addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents); + + + virtual const btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() const + { + return (btDeformableRigidDynamicsWorld*)m_dynamicsWorld; + } + + virtual btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() + { + return (btDeformableRigidDynamicsWorld*)m_dynamicsWorld; + } + + virtual void renderScene() + { + CommonMultiBodyBase::renderScene(); + btDeformableRigidDynamicsWorld* deformableWorld = getDeformableDynamicsWorld(); + + for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++) + { + btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i]; + { + btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags()); + } + } + } +}; + +void DeformableContact::initPhysics() +{ + m_guiHelper->setUpAxis(1); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver(); + btMultiBodyConstraintSolver* sol; + sol = new btMultiBodyConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); + deformableBodySolver->setWorld(getDeformableDynamicsWorld()); + m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); + getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); + + { + ///create a ground + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.))); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, -40, 0)); + groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0)); + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0, 0, 0); + if (isDynamic) + groundShape->calculateLocalInertia(mass, localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(0.5); + + //add the ground to the dynamics world + m_dynamicsWorld->addRigidBody(body,1,1+2); + } + + + { + bool damping = true; + bool gyro = true; + int numLinks = 3; + bool spherical = true; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals + bool canSleep = false; + bool selfCollide = true; + btVector3 linkHalfExtents(1, 1, 1); + btVector3 baseHalfExtents(1, 1, 1); + + btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 10.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase); + + mbC->setCanSleep(canSleep); + mbC->setHasSelfCollision(selfCollide); + mbC->setUseGyroTerm(gyro); + // + if (!damping) + { + mbC->setLinearDamping(0.f); + mbC->setAngularDamping(0.f); + } + else + { + mbC->setLinearDamping(0.1f); + mbC->setAngularDamping(0.9f); + } + + if (numLinks > 0) + { + btScalar q0 = 0.f * SIMD_PI / 180.f; + if (!spherical) + { + mbC->setJointPosMultiDof(0, &q0); + } + else + { + btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0); + quat0.normalize(); + mbC->setJointPosMultiDof(0, quat0); + } + } + /// + addColliders_testMultiDof(mbC, m_dynamicsWorld, baseHalfExtents, linkHalfExtents); + } + + // create a patch of cloth + { + const btScalar s = 6; + btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), + btVector3(+s, 0, -s), + btVector3(-s, 0, +s), + btVector3(+s, 0, +s), + 20,20, + 1 + 2 + 4 + 8, true); + + psb->getCollisionShape()->setMargin(0.25); + psb->generateBendingConstraints(2); + psb->setTotalMass(.5); + psb->setDampingCoefficient(0.01); + psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects + psb->m_cfg.kCHR = 1; // collision hardness with rigid body + psb->m_cfg.kDF = 0; + getDeformableDynamicsWorld()->addSoftBody(psb); + + } + + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); +} + +void DeformableContact::exitPhysics() +{ + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject(obj); + delete obj; + } + + //delete collision shapes + for (int j = 0; j < m_collisionShapes.size(); j++) + { + btCollisionShape* shape = m_collisionShapes[j]; + delete shape; + } + m_collisionShapes.clear(); + + delete m_dynamicsWorld; + + delete m_solver; + + delete m_broadphase; + + delete m_dispatcher; + + delete m_collisionConfiguration; +} + +void DeformableContact::stepSimulation(float deltaTime) +{ +// getDeformableDynamicsWorld()->getMultiBodyDynamicsWorld()->stepSimulation(deltaTime); + m_dynamicsWorld->stepSimulation(deltaTime, 4, 1./240.); +} + + +btMultiBody* DeformableContact::createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating) +{ + //init the base + btVector3 baseInertiaDiag(0.f, 0.f, 0.f); + float baseMass = .05f; + + if (baseMass) + { + btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2])); + pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag); + delete pTempBox; + } + + bool canSleep = false; + + btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep); + + btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f); + pMultiBody->setBasePos(basePosition); + pMultiBody->setWorldToBaseRot(baseOriQuat); + btVector3 vel(0, 0, 0); + // pMultiBody->setBaseVel(vel); + + //init the links + btVector3 hingeJointAxis(1, 0, 0); + float linkMass = .05f; + btVector3 linkInertiaDiag(0.f, 0.f, 0.f); + + btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2])); + pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag); + delete pTempBox; + + //y-axis assumed up + btVector3 parentComToCurrentCom(0, -linkHalfExtents[1] * 2.f, 0); //par body's COM to cur body's COM offset + btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1], 0); //cur body's COM to cur body's PIV offset + btVector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; //par body's COM to cur body's PIV offset + + ////// + btScalar q0 = 0.f * SIMD_PI / 180.f; + btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0); + quat0.normalize(); + ///// + + for (int i = 0; i < numLinks; ++i) + { + if (!spherical) + pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, true); + else + //pMultiBody->setupPlanar(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f)/*quat0*/, btVector3(1, 0, 0), parentComToCurrentPivot*2, false); + pMultiBody->setupSpherical(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), parentComToCurrentPivot, currentPivotToCurrentCom, true); + } + + pMultiBody->finalizeMultiDof(); + + /// + pWorld->addMultiBody(pMultiBody); + /// + return pMultiBody; +} + +void DeformableContact::addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents) +{ + btAlignedObjectArray world_to_local; + world_to_local.resize(pMultiBody->getNumLinks() + 1); + + btAlignedObjectArray local_origin; + local_origin.resize(pMultiBody->getNumLinks() + 1); + world_to_local[0] = pMultiBody->getWorldToBaseRot(); + local_origin[0] = pMultiBody->getBasePos(); + + { + // float pos[4]={local_origin[0].x(),local_origin[0].y(),local_origin[0].z(),1}; + btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()}; + + if (1) + { + btCollisionShape* box = new btBoxShape(baseHalfExtents); + btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1); + col->setCollisionShape(box); + + btTransform tr; + tr.setIdentity(); + tr.setOrigin(local_origin[0]); + tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3])); + col->setWorldTransform(tr); + + pWorld->addCollisionObject(col, 2, 1 + 2); + + col->setFriction(friction); + pMultiBody->setBaseCollider(col); + } + } + + for (int i = 0; i < pMultiBody->getNumLinks(); ++i) + { + const int parent = pMultiBody->getParent(i); + world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1]; + local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i))); + } + + for (int i = 0; i < pMultiBody->getNumLinks(); ++i) + { + btVector3 posr = local_origin[i + 1]; + // float pos[4]={posr.x(),posr.y(),posr.z(),1}; + + btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()}; + + btCollisionShape* box = new btBoxShape(linkHalfExtents); + btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i); + + col->setCollisionShape(box); + btTransform tr; + tr.setIdentity(); + tr.setOrigin(posr); + tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3])); + col->setWorldTransform(tr); + col->setFriction(friction); + pWorld->addCollisionObject(col, 2, 1 + 2); + + pMultiBody->getLink(i).m_collider = col; + } +} +class CommonExampleInterface* DeformableContactCreateFunc(struct CommonExampleOptions& options) +{ + return new DeformableContact(options.m_guiHelper); +} + + diff --git a/examples/DeformableContact/DeformableContact.h b/examples/DeformableContact/DeformableContact.h new file mode 100644 index 000000000..591c6bab1 --- /dev/null +++ b/examples/DeformableContact/DeformableContact.h @@ -0,0 +1,20 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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 _DEFORMABLE_CONTACT_H +#define _DEFORMABLE_CONTACT_H + +class CommonExampleInterface* DeformableContactCreateFunc(struct CommonExampleOptions& options); + +#endif //_DEFORMABLE_CONTACT_H diff --git a/examples/DeformableDemo/DeformableDemo.cpp b/examples/DeformableDemo/DeformableDemo.cpp index 990bdd7b9..7ce94a314 100644 --- a/examples/DeformableDemo/DeformableDemo.cpp +++ b/examples/DeformableDemo/DeformableDemo.cpp @@ -35,6 +35,7 @@ subject to the following restrictions: #include "BulletSoftBody/btSoftBodyHelpers.h" #include "BulletSoftBody/btDeformableBodySolver.h" #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h" #include //printf debugging #include "../CommonInterfaces/CommonRigidBodyBase.h" @@ -59,17 +60,23 @@ public: void resetCamera() { - float dist = 15; + float dist = 20; float pitch = -45; float yaw = 100; - float targetPos[3] = {0, -5, 0}; + float targetPos[3] = {0, -3, 0}; m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } + void stepSimulation(float deltaTime) + { + //use a smaller internal timestep, there are stability issues + float internalTimeStep = 1. / 240.f; + m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep); + } void Ctor_RbUpStack(int count) { - float mass = 1; + float mass = 0.2; btCompoundShape* cylinderCompound = new btCompoundShape; btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(2, .5, .5)); @@ -84,18 +91,30 @@ public: btCollisionShape* shape[] = { new btBoxShape(btVector3(1, 1, 1)), - cylinderCompound, - new btSphereShape(0.75) - +// new btSphereShape(0.75), +// cylinderCompound }; - static const int nshapes = sizeof(shape) / sizeof(shape[0]); - for (int i = 0; i < count; ++i) - { - btTransform startTransform; - startTransform.setIdentity(); - startTransform.setOrigin(btVector3(0, 3 + 3 * i, 0)); - createRigidBody(mass, startTransform, shape[i % nshapes]); - } +// static const int nshapes = sizeof(shape) / sizeof(shape[0]); +// for (int i = 0; i < count; ++i) +// { +// btTransform startTransform; +// startTransform.setIdentity(); +// startTransform.setOrigin(btVector3(0, 2+ 2 * i, 0)); +// startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.)); +// createRigidBody(mass, startTransform, shape[i % nshapes]); +// } + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(1, 2, 1)); + createRigidBody(mass, startTransform, shape[0]); + startTransform.setOrigin(btVector3(1, 2, -1)); + createRigidBody(mass, startTransform, shape[0]); + startTransform.setOrigin(btVector3(-1, 2, 1)); + createRigidBody(mass, startTransform, shape[0]); + startTransform.setOrigin(btVector3(-1, 2, -1)); + createRigidBody(mass, startTransform, shape[0]); + startTransform.setOrigin(btVector3(0, 4, 0)); + createRigidBody(mass, startTransform, shape[0]); } virtual const btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() const @@ -143,14 +162,16 @@ void DeformableDemo::initPhysics() btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) - btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + btMultiBodyConstraintSolver* sol = new btMultiBodyConstraintSolver(); m_solver = sol; - m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration, deformableBodySolver); + m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); deformableBodySolver->setWorld(getDeformableDynamicsWorld()); // m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); - getDeformableDynamicsWorld()->getSoftDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + +// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); { @@ -161,8 +182,8 @@ void DeformableDemo::initPhysics() btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0, -50, 0)); - groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0)); + groundTransform.setOrigin(btVector3(0, -30, 0)); + groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: btScalar mass(0.); @@ -177,7 +198,7 @@ void DeformableDemo::initPhysics() btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); - body->setFriction(.5); + body->setFriction(1); //add the ground to the dynamics world m_dynamicsWorld->addRigidBody(body); @@ -185,24 +206,37 @@ void DeformableDemo::initPhysics() // create a piece of cloth { + bool onGround = true; const btScalar s = 4; - btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getSoftDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), + btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), btVector3(+s, 0, -s), btVector3(-s, 0, +s), btVector3(+s, 0, +s), -// 3, 3, - 20,20, +// 3,3, + 20,20, 1 + 2 + 4 + 8, true); -// 0, true); +// 0, true); + + if (onGround) + psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), + btVector3(+s, 0, -s), + btVector3(-s, 0, +s), + btVector3(+s, 0, +s), + 20,20, + 0, true); - psb->getCollisionShape()->setMargin(0.25); + psb->getCollisionShape()->setMargin(0.1); psb->generateBendingConstraints(2); - psb->setTotalMass(2); - psb->setDampingCoefficient(0.02); + psb->setTotalMass(10); + psb->setSpringStiffness(10); + psb->setDampingCoefficient(0.01); + psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects + psb->m_cfg.kCHR = 1; // collision hardness with rigid body + psb->m_cfg.kDF = 1; getDeformableDynamicsWorld()->addSoftBody(psb); // add a few rigid bodies - Ctor_RbUpStack(10); + Ctor_RbUpStack(1); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp index 6d3db549e..f29cef2ba 100644 --- a/examples/ExampleBrowser/ExampleEntries.cpp +++ b/examples/ExampleBrowser/ExampleEntries.cpp @@ -48,6 +48,9 @@ #include "../DynamicControlDemo/MotorDemo.h" #include "../RollingFrictionDemo/RollingFrictionDemo.h" #include "../DeformableDemo/DeformableDemo.h" +#include "../Pinch/Pinch.h" +#include "../DeformableContact/DeformableContact.h" +#include "../VolumetricDeformable/VolumetricDeformable.h" #include "../SharedMemory/PhysicsServerExampleBullet2.h" #include "../SharedMemory/PhysicsServerExample.h" #include "../SharedMemory/PhysicsClientExample.h" @@ -119,7 +122,10 @@ static ExampleEntry gDefaultExamples[] = ExampleEntry(1, "Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc), - ExampleEntry(0, "Deformable", "Deformable test", DeformableCreateFunc), + ExampleEntry(0, "Deformable-RigidBody Contact", "Deformable test", DeformableCreateFunc), + ExampleEntry(0, "Grasp Deformable Cube", "Grasping test", PinchCreateFunc), + ExampleEntry(0, "Volumetric Deformable Objects", "Volumetric Deformable test", VolumetricDeformableCreateFunc), + ExampleEntry(0, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableContactCreateFunc), ExampleEntry(1, "Constraints", "Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.", AllConstraintCreateFunc), diff --git a/examples/Pinch/Pinch.cpp b/examples/Pinch/Pinch.cpp new file mode 100644 index 000000000..cedc51750 --- /dev/null +++ b/examples/Pinch/Pinch.cpp @@ -0,0 +1,297 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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. +*/ + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_Z 5 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X * ARRAY_SIZE_Y * ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "Pinch.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "BulletSoftBody/btDeformableRigidDynamicsWorld.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "BulletSoftBody/btDeformableBodySolver.h" +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h" +#include //printf debugging + +#include "../CommonInterfaces/CommonRigidBodyBase.h" +#include "../Utils/b3ResourcePath.h" + +///The Pinch shows the use of rolling friction. +///Spheres will come to a rest on a sloped plane using a constraint. Damping cannot achieve the same. +///Generally it is best to leave the rolling friction coefficient zero (or close to zero). + +struct TetraCube +{ +#include "../SoftDemo/cube.inl" +}; + +struct TetraBunny +{ +#include "../SoftDemo/bunny.inl" +}; + + +class Pinch : public CommonRigidBodyBase +{ +public: + Pinch(struct GUIHelperInterface* helper) + : CommonRigidBodyBase(helper) + { + } + virtual ~Pinch() + { + } + void initPhysics(); + + void exitPhysics(); + + void resetCamera() + { + float dist = 25; + float pitch = -45; + float yaw = 100; + float targetPos[3] = {0, -3, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); + } + + void stepSimulation(float deltaTime) + { + //use a smaller internal timestep, there are stability issues + float internalTimeStep = 1. / 240.f; + m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep); + } + + void createGrip() + { + int count = 2; + float mass = 2; + btCollisionShape* shape[] = { + new btBoxShape(btVector3(3, 3, 0.5)), + }; + static const int nshapes = sizeof(shape) / sizeof(shape[0]); + for (int i = 0; i < count; ++i) + { + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(10, 0, 0)); + startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.)); + createRigidBody(mass, startTransform, shape[i % nshapes]); + } + } + + virtual const btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() const + { + return (btDeformableRigidDynamicsWorld*)m_dynamicsWorld; + } + + virtual btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() + { + return (btDeformableRigidDynamicsWorld*)m_dynamicsWorld; + } + + virtual void renderScene() + { + CommonRigidBodyBase::renderScene(); + btDeformableRigidDynamicsWorld* deformableWorld = getDeformableDynamicsWorld(); + + for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++) + { + btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i]; + { + btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags()); + } + } + } +}; + +void dynamics(btScalar time, btDeformableRigidDynamicsWorld* world) +{ + btAlignedObjectArray& rbs = world->getNonStaticRigidBodies(); + if (rbs.size()<2) + return; + btRigidBody* rb0 = rbs[0]; + btScalar pressTime = 0.9; + btTransform rbTransform; + rbTransform.setIdentity(); + btVector3 translation = btVector3(0.5,3,4); + btVector3 velocity = btVector3(0,5,0); + if (time < pressTime) + { + velocity = btVector3(0,0,-2); + translation += velocity * time; + } + else + translation += btVector3(0,0,-2) * pressTime + (time-pressTime)*velocity; + rbTransform.setOrigin(translation); + rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0)); + rb0->setCenterOfMassTransform(rbTransform); + rb0->setAngularVelocity(btVector3(0,0,0)); + rb0->setLinearVelocity(velocity); + + btRigidBody* rb1 = rbs[1]; + translation = btVector3(0.5,3,-4); + velocity = btVector3(0,5,0); + if (time < pressTime) + { + velocity = btVector3(0,0,2); + translation += velocity * time; + } + else + translation += btVector3(0,0,2) * pressTime + (time-pressTime)*velocity; + rbTransform.setOrigin(translation); + rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0)); + rb1->setCenterOfMassTransform(rbTransform); + rb1->setAngularVelocity(btVector3(0,0,0)); + rb1->setLinearVelocity(velocity); + + rb0->setFriction(2); + rb1->setFriction(2); +} + +void Pinch::initPhysics() +{ + m_guiHelper->setUpAxis(1); + + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver(); + + btMultiBodyConstraintSolver* sol = new btMultiBodyConstraintSolver(); + m_solver = sol; + + m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); + deformableBodySolver->setWorld(getDeformableDynamicsWorld()); + // m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality + m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); + getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + + getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics); + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); + + //create a ground + { + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.))); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, -25, 0)); + groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0)); + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0, 0, 0); + if (isDynamic) + groundShape->calculateLocalInertia(mass, localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(0.5); + + //add the ground to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + // create a soft block + { + btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(), + TetraCube::getElements(), + 0, + TetraCube::getNodes(), + false, true, true); + getDeformableDynamicsWorld()->addSoftBody(psb); + psb->scale(btVector3(2, 2, 2)); + psb->translate(btVector3(0, 4, 0)); + psb->getCollisionShape()->setMargin(0.1); + psb->setTotalMass(1); + psb->setSpringStiffness(10); + psb->setDampingCoefficient(0.01); + psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects + psb->m_cfg.kCHR = 1; // collision hardness with rigid body + psb->m_cfg.kDF = 0.5; + // add a grippers + createGrip(); + } + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); +} + +void Pinch::exitPhysics() +{ + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject(obj); + delete obj; + } + + //delete collision shapes + for (int j = 0; j < m_collisionShapes.size(); j++) + { + btCollisionShape* shape = m_collisionShapes[j]; + delete shape; + } + m_collisionShapes.clear(); + + delete m_dynamicsWorld; + + delete m_solver; + + delete m_broadphase; + + delete m_dispatcher; + + delete m_collisionConfiguration; +} + + + +class CommonExampleInterface* PinchCreateFunc(struct CommonExampleOptions& options) +{ + return new Pinch(options.m_guiHelper); +} + + diff --git a/examples/Pinch/Pinch.h b/examples/Pinch/Pinch.h new file mode 100644 index 000000000..6c7e2fb3c --- /dev/null +++ b/examples/Pinch/Pinch.h @@ -0,0 +1,20 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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 _PINCH_H +#define _PINCH_H + +class CommonExampleInterface* PinchCreateFunc(struct CommonExampleOptions& options); + +#endif //_PINCH_H diff --git a/examples/VolumetricDeformable/VolumetricDeformable.cpp b/examples/VolumetricDeformable/VolumetricDeformable.cpp new file mode 100644 index 000000000..b30e9bc24 --- /dev/null +++ b/examples/VolumetricDeformable/VolumetricDeformable.cpp @@ -0,0 +1,294 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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. +*/ + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_Z 5 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X * ARRAY_SIZE_Y * ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "VolumetricDeformable.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "BulletSoftBody/btDeformableRigidDynamicsWorld.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "BulletSoftBody/btDeformableBodySolver.h" +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h" +#include //printf debugging + +#include "../CommonInterfaces/CommonRigidBodyBase.h" +#include "../Utils/b3ResourcePath.h" + +///The VolumetricDeformable shows the use of rolling friction. +///Spheres will come to a rest on a sloped plane using a constraint. Damping cannot achieve the same. +///Generally it is best to leave the rolling friction coefficient zero (or close to zero). + + +struct TetraCube +{ +#include "../SoftDemo/cube.inl" +}; + +class VolumetricDeformable : public CommonRigidBodyBase +{ +public: + VolumetricDeformable(struct GUIHelperInterface* helper) + : CommonRigidBodyBase(helper) + { + } + virtual ~VolumetricDeformable() + { + } + void initPhysics(); + + void exitPhysics(); + + void resetCamera() + { + float dist = 20; + float pitch = -45; + float yaw = 100; + float targetPos[3] = {0, 3, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); + } + + void stepSimulation(float deltaTime) + { + //use a smaller internal timestep, there are stability issues + float internalTimeStep = 1. / 240.f; + m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep); + } + + void createStaticBox(const btVector3& halfEdge, const btVector3& translation) + { + btCollisionShape* box = new btBoxShape(halfEdge); + m_collisionShapes.push_back(box); + + btTransform Transform; + Transform.setIdentity(); + Transform.setOrigin(translation); + Transform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0)); + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + btScalar mass(0.); + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + btVector3 localInertia(0, 0, 0); + if (isDynamic) + box->calculateLocalInertia(mass, localInertia); + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(Transform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, box, localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(0.5); + + //add the ground to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + void Ctor_RbUpStack(int count) + { + float mass = 0.02; + + btCompoundShape* cylinderCompound = new btCompoundShape; + btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(2, .5, .5)); + btCollisionShape* boxShape = new btBoxShape(btVector3(2, .5, .5)); + btTransform localTransform; + localTransform.setIdentity(); + cylinderCompound->addChildShape(localTransform, boxShape); + btQuaternion orn(SIMD_HALF_PI, 0, 0); + localTransform.setRotation(orn); + // localTransform.setOrigin(btVector3(1,1,1)); + cylinderCompound->addChildShape(localTransform, cylinderShape); + + btCollisionShape* shape[] = { + new btBoxShape(btVector3(1, 1, 1)), + }; + static const int nshapes = sizeof(shape) / sizeof(shape[0]); + for (int i = 0; i < count; ++i) + { + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(i, 10 + 2 * i, i-1)); + createRigidBody(mass, startTransform, shape[i % nshapes]); + } + } + + virtual const btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() const + { + ///just make it a btSoftRigidDynamicsWorld please + ///or we will add type checking + return (btDeformableRigidDynamicsWorld*)m_dynamicsWorld; + } + + virtual btDeformableRigidDynamicsWorld* getDeformableDynamicsWorld() + { + ///just make it a btSoftRigidDynamicsWorld please + ///or we will add type checking + return (btDeformableRigidDynamicsWorld*)m_dynamicsWorld; + } + + virtual void renderScene() + { + CommonRigidBodyBase::renderScene(); + btDeformableRigidDynamicsWorld* deformableWorld = getDeformableDynamicsWorld(); + + for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++) + { + btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i]; + //if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) + { + btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags()); + } + } + } +}; + +void VolumetricDeformable::initPhysics() +{ + m_guiHelper->setUpAxis(1); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver(); + + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btMultiBodyConstraintSolver* sol = new btMultiBodyConstraintSolver(); + m_solver = sol; + + m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); + deformableBodySolver->setWorld(getDeformableDynamicsWorld()); + // m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality + m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); + getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); + + { + ///create a ground + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(50.), btScalar(150.))); + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, -50, 0)); + groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0)); + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + btScalar mass(0.); + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + btVector3 localInertia(0, 0, 0); + if (isDynamic) + groundShape->calculateLocalInertia(mass, localInertia); + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(0.5); + + //add the ground to the dynamics world + m_dynamicsWorld->addRigidBody(body); + } + + createStaticBox(btVector3(1, 5, 5), btVector3(-5,0,0)); + createStaticBox(btVector3(1, 5, 5), btVector3(5,0,0)); + createStaticBox(btVector3(5, 5, 1), btVector3(0,0,5)); + createStaticBox(btVector3(5, 5, 1), btVector3(0,0,-5)); + + // create volumetric soft body + { + btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(), + TetraCube::getElements(), + 0, + TetraCube::getNodes(), + false, true, true); + getDeformableDynamicsWorld()->addSoftBody(psb); + psb->scale(btVector3(2, 2, 2)); + psb->translate(btVector3(0, 5, 0)); +// psb->setVolumeMass(10); + psb->getCollisionShape()->setMargin(0.25); +// psb->generateBendingConstraints(2); + psb->setTotalMass(1); + psb->setSpringStiffness(1); + psb->setDampingCoefficient(0.01); + psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects + psb->m_cfg.kCHR = 1; // collision hardness with rigid body + psb->m_cfg.kDF = 0.5; + } + // add a few rigid bodies + Ctor_RbUpStack(4); + + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); +} + +void VolumetricDeformable::exitPhysics() +{ + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject(obj); + delete obj; + } + + //delete collision shapes + for (int j = 0; j < m_collisionShapes.size(); j++) + { + btCollisionShape* shape = m_collisionShapes[j]; + delete shape; + } + m_collisionShapes.clear(); + + delete m_dynamicsWorld; + + delete m_solver; + + delete m_broadphase; + + delete m_dispatcher; + + delete m_collisionConfiguration; +} + + + +class CommonExampleInterface* VolumetricDeformableCreateFunc(struct CommonExampleOptions& options) +{ + return new VolumetricDeformable(options.m_guiHelper); +} + + diff --git a/examples/VolumetricDeformable/VolumetricDeformable.h b/examples/VolumetricDeformable/VolumetricDeformable.h new file mode 100644 index 000000000..af1cc38b6 --- /dev/null +++ b/examples/VolumetricDeformable/VolumetricDeformable.h @@ -0,0 +1,20 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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 _VOLUMETRIC_DEFORMABLE_H +#define _VOLUMETRIC_DEFORMABLE_H + +class CommonExampleInterface* VolumetricDeformableCreateFunc(struct CommonExampleOptions& options); + +#endif //_VOLUMETRIC_DEFORMABLE__H diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btBackwardEulerObjective.cpp index 9174107ba..024cc66b6 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btBackwardEulerObjective.cpp @@ -77,6 +77,51 @@ void btBackwardEulerObjective::updateVelocity(const TVStack& dv) } } +void btBackwardEulerObjective::applyForce(TVStack& force, bool setZero) +{ + size_t counter = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + btScalar one_over_mass = (psb->m_nodes[j].m_im == 0) ? 0 : psb->m_nodes[j].m_im; + psb->m_nodes[j].m_v += one_over_mass * force[counter++]; + } + } + if (setZero) + { + for (int i = 0; i < force.size(); ++i) + force[i].setZero(); + } +} + +void btBackwardEulerObjective::computeResidual(btScalar dt, TVStack &residual) const +{ + // add implicit force + for (int i = 0; i < m_lf.size(); ++i) + { + m_lf[i]->addScaledImplicitForce(dt, residual); + } +} + +btScalar btBackwardEulerObjective::computeNorm(const TVStack& residual) const +{ + btScalar norm_squared = 0; + for (int i = 0; i < residual.size(); ++i) + { + norm_squared += residual[i].length2(); + } + return std::sqrt(norm_squared+SIMD_EPSILON); +} + +void btBackwardEulerObjective::applyExplicitForce(TVStack& force) +{ + for (int i = 0; i < m_lf.size(); ++i) + m_lf[i]->addScaledExplicitForce(m_dt, force); + applyForce(force, true); +} + void btBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack& residual) { size_t counter = 0; @@ -85,7 +130,7 @@ void btBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack& residual btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { - dv[counter] = psb->m_nodes[j].m_im * residual[counter] * 1; + dv[counter] = psb->m_nodes[j].m_im * residual[counter]; ++counter; } } diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h index e9642f6ae..68f7f66fe 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -12,66 +12,10 @@ #include "btLagrangianForce.h" #include "btMassSpring.h" #include "btContactProjection.h" +#include "btPreconditioner.h" #include "btDeformableRigidDynamicsWorld.h" class btDeformableRigidDynamicsWorld; - -class Preconditioner -{ -public: - using TVStack = btAlignedObjectArray; - virtual void operator()(const TVStack& x, TVStack& b) = 0; - virtual void reinitialize(bool nodeUpdated) = 0; -}; - -class DefaultPreconditioner : public Preconditioner -{ -public: - virtual void operator()(const TVStack& x, TVStack& b) - { - btAssert(b.size() == x.size()); - for (int i = 0; i < b.size(); ++i) - b[i] = x[i]; - } - virtual void reinitialize(bool nodeUpdated) - { - - } -}; - -class MassPreconditioner : public Preconditioner -{ - btAlignedObjectArray m_inv_mass; - const btAlignedObjectArray& m_softBodies; -public: - MassPreconditioner(const btAlignedObjectArray& softBodies) - : m_softBodies(softBodies) - { - } - - virtual void reinitialize(bool nodeUpdated) - { - if (nodeUpdated) - { - m_inv_mass.clear(); - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - m_inv_mass.push_back(psb->m_nodes[j].m_im); - } - } - } - - virtual void operator()(const TVStack& x, TVStack& b) - { - btAssert(b.size() == x.size()); - btAssert(m_inv_mass.size() == x.size()); - for (int i = 0; i < b.size(); ++i) - b[i] = x[i] * m_inv_mass[i]; - } -}; - class btBackwardEulerObjective { public: @@ -91,74 +35,60 @@ public: void initialize(){} - void computeResidual(btScalar dt, TVStack& residual) const - { - // add implicit force - for (int i = 0; i < m_lf.size(); ++i) - { - m_lf[i]->addScaledImplicitForce(dt, residual); - } - } + // compute the rhs for CG solve, i.e, add the dt scaled implicit force to residual + void computeResidual(btScalar dt, TVStack& residual) const; - void applyExplicitForce(TVStack& force) - { - for (int i = 0; i < m_lf.size(); ++i) - m_lf[i]->addScaledExplicitForce(m_dt, force); - - size_t counter = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - btScalar one_over_mass = (psb->m_nodes[j].m_im == 0) ? 0 : psb->m_nodes[j].m_im; - psb->m_nodes[j].m_v += one_over_mass * force[counter]; - force[counter].setZero(); - counter++; - } - } - } + // add explicit force to the velocity + void applyExplicitForce(TVStack& force); - btScalar computeNorm(const TVStack& residual) const - { - btScalar norm_squared = 0; - for (int i = 0; i < residual.size(); ++i) - { - norm_squared += residual[i].length2(); - } - return std::sqrt(norm_squared+SIMD_EPSILON); - } + // apply force to velocity and optionally reset the force to zero + void applyForce(TVStack& force, bool setZero); + // compute the norm of the residual + btScalar computeNorm(const TVStack& residual) const; + + // compute one step of the solve (there is only one solve if the system is linear) void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt); + // perform A*x = b void multiply(const TVStack& x, TVStack& b) const; + // update the constraints treated as projections void updateProjection(const TVStack& dv) { projection.update(dv, m_backupVelocity); } + + // set initial guess for CG solve void initialGuess(TVStack& dv, const TVStack& residual); + // reset data structure void reinitialize(bool nodeUpdated); + // enforce constraints in CG solve void enforceConstraint(TVStack& x) { projection.enforceConstraint(x); updateVelocity(x); } + // add dv to velocity void updateVelocity(const TVStack& dv); - void setConstraintDirections() + //set constraints as projections + void setConstraints() { - projection.setConstraintDirections(); + projection.setConstraints(); } + + // update the projections and project the residual void project(TVStack& r, const TVStack& dv) { updateProjection(dv); projection(r); } + // perform precondition M^(-1) x = b void precondition(const TVStack& x, TVStack& b) { m_preconditioner->operator()(x,b); diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 46979c8f0..ff5eecd8c 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -17,12 +17,12 @@ struct Constraint btAlignedObjectArray m_contact; btAlignedObjectArray m_direction; btAlignedObjectArray m_value; + // the magnitude of the total impulse the node applied to the rb in the normal direction in the cg solve + btAlignedObjectArray m_accumulated_normal_impulse; Constraint(const btSoftBody::RContact& rcontact) { - m_contact.push_back(&rcontact); - m_direction.push_back(rcontact.m_cti.m_normal); - m_value.push_back(0); + append(rcontact); } Constraint(const btVector3 dir) @@ -30,30 +30,56 @@ struct Constraint m_contact.push_back(nullptr); m_direction.push_back(dir); m_value.push_back(0); + m_accumulated_normal_impulse.push_back(0); } Constraint() + { + m_contact.push_back(nullptr); + m_direction.push_back(btVector3(0,0,0)); + m_value.push_back(0); + m_accumulated_normal_impulse.push_back(0); + } + + void append(const btSoftBody::RContact& rcontact) + { + m_contact.push_back(&rcontact); + m_direction.push_back(rcontact.m_cti.m_normal); + m_value.push_back(0); + m_accumulated_normal_impulse.push_back(0); + } + + ~Constraint() { } }; struct Friction { - btAlignedObjectArray m_static; - btAlignedObjectArray m_impulse; - btAlignedObjectArray m_dv; - btAlignedObjectArray m_direction; - btAlignedObjectArray m_direction_prev; + + btAlignedObjectArray m_static; // whether the friction is static + btAlignedObjectArray m_impulse; // the impulse magnitude the node feels + btAlignedObjectArray m_dv; // the dv magnitude of the node + btAlignedObjectArray m_direction; // the direction of the friction for the node + btAlignedObjectArray m_static_prev; btAlignedObjectArray m_impulse_prev; btAlignedObjectArray m_dv_prev; + btAlignedObjectArray m_direction_prev; - btAlignedObjectArray m_released; + btAlignedObjectArray m_released; // whether the contact is released - btAlignedObjectArray m_accumulated_normal_impulse; + + + // the total impulse the node applied to the rb in the tangential direction in the cg solve btAlignedObjectArray m_accumulated_tangent_impulse; Friction() + { + append(); + } + + void append() { m_static.push_back(false); m_static_prev.push_back(false); @@ -67,7 +93,6 @@ struct Friction m_dv.push_back(0); m_dv_prev.push_back(0); - m_accumulated_normal_impulse.push_back(0); m_accumulated_tangent_impulse.push_back(btVector3(0,0,0)); m_released.push_back(false); } @@ -100,7 +125,7 @@ public: // apply the constraints virtual void operator()(TVStack& x) = 0; - virtual void setConstraintDirections() = 0; + virtual void setConstraints() = 0; // update the constraints virtual void update(const TVStack& dv, const TVStack& backup_v) = 0; diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index a2b69f48d..f23b26385 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -18,12 +18,10 @@ class btConjugateGradient using TVStack = btAlignedObjectArray; TVStack r,p,z,temp; int max_iterations; - btScalar tolerance; public: btConjugateGradient(const int max_it_in) : max_iterations(max_it_in) - , tolerance(std::numeric_limits::epsilon() * 16) { } @@ -121,12 +119,6 @@ public: return ans; } - void setZero(TVStack& a) - { - for (int i = 0; i < a.size(); ++i) - a[i].setZero(); - } - void multAndAddTo(btScalar s, const TVStack& a, TVStack& result) { // result += s*a diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 041792d08..cf2e05e59 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -61,9 +61,9 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); btScalar vel = 0.0; - for (int j = 0; j < ndof; ++j) + for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac[k]; } va = cti.m_normal * vel * m_dt; } @@ -75,41 +75,41 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit btVector3 impulse = c->m_c0 * vr; const btVector3 impulse_normal = c->m_c0 * (cti.m_normal * dn); const btVector3 impulse_tangent = impulse - impulse_normal; + + // start friction handling + // copy old data + friction.m_impulse_prev[j] = friction.m_impulse[j]; + friction.m_dv_prev[j] = friction.m_dv[j]; + friction.m_static_prev[j] = friction.m_static[j]; + + // get the current tangent direction btScalar local_tangent_norm = impulse_tangent.norm(); btVector3 local_tangent_dir = btVector3(0,0,0); if (local_tangent_norm > SIMD_EPSILON) local_tangent_dir = impulse_tangent.normalized(); // accumulated impulse on the rb in this and all prev cg iterations - friction.m_accumulated_normal_impulse[j] += impulse_normal.dot(cti.m_normal); - btScalar accumulated_normal = friction.m_accumulated_normal_impulse[j]; + constraint.m_accumulated_normal_impulse[j] += impulse_normal.dot(cti.m_normal); + const btScalar& accumulated_normal = constraint.m_accumulated_normal_impulse[j]; + + // the total tangential impulse required to stop sliding btVector3 tangent = friction.m_accumulated_tangent_impulse[j] + impulse_tangent; btScalar tangent_norm = tangent.norm(); - // start friction handling - // copy old data - friction.m_impulse_prev[j] = friction.m_impulse[j]; - friction.m_dv_prev[j] = friction.m_dv[j]; - friction.m_static_prev[j] = friction.m_static[j]; - if (accumulated_normal < 0 && tangent_norm > SIMD_EPSILON) + + if (accumulated_normal < 0) { friction.m_direction[j] = -local_tangent_dir; - btScalar compare1 = -accumulated_normal*c->m_c3; - btScalar compare2 = tangent_norm; // do not allow switching from static friction to dynamic friction // it causes cg to explode if (-accumulated_normal*c->m_c3 < tangent_norm && friction.m_static_prev[j] == false && friction.m_released[j] == false) { friction.m_static[j] = false; friction.m_impulse[j] = -accumulated_normal*c->m_c3; - friction.m_dv[j] = 0; - impulse = impulse_normal + (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); } else { friction.m_static[j] = true; - friction.m_impulse[j] = 0; - friction.m_dv[j] = local_tangent_norm * c->m_c2/m_dt; - impulse = impulse_normal + impulse_tangent; + friction.m_impulse[j] = local_tangent_norm; } } else @@ -117,27 +117,29 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit friction.m_released[j] = true; friction.m_static[j] = false; friction.m_impulse[j] = 0; - friction.m_dv[j] = 0; friction.m_direction[j] = btVector3(0,0,0); - impulse = impulse_normal; } + friction.m_dv[j] = friction.m_impulse[j] * c->m_c2/m_dt; friction.m_accumulated_tangent_impulse[j] = -friction.m_impulse[j] * friction.m_direction[j]; + + // the incremental impulse applied to rb in the tangential direction + btVector3 incremental_tangent = (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); + if (1) // in the same CG solve, the set of constraits doesn't change -// if (dn <= SIMD_EPSILON) { // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient // dv = new_impulse + accumulated velocity change in previous CG iterations // so we have the invariant node->m_v = backupVelocity + dv; - btVector3 dv = -impulse * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; - btScalar dvn = dv.dot(cti.m_normal); +// btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; +// btScalar dvn = dv.dot(cti.m_normal); + btScalar dvn = -accumulated_normal * c->m_c2/m_dt; constraint.m_value[j] = dvn; // the incremental impulse: // in the normal direction it's the normal component of "impulse" // in the tangent direction it's the difference between the frictional impulse in the iteration and the previous iteration - impulse = impulse_normal + (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); -// impulse = impulse_normal; + impulse = impulse_normal + incremental_tangent; if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { if (rigidCol) @@ -147,7 +149,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit { if (multibodyLinkCol) { - double multiplier = 1; + double multiplier = 0.5; multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); } } @@ -158,8 +160,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit } } - -void btContactProjection::setConstraintDirections() +void btContactProjection::setConstraints() { // set Dirichlet constraint for (int i = 0; i < m_softBodies.size(); ++i) @@ -188,6 +189,7 @@ void btContactProjection::setConstraintDirections() { btSoftBody* psb = m_softBodies[i]; btMultiBodyJacobianData jacobianData; + btAlignedObjectArray jacobian; for (int j = 0; j < psb->m_rcontacts.size(); ++j) { @@ -214,6 +216,7 @@ void btContactProjection::setConstraintDirections() } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { + jacobian.clear(); multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); if (multibodyLinkCol) { @@ -227,9 +230,11 @@ void btContactProjection::setConstraintDirections() multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); btScalar vel = 0.0; + jacobian.resize(ndof); for (int j = 0; j < ndof; ++j) { vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + jacobian[j] = jac[j]; } va = cti.m_normal * vel * m_dt; } @@ -262,22 +267,10 @@ void btContactProjection::setConstraintDirections() btScalar dot_prod = dirs[0].dot(cti.m_normal); if (std::abs(std::abs(dot_prod) - 1) < angle_epsilon) { - constraints[j].m_contact.push_back(&c); - constraints[j].m_direction.push_back(cti.m_normal); - constraints[j].m_value.push_back(0); - + // group the constraints + constraints[j].append(c); // push in an empty friction - frictions[j].m_direction.push_back(btVector3(0,0,0)); - frictions[j].m_direction_prev.push_back(btVector3(0,0,0)); - frictions[j].m_impulse.push_back(0); - frictions[j].m_impulse_prev.push_back(0); - frictions[j].m_dv.push_back(0); - frictions[j].m_dv_prev.push_back(0); - frictions[j].m_static.push_back(false); - frictions[j].m_static_prev.push_back(false); - frictions[j].m_accumulated_normal_impulse.push_back(0); - frictions[j].m_accumulated_tangent_impulse.push_back(btVector3(0,0,0)); - frictions[j].m_released.push_back(false); + frictions[j].append(); merged = true; break; } @@ -295,3 +288,127 @@ void btContactProjection::setConstraintDirections() } } } + +void btContactProjection::enforceConstraint(TVStack& x) +{ + const int dim = 3; + for (auto& it : m_constraints) + { + const btAlignedObjectArray& constraints = it.second; + size_t i = m_indices[it.first]; + const btAlignedObjectArray& frictions = m_frictions[it.first]; + btAssert(constraints.size() <= dim); + btAssert(constraints.size() > 0); + if (constraints.size() == 1) + { + x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; + for (int j = 0; j < constraints[0].m_direction.size(); ++j) + x[i] += constraints[0].m_value[j] * constraints[0].m_direction[j]; + } + else if (constraints.size() == 2) + { + btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); + btAssert(free_dir.norm() > SIMD_EPSILON) + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; + for (int j = 0; j < constraints.size(); ++j) + { + for (int k = 0; k < constraints[j].m_direction.size(); ++k) + { + x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; + } + } + + } + else + { + x[i].setZero(); + for (int j = 0; j < constraints.size(); ++j) + { + for (int k = 0; k < constraints[j].m_direction.size(); ++k) + { + x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; + } + } + } + + // apply friction if the node is not constrained in all directions + if (constraints.size() < 3) + { + for (int f = 0; f < frictions.size(); ++f) + { + const Friction& friction= frictions[f]; + for (int j = 0; j < friction.m_direction.size(); ++j) + { + // clear the old constraint + if (friction.m_static_prev[j] == true) + { + x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; + } + // add the new constraint + if (friction.m_static[j] == true) + { + x[i] += friction.m_direction[j] * friction.m_dv[j]; + } + } + } + } + } +} + +void btContactProjection::operator()(TVStack& x) +{ + const int dim = 3; + for (auto& it : m_constraints) + { + const btAlignedObjectArray& constraints = it.second; + size_t i = m_indices[it.first]; + btAlignedObjectArray& frictions = m_frictions[it.first]; + btAssert(constraints.size() <= dim); + btAssert(constraints.size() > 0); + if (constraints.size() == 1) + { + x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; + } + else if (constraints.size() == 2) + { + btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); + btAssert(free_dir.norm() > SIMD_EPSILON) + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; + } + else + x[i].setZero(); + + // apply friction if the node is not constrained in all directions + if (constraints.size() < 3) + { + bool has_static_constraint = false; + for (int f = 0; f < frictions.size(); ++f) + { + Friction& friction= frictions[f]; + for (int j = 0; j < friction.m_static.size(); ++j) + has_static_constraint = has_static_constraint || friction.m_static[j]; + } + + for (int f = 0; f < frictions.size(); ++f) + { + Friction& friction= frictions[f]; + for (int j = 0; j < friction.m_direction.size(); ++j) + { + // clear the old friction force + if (friction.m_static_prev[j] == false) + { + x[i] -= friction.m_direction_prev[j] * friction.m_impulse_prev[j]; + } + + // only add to the rhs if there is no static friction constraint on the node + if (friction.m_static[j] == false && !has_static_constraint) + { + x[i] += friction.m_direction[j] * friction.m_impulse[j]; + } + } + } + } + } +} diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btContactProjection.h index 566fd9f92..725cc106b 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btContactProjection.h @@ -18,171 +18,21 @@ public: btContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : btCGProjection(softBodies, dt) { - } virtual ~btContactProjection() { - } - // apply the constraints - virtual void operator()(TVStack& x) - { - const int dim = 3; - for (auto& it : m_constraints) - { - const btAlignedObjectArray& constraints = it.second; - size_t i = m_indices[it.first]; - btAlignedObjectArray& frictions = m_frictions[it.first]; - btAssert(constraints.size() <= dim); - btAssert(constraints.size() > 0); - if (constraints.size() == 1) - { - x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; - Friction& friction= frictions[0]; - - bool has_static_constraint = false; - for (int j = 0; j < friction.m_static.size(); ++j) - has_static_constraint = has_static_constraint || friction.m_static[j]; - - for (int j = 0; j < friction.m_direction.size(); ++j) - { - // clear the old friction force - if (friction.m_static_prev[j] == false) - { - x[i] -= friction.m_direction_prev[j] * friction.m_impulse_prev[j]; - } - - // only add to the rhs if there is no static friction constraint on the node - if (friction.m_static[j] == false && !has_static_constraint) - { - x[i] += friction.m_direction[j] * friction.m_impulse[j]; - } - } - } - else if (constraints.size() == 2) - { - // TODO : friction - btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); - btAssert(free_dir.norm() > SIMD_EPSILON) - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir; - - bool has_static_constraint = false; - for (int f = 0; f < 2; ++f) - { - Friction& friction= frictions[f]; - for (int j = 0; j < friction.m_static.size(); ++j) - has_static_constraint = has_static_constraint || friction.m_static[j]; - } - - for (int f = 0; f < 2; ++f) - { - Friction& friction= frictions[f]; - for (int j = 0; j < friction.m_direction.size(); ++j) - { - // clear the old friction force - if (friction.m_static_prev[j] == false) - { - x[i] -= friction.m_direction_prev[j] * friction.m_impulse_prev[j]; - } - - // only add to the rhs if there is no static friction constraint on the node - if (friction.m_static[j] == false && !has_static_constraint) - { - x[i] += friction.m_direction[j] * friction.m_impulse[j]; - } - } - } - } - else - x[i].setZero(); - } - } - + // apply the constraints to the rhs + virtual void operator()(TVStack& x); - virtual void enforceConstraint(TVStack& x) - { - const int dim = 3; - for (auto& it : m_constraints) - { - const btAlignedObjectArray& constraints = it.second; - size_t i = m_indices[it.first]; - const btAlignedObjectArray& frictions = m_frictions[it.first]; - btAssert(constraints.size() <= dim); - btAssert(constraints.size() > 0); - if (constraints.size() == 1) - { - x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; - for (int j = 0; j < constraints[0].m_direction.size(); ++j) - x[i] += constraints[0].m_value[j] * constraints[0].m_direction[j]; - - const Friction& friction= frictions[0]; - for (int j = 0; j < friction.m_direction.size(); ++j) - { - // clear the old constraint - if (friction.m_static_prev[j] == true) - { -// x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; - } - // add the new constraint - if (friction.m_static[j] == true) - { - x[i] += friction.m_direction[j] * friction.m_dv[j]; - } - } - } - else if (constraints.size() == 2) - { - // TODO: friction - btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); - btAssert(free_dir.norm() > SIMD_EPSILON) - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir; - for (int j = 0; j < constraints.size(); ++j) - { - for (int k = 0; k < constraints[j].m_direction.size(); ++k) - { - x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; - } - } - - for (int f = 0; f < 2; ++f) - { - const Friction& friction= frictions[f]; - for (int j = 0; j < friction.m_direction.size(); ++j) - { - // clear the old constraint - if (friction.m_static_prev[j] == true) - { -// x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; - } - // add the new constraint - if (friction.m_static[j] == true) - { - x[i] += friction.m_direction[j] * friction.m_dv[j]; - } - } - } - } - else - { - x[i].setZero(); - for (int j = 0; j < constraints.size(); ++j) - { - for (int k = 0; k < constraints[j].m_direction.size(); ++k) - { - x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; - } - } - } - } - } + // apply constraints to x in Ax=b + virtual void enforceConstraint(TVStack& x); // update the constraints virtual void update(const TVStack& dv, const TVStack& backupVelocity); - virtual void setConstraintDirections(); + virtual void setConstraints(); }; #endif /* btContactProjection_h */ diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index a8e1e5cd5..f98dfacbb 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -122,14 +122,15 @@ void btDeformableBodySolver::solveConstraints(float solverdt) // apply explicit force m_objective->applyExplicitForce(m_residual); - // remove contact constraints with separating velocity - setConstraintDirections(); + // add constraints to the solver + setConstraints(); backupVelocity(); for (int i = 0; i < m_solveIterations; ++i) { m_objective->computeResidual(solverdt, m_residual); + m_objective->initialGuess(m_dv, m_residual); m_objective->computeStep(m_dv, m_residual, solverdt); updateVelocity(); } @@ -153,9 +154,9 @@ void btDeformableBodySolver::reinitialize(bool nodeUpdated) m_objective->reinitialize(nodeUpdated); } -void btDeformableBodySolver::setConstraintDirections() +void btDeformableBodySolver::setConstraints() { - m_objective->setConstraintDirections(); + m_objective->setConstraints(); } void btDeformableBodySolver::setWorld(btDeformableRigidDynamicsWorld* world) @@ -173,9 +174,76 @@ void btDeformableBodySolver::updateVelocity() btSoftBody* psb = m_softBodySet[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { -// psb->m_nodes[j].m_v += m_dv[counter]; psb->m_nodes[j].m_v = m_backupVelocity[counter]+m_dv[counter]; ++counter; } } } + + +void btDeformableBodySolver::advect(btScalar dt) +{ + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + auto& node = psb->m_nodes[j]; + node.m_x = node.m_q + dt * node.m_v; + } + } +} + +void btDeformableBodySolver::backupVelocity() +{ + // serial implementation + int counter = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + m_backupVelocity[counter++] = psb->m_nodes[j].m_v; + } + } +} + +bool btDeformableBodySolver::updateNodes() +{ + int numNodes = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + numNodes += m_softBodySet[i]->m_nodes.size(); + if (numNodes != m_numNodes) + { + m_numNodes = numNodes; + m_backupVelocity.resize(numNodes); + return true; + } + return false; +} + + +void btDeformableBodySolver::predictMotion(float solverdt) +{ + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody *psb = m_softBodySet[i]; + + if (psb->isActive()) + { + psb->predictMotion(solverdt); + } + } +} + +void btDeformableBodySolver::updateSoftBodies() +{ + for (int i = 0; i < m_softBodySet.size(); i++) + { + btSoftBody *psb = (btSoftBody *)m_softBodySet[i]; + if (psb->isActive()) + { + psb->integrateMotion(); // normal is updated here + } + } +} diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 17f088c72..a1cd45077 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -51,17 +51,7 @@ public: return true; } - virtual void updateSoftBodies() - { - for (int i = 0; i < m_softBodySet.size(); i++) - { - btSoftBody *psb = (btSoftBody *)m_softBodySet[i]; - if (psb->isActive()) - { - psb->integrateMotion(); // normal is updated here - } - } - } + virtual void updateSoftBodies(); virtual void optimize(btAlignedObjectArray &softBodies, bool forceUpdate = false) { @@ -76,64 +66,17 @@ public: void reinitialize(bool nodeUpdated); - void setConstraintDirections(); + void setConstraints(); - void advect(btScalar dt) - { - size_t counter = 0; - for (int i = 0; i < m_softBodySet.size(); ++i) - { - btSoftBody* psb = m_softBodySet[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - auto& node = psb->m_nodes[j]; - node.m_x = node.m_q + dt * node.m_v; - } - } - } + void advect(btScalar dt); - void backupVelocity() - { - // serial implementation - int counter = 0; - for (int i = 0; i < m_softBodySet.size(); ++i) - { - btSoftBody* psb = m_softBodySet[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - m_backupVelocity[counter++] = psb->m_nodes[j].m_v; - } - } - } + void backupVelocity(); void updateVelocity(); - bool updateNodes() - { - int numNodes = 0; - for (int i = 0; i < m_softBodySet.size(); ++i) - numNodes += m_softBodySet[i]->m_nodes.size(); - if (numNodes != m_numNodes) - { - m_numNodes = numNodes; - m_backupVelocity.resize(numNodes); - return true; - } - return false; - } + bool updateNodes(); - virtual void predictMotion(float solverdt) - { - for (int i = 0; i < m_softBodySet.size(); ++i) - { - btSoftBody *psb = m_softBodySet[i]; - - if (psb->isActive()) - { - psb->predictMotion(solverdt); - } - } - } + virtual void predictMotion(float solverdt); virtual void copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer) {} diff --git a/src/BulletSoftBody/btPreconditioner.h b/src/BulletSoftBody/btPreconditioner.h new file mode 100644 index 000000000..ad190a3a8 --- /dev/null +++ b/src/BulletSoftBody/btPreconditioner.h @@ -0,0 +1,67 @@ +// +// btPreconditioner.h +// BulletSoftBody +// +// Created by Xuchen Han on 7/18/19. +// + +#ifndef BT_PRECONDITIONER_H +#define BT_PRECONDITIONER_H + +class Preconditioner +{ +public: + using TVStack = btAlignedObjectArray; + virtual void operator()(const TVStack& x, TVStack& b) = 0; + virtual void reinitialize(bool nodeUpdated) = 0; +}; + +class DefaultPreconditioner : public Preconditioner +{ +public: + virtual void operator()(const TVStack& x, TVStack& b) + { + btAssert(b.size() == x.size()); + for (int i = 0; i < b.size(); ++i) + b[i] = x[i]; + } + virtual void reinitialize(bool nodeUpdated) + { + + } +}; + +class MassPreconditioner : public Preconditioner +{ + btAlignedObjectArray m_inv_mass; + const btAlignedObjectArray& m_softBodies; +public: + MassPreconditioner(const btAlignedObjectArray& softBodies) + : m_softBodies(softBodies) + { + } + + virtual void reinitialize(bool nodeUpdated) + { + if (nodeUpdated) + { + m_inv_mass.clear(); + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + m_inv_mass.push_back(psb->m_nodes[j].m_im); + } + } + } + + virtual void operator()(const TVStack& x, TVStack& b) + { + btAssert(b.size() == x.size()); + btAssert(m_inv_mass.size() == x.size()); + for (int i = 0; i < b.size(); ++i) + b[i] = x[i] * m_inv_mass[i]; + } +}; + +#endif /* BT_PRECONDITIONER_H */ From a90cad2a9650ad57d597eaf72cc8b0e091e51ad5 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Sun, 21 Jul 2019 18:32:54 -0700 Subject: [PATCH 20/47] deformable code refactor --- .../Dynamics/btDiscreteDynamicsWorld.h | 10 + src/BulletSoftBody/btBackwardEulerObjective.h | 28 +- src/BulletSoftBody/btCGProjection.h | 51 +- src/BulletSoftBody/btConjugateGradient.h | 4 +- src/BulletSoftBody/btContactProjection.cpp | 156 ++++-- ...=> btDeformableBackwardEulerObjective.cpp} | 43 +- .../btDeformableBackwardEulerObjective.h | 100 ++++ src/BulletSoftBody/btDeformableBodySolver.cpp | 190 +++---- src/BulletSoftBody/btDeformableBodySolver.h | 35 +- .../btDeformableContactProjection.cpp | 488 ++++++++++++++++++ ...tion.h => btDeformableContactProjection.h} | 17 +- src/BulletSoftBody/btDeformableGravityForce.h | 60 +++ ...nForce.h => btDeformableLagrangianForce.h} | 30 +- ...Spring.h => btDeformableMassSpringForce.h} | 54 +- .../btDeformableRigidDynamicsWorld.cpp | 148 +++--- .../btDeformableRigidDynamicsWorld.h | 20 +- src/BulletSoftBody/btSoftBody.cpp | 13 +- 17 files changed, 1065 insertions(+), 382 deletions(-) rename src/BulletSoftBody/{btBackwardEulerObjective.cpp => btDeformableBackwardEulerObjective.cpp} (67%) create mode 100644 src/BulletSoftBody/btDeformableBackwardEulerObjective.h create mode 100644 src/BulletSoftBody/btDeformableContactProjection.cpp rename src/BulletSoftBody/{btContactProjection.h => btDeformableContactProjection.h} (52%) create mode 100644 src/BulletSoftBody/btDeformableGravityForce.h rename src/BulletSoftBody/{btLagrangianForce.h => btDeformableLagrangianForce.h} (58%) rename src/BulletSoftBody/{btMassSpring.h => btDeformableMassSpringForce.h} (65%) diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h index 51b3d906d..73607c61f 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -229,6 +229,16 @@ public: { return m_latencyMotionStateInterpolation; } + + btAlignedObjectArray& getNonStaticRigidBodies() + { + return m_nonStaticRigidBodies; + } + + const btAlignedObjectArray& getNonStaticRigidBodies() const + { + return m_nonStaticRigidBodies; + } }; #endif //BT_DISCRETE_DYNAMICS_WORLD_H diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h index 68f7f66fe..16ec0a542 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ b/src/BulletSoftBody/btBackwardEulerObjective.h @@ -1,5 +1,5 @@ // -// btBackwardEulerObjective.h +// btDeformableBackwardEulerObjective.h // BulletSoftBody // // Created by Xuchen Han on 7/1/19. @@ -11,27 +11,26 @@ #include "btConjugateGradient.h" #include "btLagrangianForce.h" #include "btMassSpring.h" -#include "btContactProjection.h" +#include "btDeformableContactProjection.h" #include "btPreconditioner.h" #include "btDeformableRigidDynamicsWorld.h" class btDeformableRigidDynamicsWorld; -class btBackwardEulerObjective +class btDeformableBackwardEulerObjective { public: using TVStack = btAlignedObjectArray; btScalar m_dt; - btConjugateGradient cg; btDeformableRigidDynamicsWorld* m_world; btAlignedObjectArray m_lf; btAlignedObjectArray& m_softBodies; Preconditioner* m_preconditioner; - btContactProjection projection; + btDeformableContactProjection projection; const TVStack& m_backupVelocity; - btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v); + btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v); - virtual ~btBackwardEulerObjective() {} + virtual ~btDeformableBackwardEulerObjective() {} void initialize(){} @@ -53,18 +52,14 @@ public: // perform A*x = b void multiply(const TVStack& x, TVStack& b) const; - // update the constraints treated as projections - void updateProjection(const TVStack& dv) - { - projection.update(dv, m_backupVelocity); - } - // set initial guess for CG solve void initialGuess(TVStack& dv, const TVStack& residual); // reset data structure void reinitialize(bool nodeUpdated); + void setDt(btScalar dt); + // enforce constraints in CG solve void enforceConstraint(TVStack& x) { @@ -82,10 +77,11 @@ public: } // update the projections and project the residual - void project(TVStack& r, const TVStack& dv) + void project(TVStack& r) { - updateProjection(dv); - projection(r); + projection.update(); + // TODO rename + projection.project(r); } // perform precondition M^(-1) x = b diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index ff5eecd8c..09055c7d1 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -8,53 +8,61 @@ #define BT_CG_PROJECTION_H #include "btSoftBody.h" +#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" #include class btDeformableRigidDynamicsWorld; -struct Constraint +struct DeformableContactConstraint { btAlignedObjectArray m_contact; btAlignedObjectArray m_direction; btAlignedObjectArray m_value; // the magnitude of the total impulse the node applied to the rb in the normal direction in the cg solve btAlignedObjectArray m_accumulated_normal_impulse; + btAlignedObjectArray m_normal_jacobian; - Constraint(const btSoftBody::RContact& rcontact) + DeformableContactConstraint(const btSoftBody::RContact& rcontact, const btMultiBodyJacobianData& jacobian) { - append(rcontact); + append(rcontact, jacobian); } - Constraint(const btVector3 dir) + DeformableContactConstraint(const btVector3 dir) { m_contact.push_back(nullptr); m_direction.push_back(dir); m_value.push_back(0); m_accumulated_normal_impulse.push_back(0); + btMultiBodyJacobianData j; + m_normal_jacobian.push_back(j); } - Constraint() + DeformableContactConstraint() { m_contact.push_back(nullptr); m_direction.push_back(btVector3(0,0,0)); m_value.push_back(0); m_accumulated_normal_impulse.push_back(0); + btMultiBodyJacobianData j; + m_normal_jacobian.push_back(j); } - void append(const btSoftBody::RContact& rcontact) + void append(const btSoftBody::RContact& rcontact, const btMultiBodyJacobianData& jacobian) { m_contact.push_back(&rcontact); m_direction.push_back(rcontact.m_cti.m_normal); m_value.push_back(0); m_accumulated_normal_impulse.push_back(0); + m_normal_jacobian.push_back(jacobian); } - ~Constraint() + ~DeformableContactConstraint() { } }; -struct Friction +struct DeformableFrictionConstraint { btAlignedObjectArray m_static; // whether the friction is static @@ -69,16 +77,24 @@ struct Friction btAlignedObjectArray m_direction_prev; btAlignedObjectArray m_released; // whether the contact is released - + btAlignedObjectArray m_complementary_jacobian; + btAlignedObjectArray m_complementaryDirection; // the total impulse the node applied to the rb in the tangential direction in the cg solve btAlignedObjectArray m_accumulated_tangent_impulse; - Friction() + + DeformableFrictionConstraint() { append(); } + DeformableFrictionConstraint(const btVector3& complementaryDir, const btMultiBodyJacobianData& jacobian) + { + append(); + addJacobian(complementaryDir, jacobian); + } + void append() { m_static.push_back(false); @@ -96,6 +112,13 @@ struct Friction m_accumulated_tangent_impulse.push_back(btVector3(0,0,0)); m_released.push_back(false); } + + void addJacobian(const btVector3& complementaryDir, const btMultiBodyJacobianData& jacobian) + { + m_complementary_jacobian.push_back(jacobian); + m_complementaryDirection.push_back(complementaryDir); + } + }; class btCGProjection @@ -109,8 +132,6 @@ public: btDeformableRigidDynamicsWorld* m_world; std::unordered_map m_indices; const btScalar& m_dt; - std::unordered_map > m_constraints; - std::unordered_map > m_frictions; btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : m_softBodies(softBodies) @@ -123,19 +144,17 @@ public: } // apply the constraints - virtual void operator()(TVStack& x) = 0; + virtual void project(TVStack& x) = 0; virtual void setConstraints() = 0; // update the constraints - virtual void update(const TVStack& dv, const TVStack& backup_v) = 0; + virtual void update() = 0; virtual void reinitialize(bool nodeUpdated) { if (nodeUpdated) updateId(); - m_constraints.clear(); - m_frictions.clear(); } void updateId() diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index f23b26385..0c8384a00 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -36,7 +36,7 @@ public: // r = b - A * x --with assigned dof zeroed out A.multiply(x, temp); r = sub(b, temp); - A.project(r,x); + A.project(r); A.enforceConstraint(x); btScalar r_norm = std::sqrt(squaredNorm(r)); @@ -62,7 +62,7 @@ public: multAndAddTo(alpha, p, x); multAndAddTo(-alpha, temp, r); // zero out the dofs of r - A.project(r,x); + A.project(r); A.enforceConstraint(x); r_norm = std::sqrt(squaredNorm(r)); diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index cf2e05e59..99ab6f473 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -1,14 +1,47 @@ // -// btContactProjection.cpp +// btDeformableContactProjection.cpp // BulletSoftBody // // Created by Xuchen Han on 7/4/19. // -#include "btContactProjection.h" +#include "btDeformableContactProjection.h" #include "btDeformableRigidDynamicsWorld.h" #include -void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocity) +static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, + btMultiBodyJacobianData& jacobianData, + const btVector3& contact_point, + const btVector3& dir) +{ + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, contact_point, dir, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], &jacobianData.m_deltaVelocitiesUnitImpulse[0], jacobianData.scratch_r, jacobianData.scratch_v); +} + +static btVector3 generateUnitOrthogonalVector(const btVector3& u) +{ + btScalar ux = u.getX(); + btScalar uy = u.getY(); + btScalar uz = u.getZ(); + btScalar ax = std::abs(ux); + btScalar ay = std::abs(uy); + btScalar az = std::abs(uz); + btVector3 v; + if (ax <= ay && ax <= az) + v = btVector3(0, -uz, uy); + else if (ay <= ax && ay <= az) + v = btVector3(-uz, 0, ux); + else + v = btVector3(-uy, ux, 0); + v.normalize(); + return v; +} + +void btDeformableContactProjection::update() { ///solve rigid body constraints m_world->getSolverInfo().m_numIterations = 10; @@ -32,13 +65,17 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit } const btSoftBody::RContact* c = constraint.m_contact[j]; const btSoftBody::sCti& cti = c->m_cti; - btMultiBodyJacobianData jacobianData; + + // normal jacobian is precompute but tangent jacobian is not + const btMultiBodyJacobianData& jacobianData_normal = constraint.m_normal_jacobian[j]; + const btMultiBodyJacobianData& jacobianData_complementary = friction.m_complementary_jacobian[j]; + if (cti.m_colObj->hasContactResponse()) { btVector3 va(0, 0, 0); btRigidBody* rigidCol = 0; btMultiBodyLinkCollider* multibodyLinkCol = 0; - btScalar* deltaV; + const btScalar* deltaV_normal; // grab the velocity of the rigid body if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) @@ -52,20 +89,25 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit if (multibodyLinkCol) { const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - jacobianData.m_jacobians.resize(ndof); - jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); - btScalar* jac = &jacobianData.m_jacobians[0]; - - multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c->m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); - deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); + const btScalar* jac_normal = &jacobianData_normal.m_jacobians[0]; + deltaV_normal = &jacobianData_normal.m_deltaVelocitiesUnitImpulse[0]; + // add in the normal component of the va btScalar vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac[k]; + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac_normal[k]; } va = cti.m_normal * vel * m_dt; + + // add in complementary direction of va + const btScalar* jac_complementary = &jacobianData_complementary.m_jacobians[0]; + vel = 0.0; + for (int k = 0; k < ndof; ++k) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac_complementary[k]; + } + va += friction.m_complementaryDirection[j] * vel * m_dt; } } @@ -109,7 +151,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit else { friction.m_static[j] = true; - friction.m_impulse[j] = local_tangent_norm; + friction.m_impulse[j] = tangent_norm; } } else @@ -125,15 +167,22 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit // the incremental impulse applied to rb in the tangential direction btVector3 incremental_tangent = (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); + // TODO cleanup if (1) // in the same CG solve, the set of constraits doesn't change { // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient // dv = new_impulse + accumulated velocity change in previous CG iterations // so we have the invariant node->m_v = backupVelocity + dv; -// btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; -// btScalar dvn = dv.dot(cti.m_normal); + btScalar dvn = -accumulated_normal * c->m_c2/m_dt; + + // the following is equivalent + /* + btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; + btScalar dvn = dv.dot(cti.m_normal); + */ + constraint.m_value[j] = dvn; // the incremental impulse: @@ -147,10 +196,20 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { + if (multibodyLinkCol) { - double multiplier = 0.5; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + double multiplier = 1; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_normal, -impulse_normal.length() * multiplier); + + if (incremental_tangent.norm() > SIMD_EPSILON) + { + btMultiBodyJacobianData jacobian_tangent; + btVector3 tangent = incremental_tangent.normalized(); + findJacobian(multibodyLinkCol, jacobian_tangent, c->m_node->m_x, tangent); + const btScalar* deltaV_tangent = &jacobian_tangent.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_tangent, incremental_tangent.length() * multiplier); + } } } } @@ -160,7 +219,7 @@ void btContactProjection::update(const TVStack& dv, const TVStack& backupVelocit } } -void btContactProjection::setConstraints() +void btDeformableContactProjection::setConstraints() { // set Dirichlet constraint for (int i = 0; i < m_softBodies.size(); ++i) @@ -188,8 +247,8 @@ void btContactProjection::setConstraints() for (int i = 0; i < m_softBodies.size(); ++i) { btSoftBody* psb = m_softBodies[i]; - btMultiBodyJacobianData jacobianData; - btAlignedObjectArray jacobian; + btMultiBodyJacobianData jacobianData_normal; + btMultiBodyJacobianData jacobianData_complementary; for (int j = 0; j < psb->m_rcontacts.size(); ++j) { @@ -206,7 +265,6 @@ void btContactProjection::setConstraints() btVector3 va(0, 0, 0); btRigidBody* rigidCol = 0; btMultiBodyLinkCollider* multibodyLinkCol = 0; - btScalar* deltaV; // grab the velocity of the rigid body if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) @@ -216,25 +274,18 @@ void btContactProjection::setConstraints() } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { - jacobian.clear(); multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); if (multibodyLinkCol) { - const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - jacobianData.m_jacobians.resize(ndof); - jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); - btScalar* jac = &jacobianData.m_jacobians[0]; - - multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); - deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); - + findJacobian(multibodyLinkCol, jacobianData_normal, c.m_node->m_x, cti.m_normal); btScalar vel = 0.0; - jacobian.resize(ndof); + const btScalar* jac = &jacobianData_normal.m_jacobians[0]; + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; for (int j = 0; j < ndof; ++j) { vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; - jacobian[j] = jac[j]; + std::cout << multibodyLinkCol->m_multiBody->getVelocityVector()[j] << std::endl; + std::cout << jac[j] << std::endl; } va = cti.m_normal * vel * m_dt; } @@ -245,13 +296,25 @@ void btContactProjection::setConstraints() const btScalar dn = btDot(vr, cti.m_normal); if (dn < SIMD_EPSILON) { + // find complementary jacobian + btVector3 complementaryDirection; + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + complementaryDirection = generateUnitOrthogonalVector(cti.m_normal); + findJacobian(multibodyLinkCol, jacobianData_complementary, c.m_node->m_x, complementaryDirection); + } + } + if (m_constraints.find(c.m_node) == m_constraints.end()) { btAlignedObjectArray constraints; - constraints.push_back(Constraint(c)); + constraints.push_back(Constraint(c, jacobianData_normal)); m_constraints[c.m_node] = constraints; btAlignedObjectArray frictions; - frictions.push_back(Friction()); + frictions.push_back(Friction(complementaryDirection, jacobianData_complementary)); m_frictions[c.m_node] = frictions; } else @@ -268,9 +331,10 @@ void btContactProjection::setConstraints() if (std::abs(std::abs(dot_prod) - 1) < angle_epsilon) { // group the constraints - constraints[j].append(c); + constraints[j].append(c, jacobianData_normal); // push in an empty friction frictions[j].append(); + frictions[j].addJacobian(complementaryDirection, jacobianData_complementary); merged = true; break; } @@ -279,8 +343,8 @@ void btContactProjection::setConstraints() // hard coded no more than 3 constraint directions if (!merged && constraints.size() < dim) { - constraints.push_back(Constraint(c)); - frictions.push_back(Friction()); + constraints.push_back(Constraint(c, jacobianData_normal)); + frictions.push_back(Friction(complementaryDirection, jacobianData_complementary)); } } } @@ -289,7 +353,7 @@ void btContactProjection::setConstraints() } } -void btContactProjection::enforceConstraint(TVStack& x) +void btDeformableContactProjection::enforceConstraint(TVStack& x) { const int dim = 3; for (auto& it : m_constraints) @@ -356,7 +420,7 @@ void btContactProjection::enforceConstraint(TVStack& x) } } -void btContactProjection::operator()(TVStack& x) +void btDeformableContactProjection::project(TVStack& x) { const int dim = 3; for (auto& it : m_constraints) @@ -412,3 +476,13 @@ void btContactProjection::operator()(TVStack& x) } } } + +void btDeformableContactProjection::reinitialize(bool nodeUpdated) +{ + btCGProjection::reinitialize(nodeUpdated); + m_constraints.clear(); + m_frictions.clear(); +} + + + diff --git a/src/BulletSoftBody/btBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp similarity index 67% rename from src/BulletSoftBody/btBackwardEulerObjective.cpp rename to src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 024cc66b6..31b0905ac 100644 --- a/src/BulletSoftBody/btBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -1,26 +1,26 @@ // -// btBackwardEulerObjective.cpp +// btDeformableBackwardEulerObjective.cpp // BulletSoftBody // // Created by Xuchen Han on 7/9/19. // -#include "btBackwardEulerObjective.h" +#include "btDeformableBackwardEulerObjective.h" -btBackwardEulerObjective::btBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) -: cg(10) -, m_softBodies(softBodies) +btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) +: m_softBodies(softBodies) , projection(m_softBodies, m_dt) , m_backupVelocity(backup_v) { // TODO: this should really be specified in initialization instead of here - btMassSpring* mass_spring = new btMassSpring(m_softBodies); -// m_preconditioner = new MassPreconditioner(m_softBodies); + btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(m_softBodies); + btDeformableGravityForce* gravity = new btDeformableGravityForce(m_softBodies, btVector3(0,-10,0)); m_preconditioner = new DefaultPreconditioner(); m_lf.push_back(mass_spring); + m_lf.push_back(gravity); } -void btBackwardEulerObjective::reinitialize(bool nodeUpdated) +void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated) { if(nodeUpdated) { @@ -34,8 +34,12 @@ void btBackwardEulerObjective::reinitialize(bool nodeUpdated) m_preconditioner->reinitialize(nodeUpdated); } +void btDeformableBackwardEulerObjective::setDt(btScalar dt) +{ + m_dt = dt; +} -void btBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const +void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const { for (int i = 0; i < b.size(); ++i) b[i].setZero(); @@ -56,18 +60,11 @@ void btBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const for (int i = 0; i < m_lf.size(); ++i) { // add damping matrix - m_lf[i]->addScaledDampingForceDifferential(-m_dt, x, b); + m_lf[i]->addScaledForceDifferential(-m_dt, x, b); } } -void btBackwardEulerObjective::computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt) -{ - m_dt = dt; - btScalar tolerance = std::numeric_limits::epsilon()* 1024 * computeNorm(residual); - cg.solve(*this, dv, residual, tolerance); -} - -void btBackwardEulerObjective::updateVelocity(const TVStack& dv) +void btDeformableBackwardEulerObjective::updateVelocity(const TVStack& dv) { // only the velocity of the constrained nodes needs to be updated during CG solve for (auto it : projection.m_constraints) @@ -77,7 +74,7 @@ void btBackwardEulerObjective::updateVelocity(const TVStack& dv) } } -void btBackwardEulerObjective::applyForce(TVStack& force, bool setZero) +void btDeformableBackwardEulerObjective::applyForce(TVStack& force, bool setZero) { size_t counter = 0; for (int i = 0; i < m_softBodies.size(); ++i) @@ -96,7 +93,7 @@ void btBackwardEulerObjective::applyForce(TVStack& force, bool setZero) } } -void btBackwardEulerObjective::computeResidual(btScalar dt, TVStack &residual) const +void btDeformableBackwardEulerObjective::computeResidual(btScalar dt, TVStack &residual) const { // add implicit force for (int i = 0; i < m_lf.size(); ++i) @@ -105,7 +102,7 @@ void btBackwardEulerObjective::computeResidual(btScalar dt, TVStack &residual) c } } -btScalar btBackwardEulerObjective::computeNorm(const TVStack& residual) const +btScalar btDeformableBackwardEulerObjective::computeNorm(const TVStack& residual) const { btScalar norm_squared = 0; for (int i = 0; i < residual.size(); ++i) @@ -115,14 +112,14 @@ btScalar btBackwardEulerObjective::computeNorm(const TVStack& residual) const return std::sqrt(norm_squared+SIMD_EPSILON); } -void btBackwardEulerObjective::applyExplicitForce(TVStack& force) +void btDeformableBackwardEulerObjective::applyExplicitForce(TVStack& force) { for (int i = 0; i < m_lf.size(); ++i) m_lf[i]->addScaledExplicitForce(m_dt, force); applyForce(force, true); } -void btBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack& residual) +void btDeformableBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack& residual) { size_t counter = 0; for (int i = 0; i < m_softBodies.size(); ++i) diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h new file mode 100644 index 000000000..bfd4ca3af --- /dev/null +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -0,0 +1,100 @@ +// +// btDeformableBackwardEulerObjective.h +// BulletSoftBody +// +// Created by Xuchen Han on 7/1/19. +// + +#ifndef BT_BACKWARD_EULER_OBJECTIVE_H +#define BT_BACKWARD_EULER_OBJECTIVE_H +#include +#include "btConjugateGradient.h" +#include "btDeformableLagrangianForce.h" +#include "btDeformableMassSpringForce.h" +#include "btDeformableGravityForce.h" +#include "btDeformableContactProjection.h" +#include "btPreconditioner.h" +#include "btDeformableRigidDynamicsWorld.h" + +class btDeformableRigidDynamicsWorld; +class btDeformableBackwardEulerObjective +{ +public: + using TVStack = btAlignedObjectArray; + btScalar m_dt; + btDeformableRigidDynamicsWorld* m_world; + btAlignedObjectArray m_lf; + btAlignedObjectArray& m_softBodies; + Preconditioner* m_preconditioner; + btDeformableContactProjection projection; + const TVStack& m_backupVelocity; + + btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v); + + virtual ~btDeformableBackwardEulerObjective() {} + + void initialize(){} + + // compute the rhs for CG solve, i.e, add the dt scaled implicit force to residual + void computeResidual(btScalar dt, TVStack& residual) const; + + // add explicit force to the velocity + void applyExplicitForce(TVStack& force); + + // apply force to velocity and optionally reset the force to zero + void applyForce(TVStack& force, bool setZero); + + // compute the norm of the residual + btScalar computeNorm(const TVStack& residual) const; + + // compute one step of the solve (there is only one solve if the system is linear) + void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt); + + // perform A*x = b + void multiply(const TVStack& x, TVStack& b) const; + + // set initial guess for CG solve + void initialGuess(TVStack& dv, const TVStack& residual); + + // reset data structure + void reinitialize(bool nodeUpdated); + + void setDt(btScalar dt); + + // enforce constraints in CG solve + void enforceConstraint(TVStack& x) + { + projection.enforceConstraint(x); + updateVelocity(x); + } + + // add dv to velocity + void updateVelocity(const TVStack& dv); + + //set constraints as projections + void setConstraints() + { + projection.setConstraints(); + } + + // update the projections and project the residual + void project(TVStack& r) + { + projection.update(); + projection.project(r); + } + + // perform precondition M^(-1) x = b + void precondition(const TVStack& x, TVStack& b) + { + m_preconditioner->operator()(x,b); + } + + virtual void setWorld(btDeformableRigidDynamicsWorld* world) + { + m_world = world; + projection.setWorld(world); + } +}; + +#endif /* btBackwardEulerObjective_h */ diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index f98dfacbb..96d2e0029 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -10,11 +10,9 @@ btDeformableBodySolver::btDeformableBodySolver() : m_numNodes(0) -, m_solveIterations(1) -, m_impulseIterations(1) -, m_world(nullptr) +, cg(10) { - m_objective = new btBackwardEulerObjective(m_softBodySet, m_backupVelocity); + m_objective = new btDeformableBackwardEulerObjective(m_softBodySet, m_backupVelocity); } btDeformableBodySolver::~btDeformableBodySolver() @@ -22,124 +20,31 @@ btDeformableBodySolver::~btDeformableBodySolver() delete m_objective; } -void btDeformableBodySolver::postStabilize() -{ - for (int i = 0; i < m_softBodySet.size(); ++i) - { - btSoftBody* psb = m_softBodySet[i]; - btMultiBodyJacobianData jacobianData; - const btScalar mrg = psb->getCollisionShape()->getMargin(); - for (int j = 0; j < psb->m_rcontacts.size(); ++j) - { - const btSoftBody::RContact& c = psb->m_rcontacts[j]; - // skip anchor points - if (c.m_node->m_im == 0) - continue; - - const btSoftBody::sCti& cti = c.m_cti; - if (cti.m_colObj->hasContactResponse()) - { - btVector3 va(0, 0, 0); - btRigidBody* rigidCol = 0; - btMultiBodyLinkCollider* multibodyLinkCol = 0; - btScalar* deltaV; - - // grab the velocity of the rigid body - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * m_dt : btVector3(0, 0, 0); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); - if (multibodyLinkCol) - { - const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - jacobianData.m_jacobians.resize(ndof); - jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); - btScalar* jac = &jacobianData.m_jacobians[0]; - - multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); - deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); - - btScalar vel = 0.0; - for (int j = 0; j < ndof; ++j) - { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; - } - va = cti.m_normal * vel * m_dt; - } - } - - const btVector3 vb = c.m_node->m_v * m_dt; - const btVector3 vr = vb - va; - const btScalar dn = btDot(vr, cti.m_normal); - - btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); -// dp += mrg; - // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - - btScalar dvn = dn * c.m_c4; - const btVector3 impulse = c.m_c0 * ((cti.m_normal * (dn * c.m_c4))); - // TODO: only contact is considered here, add friction later - if (dp < 0) - { - bool two_way = false; - if (two_way) - { - c.m_node->m_x -= impulse * c.m_c2; - - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - if (rigidCol) - rigidCol->applyImpulse(impulse, c.m_c1); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - if (multibodyLinkCol) - { - double multiplier = 0.5; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); - } - } - } - else - c.m_node->m_x -= dp * cti.m_normal * c.m_c4; - } - } - } - } -} - void btDeformableBodySolver::solveConstraints(float solverdt) { - m_dt = solverdt; - bool nodeUpdated = updateNodes(); - reinitialize(nodeUpdated); - - // apply explicit force - m_objective->applyExplicitForce(m_residual); + m_objective->setDt(solverdt); // add constraints to the solver setConstraints(); + // save v_{n+1}^* velocity after explicit forces backupVelocity(); - - for (int i = 0; i < m_solveIterations; ++i) - { - m_objective->computeResidual(solverdt, m_residual); - m_objective->initialGuess(m_dv, m_residual); - m_objective->computeStep(m_dv, m_residual, solverdt); - updateVelocity(); - } - advect(solverdt); - postStabilize(); + m_objective->computeResidual(solverdt, m_residual); +// m_objective->initialGuess(m_dv, m_residual); + computeStep(m_dv, m_residual); + updateVelocity(); } -void btDeformableBodySolver::reinitialize(bool nodeUpdated) +void btDeformableBodySolver::computeStep(TVStack& dv, const TVStack& residual) { + btScalar tolerance = std::numeric_limits::epsilon()* 1024 * m_objective->computeNorm(residual); + cg.solve(*m_objective, dv, residual, tolerance); +} + +void btDeformableBodySolver::reinitialize(const btAlignedObjectArray& softBodies) +{ + m_softBodySet.copyFromArray(softBodies); + bool nodeUpdated = updateNodes(); if (nodeUpdated) { m_dv.resize(m_numNodes); @@ -161,7 +66,6 @@ void btDeformableBodySolver::setConstraints() void btDeformableBodySolver::setWorld(btDeformableRigidDynamicsWorld* world) { - m_world = world; m_objective->setWorld(world); } @@ -180,20 +84,6 @@ void btDeformableBodySolver::updateVelocity() } } - -void btDeformableBodySolver::advect(btScalar dt) -{ - for (int i = 0; i < m_softBodySet.size(); ++i) - { - btSoftBody* psb = m_softBodySet[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - auto& node = psb->m_nodes[j]; - node.m_x = node.m_q + dt * node.m_v; - } - } -} - void btDeformableBodySolver::backupVelocity() { // serial implementation @@ -231,11 +121,53 @@ void btDeformableBodySolver::predictMotion(float solverdt) if (psb->isActive()) { - psb->predictMotion(solverdt); + // apply explicit forces to velocity + m_objective->applyExplicitForce(m_residual); + // predict motion for collision detection + predictDeformableMotion(psb, solverdt); } } } +void btDeformableBodySolver::predictDeformableMotion(btSoftBody* psb, btScalar dt) +{ + int i, ni; + + /* Prepare */ + psb->m_sst.sdt = dt * psb->m_cfg.timescale; + psb->m_sst.isdt = 1 / psb->m_sst.sdt; + psb->m_sst.velmrg = psb->m_sst.sdt * 3; + psb->m_sst.radmrg = psb->getCollisionShape()->getMargin(); + psb->m_sst.updmrg = psb->m_sst.radmrg * (btScalar)0.25; + /* Integrate */ + for (i = 0, ni = psb->m_nodes.size(); i < ni; ++i) + { + btSoftBody::Node& n = psb->m_nodes[i]; + n.m_q = n.m_x; + n.m_x += n.m_v * dt; + } + /* Bounds */ + psb->updateBounds(); + /* Nodes */ + ATTRIBUTE_ALIGNED16(btDbvtVolume) + vol; + for (i = 0, ni = psb->m_nodes.size(); i < ni; ++i) + { + btSoftBody::Node& n = psb->m_nodes[i]; + vol = btDbvtVolume::FromCR(n.m_x, psb->m_sst.radmrg); + psb->m_ndbvt.update(n.m_leaf, + vol, + n.m_v * psb->m_sst.velmrg, + psb->m_sst.updmrg); + } + + /* Clear contacts */ + psb->m_rcontacts.resize(0); + psb->m_scontacts.resize(0); + /* Optimize dbvt's */ + psb->m_ndbvt.optimizeIncremental(1); +} + void btDeformableBodySolver::updateSoftBodies() { for (int i = 0; i < m_softBodySet.size(); i++) @@ -243,7 +175,7 @@ void btDeformableBodySolver::updateSoftBodies() btSoftBody *psb = (btSoftBody *)m_softBodySet[i]; if (psb->isActive()) { - psb->integrateMotion(); // normal is updated here + psb->updateNormals(); // normal is updated here } } } diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index a1cd45077..570cce90f 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -10,31 +10,27 @@ #include #include "btSoftBodySolvers.h" -#include "btBackwardEulerObjective.h" +#include "btDeformableBackwardEulerObjective.h" #include "btDeformableRigidDynamicsWorld.h" #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" struct btCollisionObjectWrapper; -class btBackwardEulerObjective; +class btDeformableBackwardEulerObjective; class btDeformableRigidDynamicsWorld; class btDeformableBodySolver : public btSoftBodySolver { using TVStack = btAlignedObjectArray; protected: - /** Variable to define whether we need to update solver constants on the next iteration */ - bool m_updateSolverConstants; int m_numNodes; TVStack m_dv; TVStack m_residual; btAlignedObjectArray m_softBodySet; - btBackwardEulerObjective* m_objective; - int m_solveIterations; - int m_impulseIterations; - btDeformableRigidDynamicsWorld* m_world; + btDeformableBackwardEulerObjective* m_objective; btAlignedObjectArray m_backupVelocity; btScalar m_dt; + btConjugateGradient cg; public: btDeformableBodySolver(); @@ -45,30 +41,20 @@ public: { return DEFORMABLE_SOLVER; } - - virtual bool checkInitialized() - { - return true; - } virtual void updateSoftBodies(); - - virtual void optimize(btAlignedObjectArray &softBodies, bool forceUpdate = false) - { - m_softBodySet.copyFromArray(softBodies); - } virtual void copyBackToSoftBodies(bool bMove = true) {} + void extracted(float solverdt); + virtual void solveConstraints(float solverdt); - void postStabilize(); - - void reinitialize(bool nodeUpdated); + void reinitialize(const btAlignedObjectArray& softBodies); void setConstraints(); - void advect(btScalar dt); + void predictDeformableMotion(btSoftBody* psb, btScalar dt); void backupVelocity(); @@ -76,6 +62,8 @@ public: bool updateNodes(); + void computeStep(TVStack& dv, const TVStack& residual); + virtual void predictMotion(float solverdt); virtual void copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer) {} @@ -88,7 +76,8 @@ public: virtual void processCollision(btSoftBody * softBody, btSoftBody * otherSoftBody) { softBody->defaultCollisionHandler(otherSoftBody); } - + virtual void optimize(btAlignedObjectArray &softBodies, bool forceUpdate = false){} + virtual bool checkInitialized(){return true;} virtual void setWorld(btDeformableRigidDynamicsWorld* world); }; diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp new file mode 100644 index 000000000..e81cb2c50 --- /dev/null +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -0,0 +1,488 @@ +// +// btDeformableContactProjection.cpp +// BulletSoftBody +// +// Created by Xuchen Han on 7/4/19. +// + +#include "btDeformableContactProjection.h" +#include "btDeformableRigidDynamicsWorld.h" +#include +static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, + btMultiBodyJacobianData& jacobianData, + const btVector3& contact_point, + const btVector3& dir) +{ + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, contact_point, dir, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], &jacobianData.m_deltaVelocitiesUnitImpulse[0], jacobianData.scratch_r, jacobianData.scratch_v); +} + +static btVector3 generateUnitOrthogonalVector(const btVector3& u) +{ + btScalar ux = u.getX(); + btScalar uy = u.getY(); + btScalar uz = u.getZ(); + btScalar ax = std::abs(ux); + btScalar ay = std::abs(uy); + btScalar az = std::abs(uz); + btVector3 v; + if (ax <= ay && ax <= az) + v = btVector3(0, -uz, uy); + else if (ay <= ax && ay <= az) + v = btVector3(-uz, 0, ux); + else + v = btVector3(-uy, ux, 0); + v.normalize(); + return v; +} + +void btDeformableContactProjection::update() +{ + ///solve rigid body constraints + m_world->getSolverInfo().m_numIterations = 10; + m_world->btMultiBodyDynamicsWorld::solveConstraints(m_world->getSolverInfo()); + + // loop through constraints to set constrained values + for (auto& it : m_constraints) + { + btAlignedObjectArray& frictions = m_frictions[it.first]; + btAlignedObjectArray& constraints = it.second; + for (int i = 0; i < constraints.size(); ++i) + { + DeformableContactConstraint& constraint = constraints[i]; + DeformableFrictionConstraint& friction = frictions[i]; + for (int j = 0; j < constraint.m_contact.size(); ++j) + { + if (constraint.m_contact[j] == nullptr) + { + // nothing needs to be done for dirichelet constraints + continue; + } + const btSoftBody::RContact* c = constraint.m_contact[j]; + const btSoftBody::sCti& cti = c->m_cti; + + // normal jacobian is precompute but tangent jacobian is not + const btMultiBodyJacobianData& jacobianData_normal = constraint.m_normal_jacobian[j]; + const btMultiBodyJacobianData& jacobianData_complementary = friction.m_complementary_jacobian[j]; + + if (cti.m_colObj->hasContactResponse()) + { + btVector3 va(0, 0, 0); + btRigidBody* rigidCol = 0; + btMultiBodyLinkCollider* multibodyLinkCol = 0; + const btScalar* deltaV_normal; + + // grab the velocity of the rigid body + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c->m_c1)) * m_dt : btVector3(0, 0, 0); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + const btScalar* jac_normal = &jacobianData_normal.m_jacobians[0]; + deltaV_normal = &jacobianData_normal.m_deltaVelocitiesUnitImpulse[0]; + + // add in the normal component of the va + btScalar vel = 0.0; + for (int k = 0; k < ndof; ++k) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac_normal[k]; + } + va = cti.m_normal * vel * m_dt; + + // add in complementary direction of va + const btScalar* jac_complementary = &jacobianData_complementary.m_jacobians[0]; + vel = 0.0; + for (int k = 0; k < ndof; ++k) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac_complementary[k]; + } + va += friction.m_complementaryDirection[j] * vel * m_dt; + } + } + + const btVector3 vb = c->m_node->m_v * m_dt; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, cti.m_normal); + btVector3 impulse = c->m_c0 * vr; + const btVector3 impulse_normal = c->m_c0 * (cti.m_normal * dn); + const btVector3 impulse_tangent = impulse - impulse_normal; + + // start friction handling + // copy old data + friction.m_impulse_prev[j] = friction.m_impulse[j]; + friction.m_dv_prev[j] = friction.m_dv[j]; + friction.m_static_prev[j] = friction.m_static[j]; + + // get the current tangent direction + btScalar local_tangent_norm = impulse_tangent.norm(); + btVector3 local_tangent_dir = btVector3(0,0,0); + if (local_tangent_norm > SIMD_EPSILON) + local_tangent_dir = impulse_tangent.normalized(); + + // accumulated impulse on the rb in this and all prev cg iterations + constraint.m_accumulated_normal_impulse[j] += impulse_normal.dot(cti.m_normal); + const btScalar& accumulated_normal = constraint.m_accumulated_normal_impulse[j]; + + // the total tangential impulse required to stop sliding + btVector3 tangent = friction.m_accumulated_tangent_impulse[j] + impulse_tangent; + btScalar tangent_norm = tangent.norm(); + + if (accumulated_normal < 0) + { + friction.m_direction[j] = -local_tangent_dir; + // do not allow switching from static friction to dynamic friction + // it causes cg to explode + if (-accumulated_normal*c->m_c3 < tangent_norm && friction.m_static_prev[j] == false && friction.m_released[j] == false) + { + friction.m_static[j] = false; + friction.m_impulse[j] = -accumulated_normal*c->m_c3; + } + else + { + friction.m_static[j] = true; + friction.m_impulse[j] = tangent_norm; + } + } + else + { + friction.m_released[j] = true; + friction.m_static[j] = false; + friction.m_impulse[j] = 0; + friction.m_direction[j] = btVector3(0,0,0); + } + friction.m_dv[j] = friction.m_impulse[j] * c->m_c2/m_dt; + friction.m_accumulated_tangent_impulse[j] = -friction.m_impulse[j] * friction.m_direction[j]; + + // the incremental impulse applied to rb in the tangential direction + btVector3 incremental_tangent = (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); + + // TODO cleanup + if (1) // in the same CG solve, the set of constraits doesn't change + { + // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient + + // dv = new_impulse + accumulated velocity change in previous CG iterations + // so we have the invariant node->m_v = backupVelocity + dv; + + btScalar dvn = -accumulated_normal * c->m_c2/m_dt; + + // the following is equivalent + /* + btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; + btScalar dvn = dv.dot(cti.m_normal); + */ + + constraint.m_value[j] = dvn; + + // the incremental impulse: + // in the normal direction it's the normal component of "impulse" + // in the tangent direction it's the difference between the frictional impulse in the iteration and the previous iteration + impulse = impulse_normal + incremental_tangent; + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + if (rigidCol) + rigidCol->applyImpulse(impulse, c->m_c1); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + + if (multibodyLinkCol) + { + double multiplier = 1; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_normal, -impulse_normal.length() * multiplier); + + if (incremental_tangent.norm() > SIMD_EPSILON) + { + btMultiBodyJacobianData jacobian_tangent; + btVector3 tangent = incremental_tangent.normalized(); + findJacobian(multibodyLinkCol, jacobian_tangent, c->m_node->m_x, tangent); + const btScalar* deltaV_tangent = &jacobian_tangent.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_tangent, incremental_tangent.length() * multiplier); + } + } + } + } + } + } + } + } +} + +void btDeformableContactProjection::setConstraints() +{ + // set Dirichlet constraint + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + if (psb->m_nodes[j].m_im == 0) + { + btAlignedObjectArray c; + c.push_back(DeformableContactConstraint(btVector3(1,0,0))); + c.push_back(DeformableContactConstraint(btVector3(0,1,0))); + c.push_back(DeformableContactConstraint(btVector3(0,0,1))); + m_constraints[&(psb->m_nodes[j])] = c; + + btAlignedObjectArray f; + f.push_back(DeformableFrictionConstraint()); + f.push_back(DeformableFrictionConstraint()); + f.push_back(DeformableFrictionConstraint()); + m_frictions[&(psb->m_nodes[j])] = f; + } + } + } + + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + btMultiBodyJacobianData jacobianData_normal; + btMultiBodyJacobianData jacobianData_complementary; + + for (int j = 0; j < psb->m_rcontacts.size(); ++j) + { + const btSoftBody::RContact& c = psb->m_rcontacts[j]; + // skip anchor points + if (c.m_node->m_im == 0) + { + continue; + } + + const btSoftBody::sCti& cti = c.m_cti; + if (cti.m_colObj->hasContactResponse()) + { + btVector3 va(0, 0, 0); + btRigidBody* rigidCol = 0; + btMultiBodyLinkCollider* multibodyLinkCol = 0; + + // grab the velocity of the rigid body + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * m_dt : btVector3(0, 0, 0); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + findJacobian(multibodyLinkCol, jacobianData_normal, c.m_node->m_x, cti.m_normal); + btScalar vel = 0.0; + const btScalar* jac = &jacobianData_normal.m_jacobians[0]; + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + for (int j = 0; j < ndof; ++j) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + std::cout << multibodyLinkCol->m_multiBody->getVelocityVector()[j] << std::endl; + std::cout << jac[j] << std::endl; + } + va = cti.m_normal * vel * m_dt; + } + } + + const btVector3 vb = c.m_node->m_v * m_dt; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, cti.m_normal); + if (dn < SIMD_EPSILON) + { + // find complementary jacobian + btVector3 complementaryDirection; + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + complementaryDirection = generateUnitOrthogonalVector(cti.m_normal); + findJacobian(multibodyLinkCol, jacobianData_complementary, c.m_node->m_x, complementaryDirection); + } + } + + if (m_constraints.find(c.m_node) == m_constraints.end()) + { + btAlignedObjectArray constraints; + constraints.push_back(DeformableContactConstraint(c, jacobianData_normal)); + m_constraints[c.m_node] = constraints; + btAlignedObjectArray frictions; + frictions.push_back(DeformableFrictionConstraint(complementaryDirection, jacobianData_complementary)); + m_frictions[c.m_node] = frictions; + } + else + { + // group colinear constraints into one + const btScalar angle_epsilon = 0.015192247; // less than 10 degree + bool merged = false; + btAlignedObjectArray& constraints = m_constraints[c.m_node]; + btAlignedObjectArray& frictions = m_frictions[c.m_node]; + for (int j = 0; j < constraints.size(); ++j) + { + const btAlignedObjectArray& dirs = constraints[j].m_direction; + btScalar dot_prod = dirs[0].dot(cti.m_normal); + if (std::abs(std::abs(dot_prod) - 1) < angle_epsilon) + { + // group the constraints + constraints[j].append(c, jacobianData_normal); + // push in an empty friction + frictions[j].append(); + frictions[j].addJacobian(complementaryDirection, jacobianData_complementary); + merged = true; + break; + } + } + const int dim = 3; + // hard coded no more than 3 constraint directions + if (!merged && constraints.size() < dim) + { + constraints.push_back(DeformableContactConstraint(c, jacobianData_normal)); + frictions.push_back(DeformableFrictionConstraint(complementaryDirection, jacobianData_complementary)); + } + } + } + } + } + } +} + +void btDeformableContactProjection::enforceConstraint(TVStack& x) +{ + const int dim = 3; + for (auto& it : m_constraints) + { + const btAlignedObjectArray& constraints = it.second; + size_t i = m_indices[it.first]; + const btAlignedObjectArray& frictions = m_frictions[it.first]; + btAssert(constraints.size() <= dim); + btAssert(constraints.size() > 0); + if (constraints.size() == 1) + { + x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; + for (int j = 0; j < constraints[0].m_direction.size(); ++j) + x[i] += constraints[0].m_value[j] * constraints[0].m_direction[j]; + } + else if (constraints.size() == 2) + { + btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); + btAssert(free_dir.norm() > SIMD_EPSILON) + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; + for (int j = 0; j < constraints.size(); ++j) + { + for (int k = 0; k < constraints[j].m_direction.size(); ++k) + { + x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; + } + } + + } + else + { + x[i].setZero(); + for (int j = 0; j < constraints.size(); ++j) + { + for (int k = 0; k < constraints[j].m_direction.size(); ++k) + { + x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; + } + } + } + + // apply friction if the node is not constrained in all directions + if (constraints.size() < 3) + { + for (int f = 0; f < frictions.size(); ++f) + { + const DeformableFrictionConstraint& friction= frictions[f]; + for (int j = 0; j < friction.m_direction.size(); ++j) + { + // clear the old constraint + if (friction.m_static_prev[j] == true) + { + x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; + } + // add the new constraint + if (friction.m_static[j] == true) + { + x[i] += friction.m_direction[j] * friction.m_dv[j]; + } + } + } + } + } +} + +void btDeformableContactProjection::project(TVStack& x) +{ + const int dim = 3; + for (auto& it : m_constraints) + { + const btAlignedObjectArray& constraints = it.second; + size_t i = m_indices[it.first]; + btAlignedObjectArray& frictions = m_frictions[it.first]; + btAssert(constraints.size() <= dim); + btAssert(constraints.size() > 0); + if (constraints.size() == 1) + { + x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; + } + else if (constraints.size() == 2) + { + btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); + btAssert(free_dir.norm() > SIMD_EPSILON) + free_dir.normalize(); + x[i] = x[i].dot(free_dir) * free_dir; + } + else + x[i].setZero(); + + // apply friction if the node is not constrained in all directions + if (constraints.size() < 3) + { + bool has_static_constraint = false; + for (int f = 0; f < frictions.size(); ++f) + { + DeformableFrictionConstraint& friction= frictions[f]; + for (int j = 0; j < friction.m_static.size(); ++j) + has_static_constraint = has_static_constraint || friction.m_static[j]; + } + + for (int f = 0; f < frictions.size(); ++f) + { + DeformableFrictionConstraint& friction= frictions[f]; + for (int j = 0; j < friction.m_direction.size(); ++j) + { + // clear the old friction force + if (friction.m_static_prev[j] == false) + { + x[i] -= friction.m_direction_prev[j] * friction.m_impulse_prev[j]; + } + + // only add to the rhs if there is no static friction constraint on the node + if (friction.m_static[j] == false && !has_static_constraint) + { + x[i] += friction.m_direction[j] * friction.m_impulse[j]; + } + } + } + } + } +} + +void btDeformableContactProjection::reinitialize(bool nodeUpdated) +{ + btCGProjection::reinitialize(nodeUpdated); + m_constraints.clear(); + m_frictions.clear(); +} + + + diff --git a/src/BulletSoftBody/btContactProjection.h b/src/BulletSoftBody/btDeformableContactProjection.h similarity index 52% rename from src/BulletSoftBody/btContactProjection.h rename to src/BulletSoftBody/btDeformableContactProjection.h index 725cc106b..aa7af70fb 100644 --- a/src/BulletSoftBody/btContactProjection.h +++ b/src/BulletSoftBody/btDeformableContactProjection.h @@ -1,5 +1,5 @@ // -// btContactProjection.h +// btDeformableContactProjection.h // BulletSoftBody // // Created by Xuchen Han on 7/4/19. @@ -12,27 +12,32 @@ #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" #include -class btContactProjection : public btCGProjection +class btDeformableContactProjection : public btCGProjection { public: - btContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt) + std::unordered_map > m_constraints; + std::unordered_map > m_frictions; + + btDeformableContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : btCGProjection(softBodies, dt) { } - virtual ~btContactProjection() + virtual ~btDeformableContactProjection() { } // apply the constraints to the rhs - virtual void operator()(TVStack& x); + virtual void project(TVStack& x); // apply constraints to x in Ax=b virtual void enforceConstraint(TVStack& x); // update the constraints - virtual void update(const TVStack& dv, const TVStack& backupVelocity); + virtual void update(); virtual void setConstraints(); + + virtual void reinitialize(bool nodeUpdated); }; #endif /* btContactProjection_h */ diff --git a/src/BulletSoftBody/btDeformableGravityForce.h b/src/BulletSoftBody/btDeformableGravityForce.h new file mode 100644 index 000000000..545615a47 --- /dev/null +++ b/src/BulletSoftBody/btDeformableGravityForce.h @@ -0,0 +1,60 @@ +// +// btDeformableGravityForce.h +// BulletSoftBody +// +// Created by Xuchen Han on 7/21/19. +// + +#ifndef BT_DEFORMABLE_GRAVITY_FORCE_H +#define BT_DEFORMABLE_GRAVITY_FORCE_H + +#include "btDeformableLagrangianForce.h" + +class btDeformableGravityForce : public btDeformableLagrangianForce +{ +public: + using TVStack = btDeformableLagrangianForce::TVStack; + btVector3 m_gravity; + + btDeformableGravityForce(const btAlignedObjectArray& softBodies, const btVector3& g) : btDeformableLagrangianForce(softBodies), m_gravity(g) + { + + } + + virtual void addScaledImplicitForce(btScalar scale, TVStack& force) + { + } + + virtual void addScaledExplicitForce(btScalar scale, TVStack& force) + { + addScaledGravityForce(scale, force); + } + + virtual void addScaledForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) + { + + } + + virtual void addScaledGravityForce(btScalar scale, TVStack& force) + { + int numNodes = getNumNodes(); + btAssert(numNodes == force.size()) + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + btSoftBody::Node& n = psb->m_nodes[j]; + size_t id = m_indices[&n]; + btScalar mass = (n.m_im == 0) ? 0 : 1. / n.m_im; + btVector3 scaled_force = scale * m_gravity * mass; + force[id] += scaled_force; + } + } + } + + + + +}; +#endif /* BT_DEFORMABLE_GRAVITY_FORCE_H */ diff --git a/src/BulletSoftBody/btLagrangianForce.h b/src/BulletSoftBody/btDeformableLagrangianForce.h similarity index 58% rename from src/BulletSoftBody/btLagrangianForce.h rename to src/BulletSoftBody/btDeformableLagrangianForce.h index b95a30ce9..acb9a28ff 100644 --- a/src/BulletSoftBody/btLagrangianForce.h +++ b/src/BulletSoftBody/btDeformableLagrangianForce.h @@ -1,35 +1,33 @@ // -// btLagrangianForce.h +// btDeformableLagrangianForce.h // BulletSoftBody // // Created by Xuchen Han on 7/1/19. // -#ifndef BT_LAGRANGIAN_FORCE_H -#define BT_LAGRANGIAN_FORCE_H +#ifndef BT_DEFORMABLE_LAGRANGIAN_FORCE_H +#define BT_DEFORMABLE_LAGRANGIAN_FORCE_H #include "btSoftBody.h" #include -class btLagrangianForce +class btDeformableLagrangianForce { public: using TVStack = btAlignedObjectArray; const btAlignedObjectArray& m_softBodies; std::unordered_map m_indices; - btLagrangianForce(const btAlignedObjectArray& softBodies) + btDeformableLagrangianForce(const btAlignedObjectArray& softBodies) : m_softBodies(softBodies) { } - virtual ~btLagrangianForce(){} + virtual ~btDeformableLagrangianForce(){} virtual void addScaledImplicitForce(btScalar scale, TVStack& force) = 0; - virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) = 0; - - virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) = 0; + virtual void addScaledForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) = 0; virtual void addScaledExplicitForce(btScalar scale, TVStack& force) = 0; @@ -39,7 +37,7 @@ public: updateId(); } - void updateId() + virtual void updateId() { size_t index = 0; for (int i = 0; i < m_softBodies.size(); ++i) @@ -51,5 +49,15 @@ public: } } } + + virtual int getNumNodes() + { + int numNodes = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + numNodes += m_softBodies[i]->m_nodes.size(); + } + return numNodes; + } }; -#endif /* btLagrangianForce_h */ +#endif /* BT_DEFORMABLE_LAGRANGIAN_FORCE */ diff --git a/src/BulletSoftBody/btMassSpring.h b/src/BulletSoftBody/btDeformableMassSpringForce.h similarity index 65% rename from src/BulletSoftBody/btMassSpring.h rename to src/BulletSoftBody/btDeformableMassSpringForce.h index 78cdcf7e6..31389c20f 100644 --- a/src/BulletSoftBody/btMassSpring.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -1,20 +1,20 @@ // -// btMassSpring.h +// btDeformableMassSpringForce.h // BulletSoftBody // -// Created by Chuyuan Fu on 7/1/19. +// Created by Xuchen Gan on 7/1/19. // #ifndef BT_MASS_SPRING_H #define BT_MASS_SPRING_H -#include "btLagrangianForce.h" +#include "btDeformableLagrangianForce.h" -class btMassSpring : public btLagrangianForce +class btDeformableMassSpringForce : public btDeformableLagrangianForce { public: - using TVStack = btLagrangianForce::TVStack; - btMassSpring(const btAlignedObjectArray& softBodies) : btLagrangianForce(softBodies) + using TVStack = btDeformableLagrangianForce::TVStack; + btDeformableMassSpringForce(const btAlignedObjectArray& softBodies) : btDeformableLagrangianForce(softBodies) { } @@ -72,10 +72,6 @@ public: size_t id2 = m_indices[node2]; // elastic force - - // fully implicit -// btVector3 dir = (node2->m_x - node1->m_x); - // explicit elastic force btVector3 dir = (node2->m_q - node1->m_q); btVector3 dir_normalized = dir.normalized(); @@ -86,33 +82,7 @@ public: } } - virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) - { - int numNodes = getNumNodes(); - btAssert(numNodes == dx.size()); - btAssert(numNodes == df.size()); - - // implicit elastic force differential - for (int i = 0; i < m_softBodies.size(); ++i) - { - const btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_links.size(); ++j) - { - const auto& link = psb->m_links[j]; - const auto node1 = link.m_n[0]; - const auto node2 = link.m_n[1]; - btScalar kLST = link.Feature::m_material->m_kLST; - size_t id1 = m_indices[node1]; - size_t id2 = m_indices[node2]; - btVector3 local_scaled_df = scale * kLST * (dx[id2] - dx[id1]); - df[id1] += local_scaled_df; - df[id2] -= local_scaled_df; - } - } - } - - - virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) + virtual void addScaledForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) { // implicit damping force differential for (int i = 0; i < m_softBodies.size(); ++i) @@ -132,16 +102,6 @@ public: } } } - - int getNumNodes() - { - int numNodes = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - numNodes += m_softBodies[i]->m_nodes.size(); - } - return numNodes; - } }; #endif /* btMassSpring_h */ diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 173f71206..3af3c8499 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -12,87 +12,78 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { - m_internalTime += timeStep; - // Let the solver grab the soft bodies and if necessary optimize for it - m_deformableBodySolver->optimize(m_softBodies); + reinitialize(timeStep); - if (!m_deformableBodySolver->checkInitialized()) - { - btAssert("Solver initialization failed\n"); - } - - // from btDiscreteDynamicsWorld singleStepSimulation - if (0 != m_internalPreTickCallback) - { - (*m_internalPreTickCallback)(this, timeStep); - } + // add gravity to velocity of rigid and multi bodys + applyRigidBodyGravity(timeStep); - ///apply gravity, predict motion + ///apply gravity and explicit force to velocity, predict motion predictUnconstraintMotion(timeStep); - btDispatcherInfo& dispatchInfo = btMultiBodyDynamicsWorld::getDispatchInfo(); - - dispatchInfo.m_timeStep = timeStep; - dispatchInfo.m_stepCount = 0; - dispatchInfo.m_debugDraw = btMultiBodyDynamicsWorld::getDebugDrawer(); - - // only used in CCD -// createPredictiveContacts(timeStep); - ///perform collision detection btMultiBodyDynamicsWorld::performDiscreteCollisionDetection(); btMultiBodyDynamicsWorld::calculateSimulationIslands(); - btMultiBodyDynamicsWorld::getSolverInfo().m_timeStep = timeStep; - - if (0 != m_internalTickCallback) - { - (*m_internalTickCallback)(this, timeStep); - } + beforeSolverCallbacks(timeStep); - // TODO: This is an ugly hack to get the desired gravity behavior. - // gravity is applied in stepSimulation and then cleared here and then applied here and then cleared here again - // so that 1) gravity is applied to velocity before constraint solve and 2) gravity is applied in each substep - // when there are multiple substeps - clearForces(); - clearMultiBodyForces(); - btMultiBodyDynamicsWorld::applyGravity(); - // integrate rigid body gravity - for (int i = 0; i < m_nonStaticRigidBodies.size(); ++i) - { - btRigidBody* rb = m_nonStaticRigidBodies[i]; - rb->integrateVelocities(timeStep); - } - // integrate multibody gravity - btMultiBodyDynamicsWorld::solveExternalForces(btMultiBodyDynamicsWorld::getSolverInfo()); - clearForces(); - clearMultiBodyForces(); - - - for (int i = 0; i < before_solver_callbacks.size(); ++i) - before_solver_callbacks[i](m_internalTime, this); ///solve deformable bodies constraints solveDeformableBodiesConstraints(timeStep); - + positionCorrection(); - //integrate transforms - btMultiBodyDynamicsWorld::integrateTransforms(timeStep); + integrateTransforms(timeStep); ///update vehicle simulation btMultiBodyDynamicsWorld::updateActions(timeStep); btMultiBodyDynamicsWorld::updateActivationState(timeStep); - - ///update soft bodies - m_deformableBodySolver->updateSoftBodies(); - - clearForces(); // End solver-wise simulation step // /////////////////////////////// } +void btDeformableRigidDynamicsWorld::positionCorrection() +{ + // perform position correction for all geometric collisions + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + const btScalar mrg = psb->getCollisionShape()->getMargin(); + for (int j = 0; j < psb->m_rcontacts.size(); ++j) + { + const btSoftBody::RContact& c = psb->m_rcontacts[j]; + // skip anchor points + if (c.m_node->m_im == 0) + continue; + + const btSoftBody::sCti& cti = c.m_cti; + if (cti.m_colObj->hasContactResponse()) + { + btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); + if (dp < 0) + { + // m_c4 is the collision hardness + c.m_node->m_q -= dp * cti.m_normal * c.m_c4; + } + } + } + } +} + +void btDeformableRigidDynamicsWorld::integrateTransforms(btScalar dt) +{ + btMultiBodyDynamicsWorld::integrateTransforms(dt); + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + auto& node = psb->m_nodes[j]; + node.m_x = node.m_q + dt * node.m_v; + } + } +} + void btDeformableRigidDynamicsWorld::solveDeformableBodiesConstraints(btScalar timeStep) { m_deformableBodySolver->solveConstraints(timeStep); @@ -117,4 +108,45 @@ void btDeformableRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep m_deformableBodySolver->predictMotion(float(timeStep)); } +void btDeformableRigidDynamicsWorld::reinitialize(btScalar timeStep) +{ + m_internalTime += timeStep; + m_deformableBodySolver->reinitialize(m_softBodies); + btDispatcherInfo& dispatchInfo = btMultiBodyDynamicsWorld::getDispatchInfo(); + dispatchInfo.m_timeStep = timeStep; + dispatchInfo.m_stepCount = 0; + dispatchInfo.m_debugDraw = btMultiBodyDynamicsWorld::getDebugDrawer(); + btMultiBodyDynamicsWorld::getSolverInfo().m_timeStep = timeStep; +} +void btDeformableRigidDynamicsWorld::applyRigidBodyGravity(btScalar timeStep) +{ + // TODO: This is an ugly hack to get the desired gravity behavior. + // gravity is applied in stepSimulation and then cleared here and then applied here and then cleared here again + // so that 1) gravity is applied to velocity before constraint solve and 2) gravity is applied in each substep + // when there are multiple substeps + clearForces(); + clearMultiBodyForces(); + btMultiBodyDynamicsWorld::applyGravity(); + // integrate rigid body gravity + for (int i = 0; i < m_nonStaticRigidBodies.size(); ++i) + { + btRigidBody* rb = m_nonStaticRigidBodies[i]; + rb->integrateVelocities(timeStep); + } + // integrate multibody gravity + btMultiBodyDynamicsWorld::solveExternalForces(btMultiBodyDynamicsWorld::getSolverInfo()); + clearForces(); + clearMultiBodyForces(); +} + +void btDeformableRigidDynamicsWorld::beforeSolverCallbacks(btScalar timeStep) +{ + if (0 != m_internalTickCallback) + { + (*m_internalTickCallback)(this, timeStep); + } + + for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) + m_beforeSolverCallbacks[i](m_internalTime, this); +} diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 5bbebeda3..c5cf280ef 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -17,15 +17,15 @@ #define BT_DEFORMABLE_RIGID_DYNAMICS_WORLD_H #include "btSoftMultiBodyDynamicsWorld.h" -#include "btLagrangianForce.h" -#include "btMassSpring.h" +#include "btDeformableLagrangianForce.h" +#include "btDeformableMassSpringForce.h" #include "btDeformableBodySolver.h" #include "btSoftBodyHelpers.h" #include typedef btAlignedObjectArray btSoftBodyArray; class btDeformableBodySolver; -class btLagrangianForce; +class btDeformableLagrangianForce; typedef btAlignedObjectArray btSoftBodyArray; class btDeformableRigidDynamicsWorld : public btMultiBodyDynamicsWorld @@ -45,6 +45,10 @@ class btDeformableRigidDynamicsWorld : public btMultiBodyDynamicsWorld protected: virtual void internalSingleStepSimulation(btScalar timeStep); + virtual void integrateTransforms(btScalar timeStep); + + void positionCorrection(); + void solveDeformableBodiesConstraints(btScalar timeStep); public: @@ -70,7 +74,7 @@ public: m_sbi.m_sparsesdf.Initialize(); m_internalTime = 0.0; } - btAlignedObjectArray > before_solver_callbacks; + btAlignedObjectArray > m_beforeSolverCallbacks; virtual ~btDeformableRigidDynamicsWorld() { } @@ -108,10 +112,18 @@ public: { return m_sbi; } + const btSoftBodyWorldInfo& getWorldInfo() const { return m_sbi; } + + void reinitialize(btScalar timeStep); + + void applyRigidBodyGravity(btScalar timeStep); + + void beforeSolverCallbacks(btScalar timeStep); + int getDrawFlags() const { return (m_drawFlags); } void setDrawFlags(int f) { m_drawFlags = f; } }; diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 974246448..876b6b6e4 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -1782,7 +1782,7 @@ void btSoftBody::predictMotion(btScalar dt) m_sst.radmrg = getCollisionShape()->getMargin(); m_sst.updmrg = m_sst.radmrg * (btScalar)0.25; /* Forces */ - addVelocity(m_worldInfo->m_gravity * m_sst.sdt); +// addVelocity(m_worldInfo->m_gravity * m_sst.sdt); applyForces(); /* Integrate */ for (i = 0, ni = m_nodes.size(); i < ni; ++i) @@ -1806,7 +1806,7 @@ void btSoftBody::predictMotion(btScalar dt) } } n.m_v += deltaV; - n.m_x += n.m_v * m_sst.sdt; + n.m_x += n.m_v * m_sst.sdt; n.m_f = btVector3(0, 0, 0); } /* Clusters */ @@ -2270,10 +2270,11 @@ bool btSoftBody::checkContact(const btCollisionObjectWrapper* colObjWrap, { btVector3 nrm; const btCollisionShape* shp = colObjWrap->getCollisionShape(); - // const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); - //const btTransform &wtr = tmpRigid ? tmpRigid->getWorldTransform() : colObjWrap->getWorldTransform(); - const btTransform& wtr = colObjWrap->getWorldTransform(); - //todo: check which transform is needed here + const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); + + // get the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg + const btTransform &wtr = tmpRigid ? tmpRigid->getInterpolationWorldTransform() : colObjWrap->getWorldTransform(); + // TODO: get the correct transform for multibody btScalar dst = m_worldInfo->m_sparsesdf.Evaluate( From 243b9fc8c7e4727eb42947389a99c0254d16032d Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Tue, 23 Jul 2019 12:15:23 -0700 Subject: [PATCH 21/47] combat friction drift in positionCorrect by changing velocity and change it back (effectively only changing position) --- .../DeformableContact/DeformableContact.cpp | 23 ++- examples/DeformableDemo/DeformableDemo.cpp | 21 +-- examples/Pinch/Pinch.cpp | 136 +++++++++++++++--- .../VolumetricDeformable.cpp | 4 +- .../btSimulationIslandManager.cpp | 7 +- src/BulletSoftBody/btContactProjection.cpp | 54 +++---- src/BulletSoftBody/btDeformableBodySolver.cpp | 15 ++ src/BulletSoftBody/btDeformableBodySolver.h | 6 +- .../btDeformableContactProjection.cpp | 91 ++++++------ src/BulletSoftBody/btDeformableGravityForce.h | 1 + .../btDeformableMassSpringForce.h | 3 + .../btDeformableRigidDynamicsWorld.cpp | 67 ++++++--- .../btDeformableRigidDynamicsWorld.h | 4 +- src/BulletSoftBody/btSoftBody.cpp | 3 +- src/BulletSoftBody/btSoftBodyInternals.h | 8 +- 15 files changed, 291 insertions(+), 152 deletions(-) diff --git a/examples/DeformableContact/DeformableContact.cpp b/examples/DeformableContact/DeformableContact.cpp index b70751e2f..a43fc04ca 100644 --- a/examples/DeformableContact/DeformableContact.cpp +++ b/examples/DeformableContact/DeformableContact.cpp @@ -54,13 +54,6 @@ class DeformableContact : public CommonMultiBodyBase btMultiBody* m_multiBody; btAlignedObjectArray m_jointFeedbacks; public: - - struct TetraBunny - { - #include "../SoftDemo/bunny.inl" - }; - - DeformableContact(struct GUIHelperInterface* helper) : CommonMultiBodyBase(helper) { @@ -147,7 +140,7 @@ void DeformableContact::initPhysics() btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0, -40, 0)); - groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0)); + groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.1)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: btScalar mass(0.); @@ -170,16 +163,16 @@ void DeformableContact::initPhysics() { - bool damping = true; - bool gyro = true; - int numLinks = 3; + bool damping = false; + bool gyro = false; + int numLinks = 0; bool spherical = true; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals bool canSleep = false; bool selfCollide = true; btVector3 linkHalfExtents(1, 1, 1); btVector3 baseHalfExtents(1, 1, 1); - btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 10.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase); + btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 2.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase); mbC->setCanSleep(canSleep); mbC->setHasSelfCollision(selfCollide); @@ -216,12 +209,13 @@ void DeformableContact::initPhysics() // create a patch of cloth { - const btScalar s = 6; + const btScalar s = 4; btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), btVector3(+s, 0, -s), btVector3(-s, 0, +s), btVector3(+s, 0, +s), - 20,20, +// 20,20, + 3,3, 1 + 2 + 4 + 8, true); psb->getCollisionShape()->setMargin(0.25); @@ -232,7 +226,6 @@ void DeformableContact::initPhysics() psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = 0; getDeformableDynamicsWorld()->addSoftBody(psb); - } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); diff --git a/examples/DeformableDemo/DeformableDemo.cpp b/examples/DeformableDemo/DeformableDemo.cpp index 7ce94a314..aa58fbd6f 100644 --- a/examples/DeformableDemo/DeformableDemo.cpp +++ b/examples/DeformableDemo/DeformableDemo.cpp @@ -105,15 +105,15 @@ public: // } btTransform startTransform; startTransform.setIdentity(); - startTransform.setOrigin(btVector3(1, 2, 1)); + startTransform.setOrigin(btVector3(1, 1.5, 1)); createRigidBody(mass, startTransform, shape[0]); - startTransform.setOrigin(btVector3(1, 2, -1)); + startTransform.setOrigin(btVector3(1, 1.5, -1)); createRigidBody(mass, startTransform, shape[0]); - startTransform.setOrigin(btVector3(-1, 2, 1)); + startTransform.setOrigin(btVector3(-1, 1.5, 1)); createRigidBody(mass, startTransform, shape[0]); - startTransform.setOrigin(btVector3(-1, 2, -1)); + startTransform.setOrigin(btVector3(-1, 1.5, -1)); createRigidBody(mass, startTransform, shape[0]); - startTransform.setOrigin(btVector3(0, 4, 0)); + startTransform.setOrigin(btVector3(0, 3.5, 0)); createRigidBody(mass, startTransform, shape[0]); } @@ -182,7 +182,7 @@ void DeformableDemo::initPhysics() btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0, -30, 0)); + groundTransform.setOrigin(btVector3(0, -32, 0)); groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: btScalar mass(0.); @@ -206,7 +206,7 @@ void DeformableDemo::initPhysics() // create a piece of cloth { - bool onGround = true; + bool onGround = false; const btScalar s = 4; btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), btVector3(+s, 0, -s), @@ -222,13 +222,14 @@ void DeformableDemo::initPhysics() btVector3(+s, 0, -s), btVector3(-s, 0, +s), btVector3(+s, 0, +s), - 20,20, +// 20,20, + 2,2, 0, true); psb->getCollisionShape()->setMargin(0.1); psb->generateBendingConstraints(2); - psb->setTotalMass(10); - psb->setSpringStiffness(10); + psb->setTotalMass(1); + psb->setSpringStiffness(1); psb->setDampingCoefficient(0.01); psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body diff --git a/examples/Pinch/Pinch.cpp b/examples/Pinch/Pinch.cpp index cedc51750..cc3008f9c 100644 --- a/examples/Pinch/Pinch.cpp +++ b/examples/Pinch/Pinch.cpp @@ -73,9 +73,9 @@ public: void resetCamera() { float dist = 25; - float pitch = -45; + float pitch = -30; float yaw = 100; - float targetPos[3] = {0, -3, 0}; + float targetPos[3] = {0, -0, 0}; m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } @@ -137,17 +137,56 @@ void dynamics(btScalar time, btDeformableRigidDynamicsWorld* world) return; btRigidBody* rb0 = rbs[0]; btScalar pressTime = 0.9; + btScalar liftTime = 2.5; + btScalar shiftTime = 3.5; + btScalar holdTime = 4.5*1000; + btScalar dropTime = 5.3*1000; btTransform rbTransform; rbTransform.setIdentity(); - btVector3 translation = btVector3(0.5,3,4); - btVector3 velocity = btVector3(0,5,0); + btVector3 translation; + btVector3 velocity; + + btVector3 initialTranslationLeft = btVector3(0.5,3,4); + btVector3 initialTranslationRight = btVector3(0.5,3,-4); + btVector3 pinchVelocityLeft = btVector3(0,0,-2); + btVector3 pinchVelocityRight = btVector3(0,0,2); + btVector3 liftVelocity = btVector3(0,5,0); + btVector3 shiftVelocity = btVector3(0,0,5); + btVector3 holdVelocity = btVector3(0,0,0); + btVector3 openVelocityLeft = btVector3(0,0,4); + btVector3 openVelocityRight = btVector3(0,0,-4); + if (time < pressTime) { - velocity = btVector3(0,0,-2); - translation += velocity * time; + velocity = pinchVelocityLeft; + translation = initialTranslationLeft + pinchVelocityLeft * time; + } + else if (time < liftTime) + { + velocity = liftVelocity; + translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (time - pressTime); + + } + else if (time < shiftTime) + { + velocity = shiftVelocity; + translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime); + } + else if (time < holdTime) + { + velocity = btVector3(0,0,0); + translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime); + } + else if (time < dropTime) + { + velocity = openVelocityLeft; + translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (time - holdTime); } else - translation += btVector3(0,0,-2) * pressTime + (time-pressTime)*velocity; + { + velocity = holdVelocity; + translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (dropTime - holdTime); + } rbTransform.setOrigin(translation); rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0)); rb0->setCenterOfMassTransform(rbTransform); @@ -155,23 +194,45 @@ void dynamics(btScalar time, btDeformableRigidDynamicsWorld* world) rb0->setLinearVelocity(velocity); btRigidBody* rb1 = rbs[1]; - translation = btVector3(0.5,3,-4); - velocity = btVector3(0,5,0); if (time < pressTime) { - velocity = btVector3(0,0,2); - translation += velocity * time; + velocity = pinchVelocityRight; + translation = initialTranslationRight + pinchVelocityRight * time; + } + else if (time < liftTime) + { + velocity = liftVelocity; + translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (time - pressTime); + + } + else if (time < shiftTime) + { + velocity = shiftVelocity; + translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime); + } + else if (time < holdTime) + { + velocity = btVector3(0,0,0); + translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime); + } + else if (time < dropTime) + { + velocity = openVelocityRight; + translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (time - holdTime); } else - translation += btVector3(0,0,2) * pressTime + (time-pressTime)*velocity; + { + velocity = holdVelocity; + translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (dropTime - holdTime); + } rbTransform.setOrigin(translation); rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0)); rb1->setCenterOfMassTransform(rbTransform); rb1->setAngularVelocity(btVector3(0,0,0)); rb1->setLinearVelocity(velocity); - rb0->setFriction(2); - rb1->setFriction(2); + rb0->setFriction(20); + rb1->setFriction(20); } void Pinch::initPhysics() @@ -194,7 +255,7 @@ void Pinch::initPhysics() m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); - getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics); + getDeformableDynamicsWorld()->m_beforeSolverCallbacks.push_back(dynamics); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); //create a ground @@ -229,21 +290,58 @@ void Pinch::initPhysics() // create a soft block { + btScalar verts[24] = {0.f, 0.f, 0.f, + 1.f, 0.f, 0.f, + 0.f, 1.f, 0.f, + 0.f, 0.f, 1.f, + 1.f, 1.f, 0.f, + 0.f, 1.f, 1.f, + 1.f, 0.f, 1.f, + 1.f, 1.f, 1.f + }; + int triangles[60] = {0, 6, 3, + 0,1,6, + 7,5,3, + 7,3,6, + 4,7,6, + 4,6,1, + 7,2,5, + 7,4,2, + 0,3,2, + 2,3,5, + 0,2,4, + 0,4,1, + 0,6,5, + 0,6,4, + 3,4,2, + 3,4,7, + 2,7,3, + 2,7,1, + 4,5,0, + 4,5,6, + }; +// btSoftBody* psb = btSoftBodyHelpers::CreateFromTriMesh(getDeformableDynamicsWorld()->getWorldInfo(), &verts[0], &triangles[0], 20); +//// btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(), TetraCube::getElements(), 0, TetraCube::getNodes(), false, true, true); - getDeformableDynamicsWorld()->addSoftBody(psb); + psb->scale(btVector3(2, 2, 2)); psb->translate(btVector3(0, 4, 0)); psb->getCollisionShape()->setMargin(0.1); psb->setTotalMass(1); - psb->setSpringStiffness(10); - psb->setDampingCoefficient(0.01); +// psb->scale(btVector3(5, 5, 5)); +// psb->translate(btVector3(-2.5, 4, -2.5)); +// psb->getCollisionShape()->setMargin(0.1); +// psb->setTotalMass(1); + psb->setSpringStiffness(4); + psb->setDampingCoefficient(0.02); psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body - psb->m_cfg.kDF = 0.5; + psb->m_cfg.kDF = 2; + getDeformableDynamicsWorld()->addSoftBody(psb); // add a grippers createGrip(); } diff --git a/examples/VolumetricDeformable/VolumetricDeformable.cpp b/examples/VolumetricDeformable/VolumetricDeformable.cpp index b30e9bc24..9bcf63ab2 100644 --- a/examples/VolumetricDeformable/VolumetricDeformable.cpp +++ b/examples/VolumetricDeformable/VolumetricDeformable.cpp @@ -77,8 +77,8 @@ public: void stepSimulation(float deltaTime) { //use a smaller internal timestep, there are stability issues - float internalTimeStep = 1. / 240.f; - m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep); + float internalTimeStep = 1. / 480.f; + m_dynamicsWorld->stepSimulation(deltaTime, 8, internalTimeStep); } void createStaticBox(const btVector3& halfEdge, const btVector3& translation) diff --git a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp index e5097ccbb..11fa97cdd 100644 --- a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp +++ b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp @@ -233,7 +233,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher, btCollisi // printf("error in island management\n"); } - btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); +// btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { if (colObj0->getActivationState() == ACTIVE_TAG || @@ -257,7 +257,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher, btCollisi // printf("error in island management\n"); } - btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); +// btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { @@ -278,7 +278,8 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher, btCollisi // printf("error in island management\n"); } - btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); +// btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + if (colObj0->getIslandTag() == islandId) { diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp index 99ab6f473..e81cb2c50 100644 --- a/src/BulletSoftBody/btContactProjection.cpp +++ b/src/BulletSoftBody/btContactProjection.cpp @@ -50,12 +50,12 @@ void btDeformableContactProjection::update() // loop through constraints to set constrained values for (auto& it : m_constraints) { - btAlignedObjectArray& frictions = m_frictions[it.first]; - btAlignedObjectArray& constraints = it.second; + btAlignedObjectArray& frictions = m_frictions[it.first]; + btAlignedObjectArray& constraints = it.second; for (int i = 0; i < constraints.size(); ++i) { - Constraint& constraint = constraints[i]; - Friction& friction = frictions[i]; + DeformableContactConstraint& constraint = constraints[i]; + DeformableFrictionConstraint& friction = frictions[i]; for (int j = 0; j < constraint.m_contact.size(); ++j) { if (constraint.m_contact[j] == nullptr) @@ -229,16 +229,16 @@ void btDeformableContactProjection::setConstraints() { if (psb->m_nodes[j].m_im == 0) { - btAlignedObjectArray c; - c.push_back(Constraint(btVector3(1,0,0))); - c.push_back(Constraint(btVector3(0,1,0))); - c.push_back(Constraint(btVector3(0,0,1))); + btAlignedObjectArray c; + c.push_back(DeformableContactConstraint(btVector3(1,0,0))); + c.push_back(DeformableContactConstraint(btVector3(0,1,0))); + c.push_back(DeformableContactConstraint(btVector3(0,0,1))); m_constraints[&(psb->m_nodes[j])] = c; - btAlignedObjectArray f; - f.push_back(Friction()); - f.push_back(Friction()); - f.push_back(Friction()); + btAlignedObjectArray f; + f.push_back(DeformableFrictionConstraint()); + f.push_back(DeformableFrictionConstraint()); + f.push_back(DeformableFrictionConstraint()); m_frictions[&(psb->m_nodes[j])] = f; } } @@ -310,11 +310,11 @@ void btDeformableContactProjection::setConstraints() if (m_constraints.find(c.m_node) == m_constraints.end()) { - btAlignedObjectArray constraints; - constraints.push_back(Constraint(c, jacobianData_normal)); + btAlignedObjectArray constraints; + constraints.push_back(DeformableContactConstraint(c, jacobianData_normal)); m_constraints[c.m_node] = constraints; - btAlignedObjectArray frictions; - frictions.push_back(Friction(complementaryDirection, jacobianData_complementary)); + btAlignedObjectArray frictions; + frictions.push_back(DeformableFrictionConstraint(complementaryDirection, jacobianData_complementary)); m_frictions[c.m_node] = frictions; } else @@ -322,8 +322,8 @@ void btDeformableContactProjection::setConstraints() // group colinear constraints into one const btScalar angle_epsilon = 0.015192247; // less than 10 degree bool merged = false; - btAlignedObjectArray& constraints = m_constraints[c.m_node]; - btAlignedObjectArray& frictions = m_frictions[c.m_node]; + btAlignedObjectArray& constraints = m_constraints[c.m_node]; + btAlignedObjectArray& frictions = m_frictions[c.m_node]; for (int j = 0; j < constraints.size(); ++j) { const btAlignedObjectArray& dirs = constraints[j].m_direction; @@ -343,8 +343,8 @@ void btDeformableContactProjection::setConstraints() // hard coded no more than 3 constraint directions if (!merged && constraints.size() < dim) { - constraints.push_back(Constraint(c, jacobianData_normal)); - frictions.push_back(Friction(complementaryDirection, jacobianData_complementary)); + constraints.push_back(DeformableContactConstraint(c, jacobianData_normal)); + frictions.push_back(DeformableFrictionConstraint(complementaryDirection, jacobianData_complementary)); } } } @@ -358,9 +358,9 @@ void btDeformableContactProjection::enforceConstraint(TVStack& x) const int dim = 3; for (auto& it : m_constraints) { - const btAlignedObjectArray& constraints = it.second; + const btAlignedObjectArray& constraints = it.second; size_t i = m_indices[it.first]; - const btAlignedObjectArray& frictions = m_frictions[it.first]; + const btAlignedObjectArray& frictions = m_frictions[it.first]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); if (constraints.size() == 1) @@ -401,7 +401,7 @@ void btDeformableContactProjection::enforceConstraint(TVStack& x) { for (int f = 0; f < frictions.size(); ++f) { - const Friction& friction= frictions[f]; + const DeformableFrictionConstraint& friction= frictions[f]; for (int j = 0; j < friction.m_direction.size(); ++j) { // clear the old constraint @@ -425,9 +425,9 @@ void btDeformableContactProjection::project(TVStack& x) const int dim = 3; for (auto& it : m_constraints) { - const btAlignedObjectArray& constraints = it.second; + const btAlignedObjectArray& constraints = it.second; size_t i = m_indices[it.first]; - btAlignedObjectArray& frictions = m_frictions[it.first]; + btAlignedObjectArray& frictions = m_frictions[it.first]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); if (constraints.size() == 1) @@ -450,14 +450,14 @@ void btDeformableContactProjection::project(TVStack& x) bool has_static_constraint = false; for (int f = 0; f < frictions.size(); ++f) { - Friction& friction= frictions[f]; + DeformableFrictionConstraint& friction= frictions[f]; for (int j = 0; j < friction.m_static.size(); ++j) has_static_constraint = has_static_constraint || friction.m_static[j]; } for (int f = 0; f < frictions.size(); ++f) { - Friction& friction= frictions[f]; + DeformableFrictionConstraint& friction= frictions[f]; for (int j = 0; j < friction.m_direction.size(); ++j) { // clear the old friction force diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index 96d2e0029..e3009dcbb 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -29,6 +29,7 @@ void btDeformableBodySolver::solveConstraints(float solverdt) // save v_{n+1}^* velocity after explicit forces backupVelocity(); + m_objective->computeResidual(solverdt, m_residual); // m_objective->initialGuess(m_dv, m_residual); computeStep(m_dv, m_residual); @@ -98,6 +99,20 @@ void btDeformableBodySolver::backupVelocity() } } +void btDeformableBodySolver::revertVelocity() +{ + // serial implementation + int counter = 0; + for (int i = 0; i < m_softBodySet.size(); ++i) + { + btSoftBody* psb = m_softBodySet[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + psb->m_nodes[j].m_v = m_backupVelocity[counter++]; + } + } +} + bool btDeformableBodySolver::updateNodes() { int numNodes = 0; diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 570cce90f..0b4a4819f 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -27,12 +27,14 @@ protected: TVStack m_dv; TVStack m_residual; btAlignedObjectArray m_softBodySet; - btDeformableBackwardEulerObjective* m_objective; + btAlignedObjectArray m_backupVelocity; btScalar m_dt; btConjugateGradient cg; public: + btDeformableBackwardEulerObjective* m_objective; + btDeformableBodySolver(); virtual ~btDeformableBodySolver(); @@ -57,7 +59,7 @@ public: void predictDeformableMotion(btSoftBody* psb, btScalar dt); void backupVelocity(); - + void revertVelocity(); void updateVelocity(); bool updateNodes(); diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index e81cb2c50..25f667711 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -143,6 +143,8 @@ void btDeformableContactProjection::update() friction.m_direction[j] = -local_tangent_dir; // do not allow switching from static friction to dynamic friction // it causes cg to explode + btScalar comp1 = -accumulated_normal*c->m_c3; + btScalar comp2 = tangent_norm; if (-accumulated_normal*c->m_c3 < tangent_norm && friction.m_static_prev[j] == false && friction.m_released[j] == false) { friction.m_static[j] = false; @@ -167,49 +169,44 @@ void btDeformableContactProjection::update() // the incremental impulse applied to rb in the tangential direction btVector3 incremental_tangent = (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); - // TODO cleanup - if (1) // in the same CG solve, the set of constraits doesn't change - { - // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - - // dv = new_impulse + accumulated velocity change in previous CG iterations - // so we have the invariant node->m_v = backupVelocity + dv; - btScalar dvn = -accumulated_normal * c->m_c2/m_dt; + // dv = new_impulse + accumulated velocity change in previous CG iterations + // so we have the invariant node->m_v = backupVelocity + dv; + + btScalar dvn = -accumulated_normal * c->m_c2/m_dt; + + // the following is equivalent + /* + btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; + btScalar dvn = dv.dot(cti.m_normal); + */ + + constraint.m_value[j] = dvn; + + // the incremental impulse: + // in the normal direction it's the normal component of "impulse" + // in the tangent direction it's the difference between the frictional impulse in the iteration and the previous iteration + impulse = impulse_normal + incremental_tangent; + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + if (rigidCol) + rigidCol->applyImpulse(impulse, c->m_c1); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { - // the following is equivalent - /* - btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; - btScalar dvn = dv.dot(cti.m_normal); - */ - - constraint.m_value[j] = dvn; - - // the incremental impulse: - // in the normal direction it's the normal component of "impulse" - // in the tangent direction it's the difference between the frictional impulse in the iteration and the previous iteration - impulse = impulse_normal + incremental_tangent; - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - if (rigidCol) - rigidCol->applyImpulse(impulse, c->m_c1); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + if (multibodyLinkCol) { + double multiplier = 1; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_normal, -impulse_normal.length() * multiplier); - if (multibodyLinkCol) + if (incremental_tangent.norm() > SIMD_EPSILON) { - double multiplier = 1; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_normal, -impulse_normal.length() * multiplier); - - if (incremental_tangent.norm() > SIMD_EPSILON) - { - btMultiBodyJacobianData jacobian_tangent; - btVector3 tangent = incremental_tangent.normalized(); - findJacobian(multibodyLinkCol, jacobian_tangent, c->m_node->m_x, tangent); - const btScalar* deltaV_tangent = &jacobian_tangent.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_tangent, incremental_tangent.length() * multiplier); - } + btMultiBodyJacobianData jacobian_tangent; + btVector3 tangent = incremental_tangent.normalized(); + findJacobian(multibodyLinkCol, jacobian_tangent, c->m_node->m_x, tangent); + const btScalar* deltaV_tangent = &jacobian_tangent.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_tangent, incremental_tangent.length() * multiplier); } } } @@ -404,14 +401,10 @@ void btDeformableContactProjection::enforceConstraint(TVStack& x) const DeformableFrictionConstraint& friction= frictions[f]; for (int j = 0; j < friction.m_direction.size(); ++j) { - // clear the old constraint - if (friction.m_static_prev[j] == true) - { - x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; - } - // add the new constraint + // add the friction constraint if (friction.m_static[j] == true) { + x[i] -= x[i].dot(friction.m_direction[j]) * friction.m_direction[j]; x[i] += friction.m_direction[j] * friction.m_dv[j]; } } @@ -467,9 +460,15 @@ void btDeformableContactProjection::project(TVStack& x) } // only add to the rhs if there is no static friction constraint on the node - if (friction.m_static[j] == false && !has_static_constraint) + if (friction.m_static[j] == false) { - x[i] += friction.m_direction[j] * friction.m_impulse[j]; + if (!has_static_constraint) + x[i] += friction.m_direction[j] * friction.m_impulse[j]; + } + else + { + // otherwise clear the constraint in the friction direction + x[i] -= x[i].dot(friction.m_direction[j]) * friction.m_direction[j]; } } } diff --git a/src/BulletSoftBody/btDeformableGravityForce.h b/src/BulletSoftBody/btDeformableGravityForce.h index 545615a47..d8571fa73 100644 --- a/src/BulletSoftBody/btDeformableGravityForce.h +++ b/src/BulletSoftBody/btDeformableGravityForce.h @@ -23,6 +23,7 @@ public: virtual void addScaledImplicitForce(btScalar scale, TVStack& force) { +// addScaledGravityForce(scale, force); } virtual void addScaledExplicitForce(btScalar scale, TVStack& force) diff --git a/src/BulletSoftBody/btDeformableMassSpringForce.h b/src/BulletSoftBody/btDeformableMassSpringForce.h index 31389c20f..70ad6e69c 100644 --- a/src/BulletSoftBody/btDeformableMassSpringForce.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -22,6 +22,7 @@ public: virtual void addScaledImplicitForce(btScalar scale, TVStack& force) { addScaledDampingForce(scale, force); +// addScaledElasticForce(scale, force); } virtual void addScaledExplicitForce(btScalar scale, TVStack& force) @@ -102,6 +103,8 @@ public: } } } + + }; #endif /* btMassSpring_h */ diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 3af3c8499..216c1a24d 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -13,7 +13,7 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { reinitialize(timeStep); - +// beforeSolverCallbacks(timeStep); // add gravity to velocity of rigid and multi bodys applyRigidBodyGravity(timeStep); @@ -30,7 +30,7 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS ///solve deformable bodies constraints solveDeformableBodiesConstraints(timeStep); - positionCorrection(); + afterSolverCallbacks(timeStep); integrateTransforms(timeStep); @@ -42,36 +42,57 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS // /////////////////////////////// } -void btDeformableRigidDynamicsWorld::positionCorrection() +void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) { - // perform position correction for all geometric collisions - for (int i = 0; i < m_softBodies.size(); ++i) + // perform position correction for all constraints + for (auto& it : m_deformableBodySolver->m_objective->projection.m_constraints) { - btSoftBody* psb = m_softBodies[i]; - const btScalar mrg = psb->getCollisionShape()->getMargin(); - for (int j = 0; j < psb->m_rcontacts.size(); ++j) + btAlignedObjectArray& frictions = m_deformableBodySolver->m_objective->projection.m_frictions[it.first]; + btAlignedObjectArray& constraints = it.second; + for (int i = 0; i < constraints.size(); ++i) { - const btSoftBody::RContact& c = psb->m_rcontacts[j]; - // skip anchor points - if (c.m_node->m_im == 0) - continue; - - const btSoftBody::sCti& cti = c.m_cti; - if (cti.m_colObj->hasContactResponse()) + DeformableContactConstraint& constraint = constraints[i]; + DeformableFrictionConstraint& friction = frictions[i]; + for (int j = 0; j < constraint.m_contact.size(); ++j) { - btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); - if (dp < 0) + const btSoftBody::RContact* c = constraint.m_contact[j]; + // skip anchor points + if (c == nullptr || c->m_node->m_im == 0) + continue; + const btSoftBody::sCti& cti = c->m_cti; + btRigidBody* rigidCol = 0; + btVector3 va(0, 0, 0); + + // grab the velocity of the rigid body + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { - // m_c4 is the collision hardness - c.m_node->m_q -= dp * cti.m_normal * c.m_c4; + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c->m_c1)): btVector3(0, 0, 0); + } + + if (cti.m_colObj->hasContactResponse()) + { + btScalar dp = cti.m_offset; + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + if (friction.m_static[j] == true) + { + c->m_node->m_v = va; + } + if (dp < 0) + { + c->m_node->m_v -= dp * cti.m_normal / dt; + } } } } } } + void btDeformableRigidDynamicsWorld::integrateTransforms(btScalar dt) { + m_deformableBodySolver->backupVelocity(); + positionCorrection(dt); btMultiBodyDynamicsWorld::integrateTransforms(dt); for (int i = 0; i < m_softBodies.size(); ++i) { @@ -82,6 +103,7 @@ void btDeformableRigidDynamicsWorld::integrateTransforms(btScalar dt) node.m_x = node.m_q + dt * node.m_v; } } + m_deformableBodySolver->revertVelocity(); } void btDeformableRigidDynamicsWorld::solveDeformableBodiesConstraints(btScalar timeStep) @@ -146,7 +168,12 @@ void btDeformableRigidDynamicsWorld::beforeSolverCallbacks(btScalar timeStep) { (*m_internalTickCallback)(this, timeStep); } - + for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) + m_beforeSolverCallbacks[i](m_internalTime, this); +} + +void btDeformableRigidDynamicsWorld::afterSolverCallbacks(btScalar timeStep) +{ for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) m_beforeSolverCallbacks[i](m_internalTime, this); } diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index c5cf280ef..f1be4fd85 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -47,7 +47,7 @@ protected: virtual void integrateTransforms(btScalar timeStep); - void positionCorrection(); + void positionCorrection(btScalar dt); void solveDeformableBodiesConstraints(btScalar timeStep); @@ -124,6 +124,8 @@ public: void beforeSolverCallbacks(btScalar timeStep); + void afterSolverCallbacks(btScalar timeStep); + int getDrawFlags() const { return (m_drawFlags); } void setDrawFlags(int f) { m_drawFlags = f; } }; diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 876b6b6e4..bd7587c47 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -2286,7 +2286,8 @@ bool btSoftBody::checkContact(const btCollisionObjectWrapper* colObjWrap, { cti.m_colObj = colObjWrap->getCollisionObject(); cti.m_normal = wtr.getBasis() * nrm; - cti.m_offset = -btDot(cti.m_normal, x - cti.m_normal * dst); +// cti.m_offset = -btDot(cti.m_normal, x - cti.m_normal * dst); + cti.m_offset = dst; return (true); } return (false); diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index b892498ea..9b3e45ea4 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -878,15 +878,11 @@ struct btSoftColliders const btScalar ms = ima + imb; if (ms > 0) { + psb->checkContact(m_colObj1Wrap, n.m_q, m, c.m_cti); const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0); const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; - const btVector3 ra = n.m_x - wtr.getOrigin(); - const btVector3 va = m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra) * psb->m_sst.sdt : btVector3(0, 0, 0); - const btVector3 vb = n.m_x - n.m_q; - const btVector3 vr = vb - va; - const btScalar dn = btDot(vr, c.m_cti.m_normal); - const btVector3 fv = vr - c.m_cti.m_normal * dn; + const btVector3 ra = n.m_q - wtr.getOrigin(); const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); c.m_node = &n; c.m_c0 = ImpulseMatrix(psb->m_sst.sdt, ima, imb, iwi, ra); From 233a381e7cc39b1768771f0d3660f985dd1bcf95 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Wed, 24 Jul 2019 16:01:47 -0700 Subject: [PATCH 22/47] add correct impulse matrix to multibody-deformable contact --- .../DeformableContact/DeformableContact.cpp | 46 +- examples/ExampleBrowser/ExampleEntries.cpp | 2 + .../MultiBodyBaseline/MultiBodyBaseline.cpp | 358 +++++++++++++ .../MultiBodyBaseline/MultiBodyBaseline.h | 20 + .../VolumetricDeformable.cpp | 4 +- .../Featherstone/btMultiBodyDynamicsWorld.cpp | 4 + .../Featherstone/btMultiBodyDynamicsWorld.h | 1 + src/BulletSoftBody/btCGProjection.h | 27 +- src/BulletSoftBody/btContactProjection.cpp | 488 ------------------ .../btDeformableContactProjection.cpp | 72 +-- .../btDeformableContactProjection.h | 2 +- .../btDeformableRigidDynamicsWorld.cpp | 37 ++ src/BulletSoftBody/btSoftBody.h | 10 +- src/BulletSoftBody/btSoftBodyInternals.h | 141 ++++- 14 files changed, 618 insertions(+), 594 deletions(-) create mode 100644 examples/MultiBodyBaseline/MultiBodyBaseline.cpp create mode 100644 examples/MultiBodyBaseline/MultiBodyBaseline.h delete mode 100644 src/BulletSoftBody/btContactProjection.cpp diff --git a/examples/DeformableContact/DeformableContact.cpp b/examples/DeformableContact/DeformableContact.cpp index a43fc04ca..f51978ae3 100644 --- a/examples/DeformableContact/DeformableContact.cpp +++ b/examples/DeformableContact/DeformableContact.cpp @@ -69,10 +69,10 @@ public: void resetCamera() { - float dist = 15; + float dist = 30; float pitch = -30; float yaw = 100; - float targetPos[3] = {0, -3, 0}; + float targetPos[3] = {0, -10, 0}; m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } @@ -140,7 +140,7 @@ void DeformableContact::initPhysics() btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0, -40, 0)); - groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.1)); + groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: btScalar mass(0.); @@ -163,16 +163,16 @@ void DeformableContact::initPhysics() { - bool damping = false; + bool damping = true; bool gyro = false; - int numLinks = 0; - bool spherical = true; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals + int numLinks = 4; + bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals bool canSleep = false; bool selfCollide = true; btVector3 linkHalfExtents(1, 1, 1); btVector3 baseHalfExtents(1, 1, 1); - btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 2.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase); + btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 10.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase); mbC->setCanSleep(canSleep); mbC->setHasSelfCollision(selfCollide); @@ -180,13 +180,13 @@ void DeformableContact::initPhysics() // if (!damping) { - mbC->setLinearDamping(0.f); - mbC->setAngularDamping(0.f); + mbC->setLinearDamping(0.0f); + mbC->setAngularDamping(0.0f); } else { - mbC->setLinearDamping(0.1f); - mbC->setAngularDamping(0.9f); + mbC->setLinearDamping(0.04f); + mbC->setAngularDamping(0.04f); } if (numLinks > 0) @@ -209,22 +209,24 @@ void DeformableContact::initPhysics() // create a patch of cloth { + btScalar h = 0; const btScalar s = 4; - btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s), - btVector3(+s, 0, -s), - btVector3(-s, 0, +s), - btVector3(+s, 0, +s), -// 20,20, - 3,3, + btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s), + btVector3(+s, h, -s), + btVector3(-s, h, +s), + btVector3(+s, h, +s), + 20,20, +// 3,3, 1 + 2 + 4 + 8, true); psb->getCollisionShape()->setMargin(0.25); psb->generateBendingConstraints(2); - psb->setTotalMass(.5); + psb->setTotalMass(5); + psb->setSpringStiffness(2); psb->setDampingCoefficient(0.01); psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body - psb->m_cfg.kDF = 0; + psb->m_cfg.kDF = .1; getDeformableDynamicsWorld()->addSoftBody(psb); } @@ -271,7 +273,7 @@ void DeformableContact::exitPhysics() void DeformableContact::stepSimulation(float deltaTime) { // getDeformableDynamicsWorld()->getMultiBodyDynamicsWorld()->stepSimulation(deltaTime); - m_dynamicsWorld->stepSimulation(deltaTime, 4, 1./240.); + m_dynamicsWorld->stepSimulation(deltaTime, 5, 1./250.); } @@ -279,7 +281,7 @@ btMultiBody* DeformableContact::createFeatherstoneMultiBody_testMultiDof(btMulti { //init the base btVector3 baseInertiaDiag(0.f, 0.f, 0.f); - float baseMass = .05f; + float baseMass = .1f; if (baseMass) { @@ -300,7 +302,7 @@ btMultiBody* DeformableContact::createFeatherstoneMultiBody_testMultiDof(btMulti //init the links btVector3 hingeJointAxis(1, 0, 0); - float linkMass = .05f; + float linkMass = .1f; btVector3 linkInertiaDiag(0.f, 0.f, 0.f); btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2])); diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp index f29cef2ba..1bbadd941 100644 --- a/examples/ExampleBrowser/ExampleEntries.cpp +++ b/examples/ExampleBrowser/ExampleEntries.cpp @@ -50,6 +50,7 @@ #include "../DeformableDemo/DeformableDemo.h" #include "../Pinch/Pinch.h" #include "../DeformableContact/DeformableContact.h" +#include "../MultiBodyBaseline/MultiBodyBaseline.h" #include "../VolumetricDeformable/VolumetricDeformable.h" #include "../SharedMemory/PhysicsServerExampleBullet2.h" #include "../SharedMemory/PhysicsServerExample.h" @@ -126,6 +127,7 @@ static ExampleEntry gDefaultExamples[] = ExampleEntry(0, "Grasp Deformable Cube", "Grasping test", PinchCreateFunc), ExampleEntry(0, "Volumetric Deformable Objects", "Volumetric Deformable test", VolumetricDeformableCreateFunc), ExampleEntry(0, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableContactCreateFunc), + ExampleEntry(0, "MultiBody Baseline", "MultiBody Baseline", MultiBodyBaselineCreateFunc), ExampleEntry(1, "Constraints", "Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.", AllConstraintCreateFunc), diff --git a/examples/MultiBodyBaseline/MultiBodyBaseline.cpp b/examples/MultiBodyBaseline/MultiBodyBaseline.cpp new file mode 100644 index 000000000..663c2d33a --- /dev/null +++ b/examples/MultiBodyBaseline/MultiBodyBaseline.cpp @@ -0,0 +1,358 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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. +*/ + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_Z 5 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X * ARRAY_SIZE_Y * ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + +#include "MultiBodyBaseline.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "BulletSoftBody/btDeformableRigidDynamicsWorld.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "BulletSoftBody/btDeformableBodySolver.h" +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h" +#include //printf debugging + +#include "../CommonInterfaces/CommonRigidBodyBase.h" +#include "../Utils/b3ResourcePath.h" +#include "../SoftDemo/BunnyMesh.h" +#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" +#include "BulletDynamics/Featherstone/btMultiBodyJointFeedback.h" + +#include "../CommonInterfaces/CommonMultiBodyBase.h" +#include "../Utils/b3ResourcePath.h" +///The MultiBodyBaseline demo deformable bodies self-collision +static bool g_floatingBase = true; +static float friction = 1.; +class MultiBodyBaseline : public CommonMultiBodyBase +{ + btMultiBody* m_multiBody; + btAlignedObjectArray m_jointFeedbacks; +public: + MultiBodyBaseline(struct GUIHelperInterface* helper) + : CommonMultiBodyBase(helper) + { + } + + virtual ~MultiBodyBaseline() + { + } + + void initPhysics(); + + void exitPhysics(); + + void resetCamera() + { + float dist = 30; + float pitch = -30; + float yaw = 100; + float targetPos[3] = {0, -10, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); + } + + virtual void stepSimulation(float deltaTime); + + btMultiBody* createFeatherstoneMultiBody_testMultiDof(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical = false, bool floating = false); + + void addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents); + +}; + +void MultiBodyBaseline::initPhysics() +{ + m_guiHelper->setUpAxis(1); + + ///collision configuration contains default setup for memory, collision setup + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + btMultiBodyConstraintSolver* sol; + sol = new btMultiBodyConstraintSolver; + m_solver = sol; + + btMultiBodyDynamicsWorld* world = new btMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration); + m_dynamicsWorld = world; + // m_dynamicsWorld->setDebugDrawer(&gDebugDraw); + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); + m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); + + { + ///create a ground + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.))); + + m_collisionShapes.push_back(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, -40, 0)); + groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.)); + //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: + btScalar mass(0.); + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + bool isDynamic = (mass != 0.f); + + btVector3 localInertia(0, 0, 0); + if (isDynamic) + groundShape->calculateLocalInertia(mass, localInertia); + + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setFriction(0.5); + + //add the ground to the dynamics world + m_dynamicsWorld->addRigidBody(body,1,1+2); + } + + + { + bool damping = true; + bool gyro = false; + int numLinks = 4; + bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals + bool canSleep = false; + bool selfCollide = true; + btVector3 linkHalfExtents(1, 1, 1); + btVector3 baseHalfExtents(1, 1, 1); + + btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 10.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase); + + mbC->setCanSleep(canSleep); + mbC->setHasSelfCollision(selfCollide); + mbC->setUseGyroTerm(gyro); + // + if (!damping) + { + mbC->setLinearDamping(0.0f); + mbC->setAngularDamping(0.0f); + } + else + { + mbC->setLinearDamping(0.04f); + mbC->setAngularDamping(0.04f); + } + + if (numLinks > 0) + { + btScalar q0 = 0.f * SIMD_PI / 180.f; + if (!spherical) + { + mbC->setJointPosMultiDof(0, &q0); + } + else + { + btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0); + quat0.normalize(); + mbC->setJointPosMultiDof(0, quat0); + } + } + /// + addColliders_testMultiDof(mbC, m_dynamicsWorld, baseHalfExtents, linkHalfExtents); + } + + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); +} + +void MultiBodyBaseline::exitPhysics() +{ + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject(obj); + delete obj; + } + + //delete collision shapes + for (int j = 0; j < m_collisionShapes.size(); j++) + { + btCollisionShape* shape = m_collisionShapes[j]; + delete shape; + } + m_collisionShapes.clear(); + + delete m_dynamicsWorld; + + delete m_solver; + + delete m_broadphase; + + delete m_dispatcher; + + delete m_collisionConfiguration; +} + +void MultiBodyBaseline::stepSimulation(float deltaTime) +{ +// getDeformableDynamicsWorld()->getMultiBodyDynamicsWorld()->stepSimulation(deltaTime); + m_dynamicsWorld->stepSimulation(deltaTime, 5, 1./250.); +} + + +btMultiBody* MultiBodyBaseline::createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating) +{ + //init the base + btVector3 baseInertiaDiag(0.f, 0.f, 0.f); + float baseMass = .1f; + + if (baseMass) + { + btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2])); + pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag); + delete pTempBox; + } + + bool canSleep = false; + + btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep); + + btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f); + pMultiBody->setBasePos(basePosition); + pMultiBody->setWorldToBaseRot(baseOriQuat); + btVector3 vel(0, 0, 0); + // pMultiBody->setBaseVel(vel); + + //init the links + btVector3 hingeJointAxis(1, 0, 0); + float linkMass = .1f; + btVector3 linkInertiaDiag(0.f, 0.f, 0.f); + + btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2])); + pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag); + delete pTempBox; + + //y-axis assumed up + btVector3 parentComToCurrentCom(0, -linkHalfExtents[1] * 2.f, 0); //par body's COM to cur body's COM offset + btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1], 0); //cur body's COM to cur body's PIV offset + btVector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; //par body's COM to cur body's PIV offset + + ////// + btScalar q0 = 0.f * SIMD_PI / 180.f; + btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0); + quat0.normalize(); + ///// + + for (int i = 0; i < numLinks; ++i) + { + if (!spherical) + pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, true); + else + //pMultiBody->setupPlanar(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f)/*quat0*/, btVector3(1, 0, 0), parentComToCurrentPivot*2, false); + pMultiBody->setupSpherical(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), parentComToCurrentPivot, currentPivotToCurrentCom, true); + } + + pMultiBody->finalizeMultiDof(); + + /// + pWorld->addMultiBody(pMultiBody); + /// + return pMultiBody; +} + +void MultiBodyBaseline::addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents) +{ + btAlignedObjectArray world_to_local; + world_to_local.resize(pMultiBody->getNumLinks() + 1); + + btAlignedObjectArray local_origin; + local_origin.resize(pMultiBody->getNumLinks() + 1); + world_to_local[0] = pMultiBody->getWorldToBaseRot(); + local_origin[0] = pMultiBody->getBasePos(); + + { + // float pos[4]={local_origin[0].x(),local_origin[0].y(),local_origin[0].z(),1}; + btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()}; + + if (1) + { + btCollisionShape* box = new btBoxShape(baseHalfExtents); + btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1); + col->setCollisionShape(box); + + btTransform tr; + tr.setIdentity(); + tr.setOrigin(local_origin[0]); + tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3])); + col->setWorldTransform(tr); + + pWorld->addCollisionObject(col, 2, 1 + 2); + + col->setFriction(friction); + pMultiBody->setBaseCollider(col); + } + } + + for (int i = 0; i < pMultiBody->getNumLinks(); ++i) + { + const int parent = pMultiBody->getParent(i); + world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1]; + local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i))); + } + + for (int i = 0; i < pMultiBody->getNumLinks(); ++i) + { + btVector3 posr = local_origin[i + 1]; + // float pos[4]={posr.x(),posr.y(),posr.z(),1}; + + btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()}; + + btCollisionShape* box = new btBoxShape(linkHalfExtents); + btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i); + + col->setCollisionShape(box); + btTransform tr; + tr.setIdentity(); + tr.setOrigin(posr); + tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3])); + col->setWorldTransform(tr); + col->setFriction(friction); + pWorld->addCollisionObject(col, 2, 1 + 2); + + pMultiBody->getLink(i).m_collider = col; + } +} +class CommonExampleInterface* MultiBodyBaselineCreateFunc(struct CommonExampleOptions& options) +{ + return new MultiBodyBaseline(options.m_guiHelper); +} + + diff --git a/examples/MultiBodyBaseline/MultiBodyBaseline.h b/examples/MultiBodyBaseline/MultiBodyBaseline.h new file mode 100644 index 000000000..35734c63c --- /dev/null +++ b/examples/MultiBodyBaseline/MultiBodyBaseline.h @@ -0,0 +1,20 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +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 _MULTIBODY_BASELINE_H +#define _MULTIBODY_BASELINE_H + +class CommonExampleInterface* MultiBodyBaselineCreateFunc(struct CommonExampleOptions& options); + +#endif //_MULTIBODY_BASELINE_H diff --git a/examples/VolumetricDeformable/VolumetricDeformable.cpp b/examples/VolumetricDeformable/VolumetricDeformable.cpp index 9bcf63ab2..b30e9bc24 100644 --- a/examples/VolumetricDeformable/VolumetricDeformable.cpp +++ b/examples/VolumetricDeformable/VolumetricDeformable.cpp @@ -77,8 +77,8 @@ public: void stepSimulation(float deltaTime) { //use a smaller internal timestep, there are stability issues - float internalTimeStep = 1. / 480.f; - m_dynamicsWorld->stepSimulation(deltaTime, 8, internalTimeStep); + float internalTimeStep = 1. / 240.f; + m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep); } void createStaticBox(const btVector3& halfEdge, const btVector3& translation) diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index 718106e77..d4a9a754f 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -422,7 +422,11 @@ void btMultiBodyDynamicsWorld::forwardKinematics() void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { solveExternalForces(solverInfo); + solveInternalConstraints(solverInfo); +} +void btMultiBodyDynamicsWorld::solveInternalConstraints(btContactSolverInfo& solverInfo) +{ /// solve all the constraints for this island m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_solverMultiBodyIslandCallback); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h index 019d1bd87..4f48f07d2 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h @@ -113,6 +113,7 @@ public: virtual void getAnalyticsData(btAlignedObjectArray& m_islandAnalyticsData) const; virtual void solveExternalForces(btContactSolverInfo& solverInfo); + virtual void solveInternalConstraints(btContactSolverInfo& solverInfo); }; #endif //BT_MULTIBODY_DYNAMICS_WORLD_H diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 09055c7d1..928ee46f8 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -21,11 +21,10 @@ struct DeformableContactConstraint btAlignedObjectArray m_value; // the magnitude of the total impulse the node applied to the rb in the normal direction in the cg solve btAlignedObjectArray m_accumulated_normal_impulse; - btAlignedObjectArray m_normal_jacobian; - DeformableContactConstraint(const btSoftBody::RContact& rcontact, const btMultiBodyJacobianData& jacobian) + DeformableContactConstraint(const btSoftBody::RContact& rcontact) { - append(rcontact, jacobian); + append(rcontact); } DeformableContactConstraint(const btVector3 dir) @@ -34,8 +33,6 @@ struct DeformableContactConstraint m_direction.push_back(dir); m_value.push_back(0); m_accumulated_normal_impulse.push_back(0); - btMultiBodyJacobianData j; - m_normal_jacobian.push_back(j); } DeformableContactConstraint() @@ -44,17 +41,14 @@ struct DeformableContactConstraint m_direction.push_back(btVector3(0,0,0)); m_value.push_back(0); m_accumulated_normal_impulse.push_back(0); - btMultiBodyJacobianData j; - m_normal_jacobian.push_back(j); } - void append(const btSoftBody::RContact& rcontact, const btMultiBodyJacobianData& jacobian) + void append(const btSoftBody::RContact& rcontact) { m_contact.push_back(&rcontact); m_direction.push_back(rcontact.m_cti.m_normal); m_value.push_back(0); m_accumulated_normal_impulse.push_back(0); - m_normal_jacobian.push_back(jacobian); } ~DeformableContactConstraint() @@ -77,8 +71,6 @@ struct DeformableFrictionConstraint btAlignedObjectArray m_direction_prev; btAlignedObjectArray m_released; // whether the contact is released - btAlignedObjectArray m_complementary_jacobian; - btAlignedObjectArray m_complementaryDirection; // the total impulse the node applied to the rb in the tangential direction in the cg solve @@ -89,12 +81,6 @@ struct DeformableFrictionConstraint append(); } - DeformableFrictionConstraint(const btVector3& complementaryDir, const btMultiBodyJacobianData& jacobian) - { - append(); - addJacobian(complementaryDir, jacobian); - } - void append() { m_static.push_back(false); @@ -112,13 +98,6 @@ struct DeformableFrictionConstraint m_accumulated_tangent_impulse.push_back(btVector3(0,0,0)); m_released.push_back(false); } - - void addJacobian(const btVector3& complementaryDir, const btMultiBodyJacobianData& jacobian) - { - m_complementary_jacobian.push_back(jacobian); - m_complementaryDirection.push_back(complementaryDir); - } - }; class btCGProjection diff --git a/src/BulletSoftBody/btContactProjection.cpp b/src/BulletSoftBody/btContactProjection.cpp deleted file mode 100644 index e81cb2c50..000000000 --- a/src/BulletSoftBody/btContactProjection.cpp +++ /dev/null @@ -1,488 +0,0 @@ -// -// btDeformableContactProjection.cpp -// BulletSoftBody -// -// Created by Xuchen Han on 7/4/19. -// - -#include "btDeformableContactProjection.h" -#include "btDeformableRigidDynamicsWorld.h" -#include -static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, - btMultiBodyJacobianData& jacobianData, - const btVector3& contact_point, - const btVector3& dir) -{ - const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - jacobianData.m_jacobians.resize(ndof); - jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); - btScalar* jac = &jacobianData.m_jacobians[0]; - - multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, contact_point, dir, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); - multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], &jacobianData.m_deltaVelocitiesUnitImpulse[0], jacobianData.scratch_r, jacobianData.scratch_v); -} - -static btVector3 generateUnitOrthogonalVector(const btVector3& u) -{ - btScalar ux = u.getX(); - btScalar uy = u.getY(); - btScalar uz = u.getZ(); - btScalar ax = std::abs(ux); - btScalar ay = std::abs(uy); - btScalar az = std::abs(uz); - btVector3 v; - if (ax <= ay && ax <= az) - v = btVector3(0, -uz, uy); - else if (ay <= ax && ay <= az) - v = btVector3(-uz, 0, ux); - else - v = btVector3(-uy, ux, 0); - v.normalize(); - return v; -} - -void btDeformableContactProjection::update() -{ - ///solve rigid body constraints - m_world->getSolverInfo().m_numIterations = 10; - m_world->btMultiBodyDynamicsWorld::solveConstraints(m_world->getSolverInfo()); - - // loop through constraints to set constrained values - for (auto& it : m_constraints) - { - btAlignedObjectArray& frictions = m_frictions[it.first]; - btAlignedObjectArray& constraints = it.second; - for (int i = 0; i < constraints.size(); ++i) - { - DeformableContactConstraint& constraint = constraints[i]; - DeformableFrictionConstraint& friction = frictions[i]; - for (int j = 0; j < constraint.m_contact.size(); ++j) - { - if (constraint.m_contact[j] == nullptr) - { - // nothing needs to be done for dirichelet constraints - continue; - } - const btSoftBody::RContact* c = constraint.m_contact[j]; - const btSoftBody::sCti& cti = c->m_cti; - - // normal jacobian is precompute but tangent jacobian is not - const btMultiBodyJacobianData& jacobianData_normal = constraint.m_normal_jacobian[j]; - const btMultiBodyJacobianData& jacobianData_complementary = friction.m_complementary_jacobian[j]; - - if (cti.m_colObj->hasContactResponse()) - { - btVector3 va(0, 0, 0); - btRigidBody* rigidCol = 0; - btMultiBodyLinkCollider* multibodyLinkCol = 0; - const btScalar* deltaV_normal; - - // grab the velocity of the rigid body - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c->m_c1)) * m_dt : btVector3(0, 0, 0); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); - if (multibodyLinkCol) - { - const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - const btScalar* jac_normal = &jacobianData_normal.m_jacobians[0]; - deltaV_normal = &jacobianData_normal.m_deltaVelocitiesUnitImpulse[0]; - - // add in the normal component of the va - btScalar vel = 0.0; - for (int k = 0; k < ndof; ++k) - { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac_normal[k]; - } - va = cti.m_normal * vel * m_dt; - - // add in complementary direction of va - const btScalar* jac_complementary = &jacobianData_complementary.m_jacobians[0]; - vel = 0.0; - for (int k = 0; k < ndof; ++k) - { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac_complementary[k]; - } - va += friction.m_complementaryDirection[j] * vel * m_dt; - } - } - - const btVector3 vb = c->m_node->m_v * m_dt; - const btVector3 vr = vb - va; - const btScalar dn = btDot(vr, cti.m_normal); - btVector3 impulse = c->m_c0 * vr; - const btVector3 impulse_normal = c->m_c0 * (cti.m_normal * dn); - const btVector3 impulse_tangent = impulse - impulse_normal; - - // start friction handling - // copy old data - friction.m_impulse_prev[j] = friction.m_impulse[j]; - friction.m_dv_prev[j] = friction.m_dv[j]; - friction.m_static_prev[j] = friction.m_static[j]; - - // get the current tangent direction - btScalar local_tangent_norm = impulse_tangent.norm(); - btVector3 local_tangent_dir = btVector3(0,0,0); - if (local_tangent_norm > SIMD_EPSILON) - local_tangent_dir = impulse_tangent.normalized(); - - // accumulated impulse on the rb in this and all prev cg iterations - constraint.m_accumulated_normal_impulse[j] += impulse_normal.dot(cti.m_normal); - const btScalar& accumulated_normal = constraint.m_accumulated_normal_impulse[j]; - - // the total tangential impulse required to stop sliding - btVector3 tangent = friction.m_accumulated_tangent_impulse[j] + impulse_tangent; - btScalar tangent_norm = tangent.norm(); - - if (accumulated_normal < 0) - { - friction.m_direction[j] = -local_tangent_dir; - // do not allow switching from static friction to dynamic friction - // it causes cg to explode - if (-accumulated_normal*c->m_c3 < tangent_norm && friction.m_static_prev[j] == false && friction.m_released[j] == false) - { - friction.m_static[j] = false; - friction.m_impulse[j] = -accumulated_normal*c->m_c3; - } - else - { - friction.m_static[j] = true; - friction.m_impulse[j] = tangent_norm; - } - } - else - { - friction.m_released[j] = true; - friction.m_static[j] = false; - friction.m_impulse[j] = 0; - friction.m_direction[j] = btVector3(0,0,0); - } - friction.m_dv[j] = friction.m_impulse[j] * c->m_c2/m_dt; - friction.m_accumulated_tangent_impulse[j] = -friction.m_impulse[j] * friction.m_direction[j]; - - // the incremental impulse applied to rb in the tangential direction - btVector3 incremental_tangent = (friction.m_impulse_prev[j] * friction.m_direction_prev[j])-(friction.m_impulse[j] * friction.m_direction[j]); - - // TODO cleanup - if (1) // in the same CG solve, the set of constraits doesn't change - { - // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - - // dv = new_impulse + accumulated velocity change in previous CG iterations - // so we have the invariant node->m_v = backupVelocity + dv; - - btScalar dvn = -accumulated_normal * c->m_c2/m_dt; - - // the following is equivalent - /* - btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; - btScalar dvn = dv.dot(cti.m_normal); - */ - - constraint.m_value[j] = dvn; - - // the incremental impulse: - // in the normal direction it's the normal component of "impulse" - // in the tangent direction it's the difference between the frictional impulse in the iteration and the previous iteration - impulse = impulse_normal + incremental_tangent; - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - if (rigidCol) - rigidCol->applyImpulse(impulse, c->m_c1); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - - if (multibodyLinkCol) - { - double multiplier = 1; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_normal, -impulse_normal.length() * multiplier); - - if (incremental_tangent.norm() > SIMD_EPSILON) - { - btMultiBodyJacobianData jacobian_tangent; - btVector3 tangent = incremental_tangent.normalized(); - findJacobian(multibodyLinkCol, jacobian_tangent, c->m_node->m_x, tangent); - const btScalar* deltaV_tangent = &jacobian_tangent.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_tangent, incremental_tangent.length() * multiplier); - } - } - } - } - } - } - } - } -} - -void btDeformableContactProjection::setConstraints() -{ - // set Dirichlet constraint - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - if (psb->m_nodes[j].m_im == 0) - { - btAlignedObjectArray c; - c.push_back(DeformableContactConstraint(btVector3(1,0,0))); - c.push_back(DeformableContactConstraint(btVector3(0,1,0))); - c.push_back(DeformableContactConstraint(btVector3(0,0,1))); - m_constraints[&(psb->m_nodes[j])] = c; - - btAlignedObjectArray f; - f.push_back(DeformableFrictionConstraint()); - f.push_back(DeformableFrictionConstraint()); - f.push_back(DeformableFrictionConstraint()); - m_frictions[&(psb->m_nodes[j])] = f; - } - } - } - - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - btMultiBodyJacobianData jacobianData_normal; - btMultiBodyJacobianData jacobianData_complementary; - - for (int j = 0; j < psb->m_rcontacts.size(); ++j) - { - const btSoftBody::RContact& c = psb->m_rcontacts[j]; - // skip anchor points - if (c.m_node->m_im == 0) - { - continue; - } - - const btSoftBody::sCti& cti = c.m_cti; - if (cti.m_colObj->hasContactResponse()) - { - btVector3 va(0, 0, 0); - btRigidBody* rigidCol = 0; - btMultiBodyLinkCollider* multibodyLinkCol = 0; - - // grab the velocity of the rigid body - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c.m_c1)) * m_dt : btVector3(0, 0, 0); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); - if (multibodyLinkCol) - { - findJacobian(multibodyLinkCol, jacobianData_normal, c.m_node->m_x, cti.m_normal); - btScalar vel = 0.0; - const btScalar* jac = &jacobianData_normal.m_jacobians[0]; - const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - for (int j = 0; j < ndof; ++j) - { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; - std::cout << multibodyLinkCol->m_multiBody->getVelocityVector()[j] << std::endl; - std::cout << jac[j] << std::endl; - } - va = cti.m_normal * vel * m_dt; - } - } - - const btVector3 vb = c.m_node->m_v * m_dt; - const btVector3 vr = vb - va; - const btScalar dn = btDot(vr, cti.m_normal); - if (dn < SIMD_EPSILON) - { - // find complementary jacobian - btVector3 complementaryDirection; - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); - if (multibodyLinkCol) - { - complementaryDirection = generateUnitOrthogonalVector(cti.m_normal); - findJacobian(multibodyLinkCol, jacobianData_complementary, c.m_node->m_x, complementaryDirection); - } - } - - if (m_constraints.find(c.m_node) == m_constraints.end()) - { - btAlignedObjectArray constraints; - constraints.push_back(DeformableContactConstraint(c, jacobianData_normal)); - m_constraints[c.m_node] = constraints; - btAlignedObjectArray frictions; - frictions.push_back(DeformableFrictionConstraint(complementaryDirection, jacobianData_complementary)); - m_frictions[c.m_node] = frictions; - } - else - { - // group colinear constraints into one - const btScalar angle_epsilon = 0.015192247; // less than 10 degree - bool merged = false; - btAlignedObjectArray& constraints = m_constraints[c.m_node]; - btAlignedObjectArray& frictions = m_frictions[c.m_node]; - for (int j = 0; j < constraints.size(); ++j) - { - const btAlignedObjectArray& dirs = constraints[j].m_direction; - btScalar dot_prod = dirs[0].dot(cti.m_normal); - if (std::abs(std::abs(dot_prod) - 1) < angle_epsilon) - { - // group the constraints - constraints[j].append(c, jacobianData_normal); - // push in an empty friction - frictions[j].append(); - frictions[j].addJacobian(complementaryDirection, jacobianData_complementary); - merged = true; - break; - } - } - const int dim = 3; - // hard coded no more than 3 constraint directions - if (!merged && constraints.size() < dim) - { - constraints.push_back(DeformableContactConstraint(c, jacobianData_normal)); - frictions.push_back(DeformableFrictionConstraint(complementaryDirection, jacobianData_complementary)); - } - } - } - } - } - } -} - -void btDeformableContactProjection::enforceConstraint(TVStack& x) -{ - const int dim = 3; - for (auto& it : m_constraints) - { - const btAlignedObjectArray& constraints = it.second; - size_t i = m_indices[it.first]; - const btAlignedObjectArray& frictions = m_frictions[it.first]; - btAssert(constraints.size() <= dim); - btAssert(constraints.size() > 0); - if (constraints.size() == 1) - { - x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; - for (int j = 0; j < constraints[0].m_direction.size(); ++j) - x[i] += constraints[0].m_value[j] * constraints[0].m_direction[j]; - } - else if (constraints.size() == 2) - { - btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); - btAssert(free_dir.norm() > SIMD_EPSILON) - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir; - for (int j = 0; j < constraints.size(); ++j) - { - for (int k = 0; k < constraints[j].m_direction.size(); ++k) - { - x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; - } - } - - } - else - { - x[i].setZero(); - for (int j = 0; j < constraints.size(); ++j) - { - for (int k = 0; k < constraints[j].m_direction.size(); ++k) - { - x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; - } - } - } - - // apply friction if the node is not constrained in all directions - if (constraints.size() < 3) - { - for (int f = 0; f < frictions.size(); ++f) - { - const DeformableFrictionConstraint& friction= frictions[f]; - for (int j = 0; j < friction.m_direction.size(); ++j) - { - // clear the old constraint - if (friction.m_static_prev[j] == true) - { - x[i] -= friction.m_direction_prev[j] * friction.m_dv_prev[j]; - } - // add the new constraint - if (friction.m_static[j] == true) - { - x[i] += friction.m_direction[j] * friction.m_dv[j]; - } - } - } - } - } -} - -void btDeformableContactProjection::project(TVStack& x) -{ - const int dim = 3; - for (auto& it : m_constraints) - { - const btAlignedObjectArray& constraints = it.second; - size_t i = m_indices[it.first]; - btAlignedObjectArray& frictions = m_frictions[it.first]; - btAssert(constraints.size() <= dim); - btAssert(constraints.size() > 0); - if (constraints.size() == 1) - { - x[i] -= x[i].dot(constraints[0].m_direction[0]) * constraints[0].m_direction[0]; - } - else if (constraints.size() == 2) - { - btVector3 free_dir = btCross(constraints[0].m_direction[0], constraints[1].m_direction[0]); - btAssert(free_dir.norm() > SIMD_EPSILON) - free_dir.normalize(); - x[i] = x[i].dot(free_dir) * free_dir; - } - else - x[i].setZero(); - - // apply friction if the node is not constrained in all directions - if (constraints.size() < 3) - { - bool has_static_constraint = false; - for (int f = 0; f < frictions.size(); ++f) - { - DeformableFrictionConstraint& friction= frictions[f]; - for (int j = 0; j < friction.m_static.size(); ++j) - has_static_constraint = has_static_constraint || friction.m_static[j]; - } - - for (int f = 0; f < frictions.size(); ++f) - { - DeformableFrictionConstraint& friction= frictions[f]; - for (int j = 0; j < friction.m_direction.size(); ++j) - { - // clear the old friction force - if (friction.m_static_prev[j] == false) - { - x[i] -= friction.m_direction_prev[j] * friction.m_impulse_prev[j]; - } - - // only add to the rhs if there is no static friction constraint on the node - if (friction.m_static[j] == false && !has_static_constraint) - { - x[i] += friction.m_direction[j] * friction.m_impulse[j]; - } - } - } - } - } -} - -void btDeformableContactProjection::reinitialize(bool nodeUpdated) -{ - btCGProjection::reinitialize(nodeUpdated); - m_constraints.clear(); - m_frictions.clear(); -} - - - diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index 25f667711..1a9cad120 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -45,7 +45,7 @@ void btDeformableContactProjection::update() { ///solve rigid body constraints m_world->getSolverInfo().m_numIterations = 10; - m_world->btMultiBodyDynamicsWorld::solveConstraints(m_world->getSolverInfo()); + m_world->btMultiBodyDynamicsWorld::solveInternalConstraints(m_world->getSolverInfo()); // loop through constraints to set constrained values for (auto& it : m_constraints) @@ -66,10 +66,6 @@ void btDeformableContactProjection::update() const btSoftBody::RContact* c = constraint.m_contact[j]; const btSoftBody::sCti& cti = c->m_cti; - // normal jacobian is precompute but tangent jacobian is not - const btMultiBodyJacobianData& jacobianData_normal = constraint.m_normal_jacobian[j]; - const btMultiBodyJacobianData& jacobianData_complementary = friction.m_complementary_jacobian[j]; - if (cti.m_colObj->hasContactResponse()) { btVector3 va(0, 0, 0); @@ -89,25 +85,31 @@ void btDeformableContactProjection::update() if (multibodyLinkCol) { const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - const btScalar* jac_normal = &jacobianData_normal.m_jacobians[0]; - deltaV_normal = &jacobianData_normal.m_deltaVelocitiesUnitImpulse[0]; + const btScalar* J_n = &c->jacobianData_normal.m_jacobians[0]; + const btScalar* J_t1 = &c->jacobianData_t1.m_jacobians[0]; + const btScalar* J_t2 = &c->jacobianData_t2.m_jacobians[0]; + deltaV_normal = &c->jacobianData_normal.m_deltaVelocitiesUnitImpulse[0]; // add in the normal component of the va btScalar vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac_normal[k]; + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_n[k]; } va = cti.m_normal * vel * m_dt; - - // add in complementary direction of va - const btScalar* jac_complementary = &jacobianData_complementary.m_jacobians[0]; + vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * jac_complementary[k]; + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_t1[k]; } - va += friction.m_complementaryDirection[j] * vel * m_dt; + va += c->t1 * vel * m_dt; + vel = 0.0; + for (int k = 0; k < ndof; ++k) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_t2[k]; + } + va += c->t2 * vel * m_dt; } } @@ -143,8 +145,6 @@ void btDeformableContactProjection::update() friction.m_direction[j] = -local_tangent_dir; // do not allow switching from static friction to dynamic friction // it causes cg to explode - btScalar comp1 = -accumulated_normal*c->m_c3; - btScalar comp2 = tangent_norm; if (-accumulated_normal*c->m_c3 < tangent_norm && friction.m_static_prev[j] == false && friction.m_released[j] == false) { friction.m_static[j] = false; @@ -194,19 +194,15 @@ void btDeformableContactProjection::update() } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { - if (multibodyLinkCol) { - double multiplier = 1; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_normal, -impulse_normal.length() * multiplier); - + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_normal, impulse.dot(cti.m_normal)); if (incremental_tangent.norm() > SIMD_EPSILON) { - btMultiBodyJacobianData jacobian_tangent; - btVector3 tangent = incremental_tangent.normalized(); - findJacobian(multibodyLinkCol, jacobian_tangent, c->m_node->m_x, tangent); - const btScalar* deltaV_tangent = &jacobian_tangent.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_tangent, incremental_tangent.length() * multiplier); + const btScalar* deltaV_t1 = &c->jacobianData_t1.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_t1, impulse.dot(c->t1)); + const btScalar* deltaV_t2 = &c->jacobianData_t2.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_t2, impulse.dot(c->t2)); } } } @@ -274,15 +270,12 @@ void btDeformableContactProjection::setConstraints() multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); if (multibodyLinkCol) { - findJacobian(multibodyLinkCol, jacobianData_normal, c.m_node->m_x, cti.m_normal); btScalar vel = 0.0; - const btScalar* jac = &jacobianData_normal.m_jacobians[0]; + const btScalar* jac = &c.jacobianData_normal.m_jacobians[0]; const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; for (int j = 0; j < ndof; ++j) { vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; - std::cout << multibodyLinkCol->m_multiBody->getVelocityVector()[j] << std::endl; - std::cout << jac[j] << std::endl; } va = cti.m_normal * vel * m_dt; } @@ -293,25 +286,13 @@ void btDeformableContactProjection::setConstraints() const btScalar dn = btDot(vr, cti.m_normal); if (dn < SIMD_EPSILON) { - // find complementary jacobian - btVector3 complementaryDirection; - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); - if (multibodyLinkCol) - { - complementaryDirection = generateUnitOrthogonalVector(cti.m_normal); - findJacobian(multibodyLinkCol, jacobianData_complementary, c.m_node->m_x, complementaryDirection); - } - } - if (m_constraints.find(c.m_node) == m_constraints.end()) { btAlignedObjectArray constraints; - constraints.push_back(DeformableContactConstraint(c, jacobianData_normal)); + constraints.push_back(DeformableContactConstraint(c)); m_constraints[c.m_node] = constraints; btAlignedObjectArray frictions; - frictions.push_back(DeformableFrictionConstraint(complementaryDirection, jacobianData_complementary)); + frictions.push_back(DeformableFrictionConstraint()); m_frictions[c.m_node] = frictions; } else @@ -328,10 +309,9 @@ void btDeformableContactProjection::setConstraints() if (std::abs(std::abs(dot_prod) - 1) < angle_epsilon) { // group the constraints - constraints[j].append(c, jacobianData_normal); + constraints[j].append(c); // push in an empty friction frictions[j].append(); - frictions[j].addJacobian(complementaryDirection, jacobianData_complementary); merged = true; break; } @@ -340,8 +320,8 @@ void btDeformableContactProjection::setConstraints() // hard coded no more than 3 constraint directions if (!merged && constraints.size() < dim) { - constraints.push_back(DeformableContactConstraint(c, jacobianData_normal)); - frictions.push_back(DeformableFrictionConstraint(complementaryDirection, jacobianData_complementary)); + constraints.push_back(DeformableContactConstraint(c)); + frictions.push_back(DeformableFrictionConstraint()); } } } diff --git a/src/BulletSoftBody/btDeformableContactProjection.h b/src/BulletSoftBody/btDeformableContactProjection.h index aa7af70fb..e73d8faa4 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.h +++ b/src/BulletSoftBody/btDeformableContactProjection.h @@ -40,4 +40,4 @@ public: virtual void reinitialize(bool nodeUpdated); }; -#endif /* btContactProjection_h */ +#endif /* btDeformableContactProjection_h */ diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 216c1a24d..f9c9968c9 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -69,6 +69,43 @@ void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c->m_c1)): btVector3(0, 0, 0); } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + btMultiBodyLinkCollider* multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + const btScalar* J_n = &c->jacobianData_normal.m_jacobians[0]; + const btScalar* J_t1 = &c->jacobianData_t1.m_jacobians[0]; + const btScalar* J_t2 = &c->jacobianData_t2.m_jacobians[0]; + + // add in the normal component of the va + btScalar vel = 0.0; + for (int k = 0; k < ndof; ++k) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_n[k]; + } + va = cti.m_normal * vel; + + vel = 0.0; + for (int k = 0; k < ndof; ++k) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_t1[k]; + } + va += c->t1 * vel; + vel = 0.0; + for (int k = 0; k < ndof; ++k) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_t2[k]; + } + va += c->t2 * vel; + } + } + else + { + // The object interacting with deformable node is not supported for position correction + btAssert(false); + } if (cti.m_colObj->hasContactResponse()) { diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index e8fd3da39..95249b093 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -26,7 +26,8 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" #include "btSparseSDF.h" #include "BulletCollision/BroadphaseCollision/btDbvt.h" - +#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" //#ifdef BT_USE_DOUBLE_PRECISION //#define btRigidBodyData btRigidBodyDoubleData //#define btRigidBodyDataName "btRigidBodyDoubleData" @@ -300,6 +301,13 @@ public: btScalar m_c2; // ima*dt btScalar m_c3; // Friction btScalar m_c4; // Hardness + + // jacobians and unit impulse responses for multibody + btMultiBodyJacobianData jacobianData_normal; + btMultiBodyJacobianData jacobianData_t1; + btMultiBodyJacobianData jacobianData_t2; + btVector3 t1; + btVector3 t2; }; /* SContact */ struct SContact diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 9b3e45ea4..8cf0ed3c0 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -25,7 +25,41 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" #include "BulletCollision/CollisionShapes/btConvexInternalShape.h" #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" +#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" #include //for memset +#include +static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, + btMultiBodyJacobianData& jacobianData, + const btVector3& contact_point, + const btVector3& dir) +{ + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, contact_point, dir, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], &jacobianData.m_deltaVelocitiesUnitImpulse[0], jacobianData.scratch_r, jacobianData.scratch_v); +} +static btVector3 generateUnitOrthogonalVector(const btVector3& u) +{ + btScalar ux = u.getX(); + btScalar uy = u.getY(); + btScalar uz = u.getZ(); + btScalar ax = std::abs(ux); + btScalar ay = std::abs(uy); + btScalar az = std::abs(uz); + btVector3 v; + if (ax <= ay && ax <= az) + v = btVector3(0, -uz, uy); + else if (ay <= ax && ay <= az) + v = btVector3(-uz, 0, ux); + else + v = btVector3(-uy, ux, 0); + v.normalize(); + return v; +} // // btSymMatrix // @@ -298,6 +332,46 @@ static inline btMatrix3x3 Diagonal(btScalar x) m[2] = btVector3(0, 0, x); return (m); } + +static inline btMatrix3x3 Diagonal(const btVector3& v) +{ + btMatrix3x3 m; + m[0] = btVector3(v.getX(), 0, 0); + m[1] = btVector3(0, v.getY(), 0); + m[2] = btVector3(0, 0, v.getZ()); + return (m); +} + +static inline btScalar Dot(const btScalar* a,const btScalar* b, int ndof) +{ + btScalar result = 0; + for (int i = 0; i < ndof; ++i) + result += a[i] * b[i]; + return result; +} + +static inline btMatrix3x3 OuterProduct(const btScalar* v1,const btScalar* v2,const btScalar* v3, + const btScalar* u1, const btScalar* u2, const btScalar* u3, int ndof) +{ + btMatrix3x3 m; + btScalar a11 = Dot(v1,u1,ndof); + btScalar a12 = Dot(v1,u2,ndof); + btScalar a13 = Dot(v1,u3,ndof); + + btScalar a21 = Dot(v2,u1,ndof); + btScalar a22 = Dot(v2,u2,ndof); + btScalar a23 = Dot(v2,u3,ndof); + + btScalar a31 = Dot(v3,u1,ndof); + btScalar a32 = Dot(v3,u2,ndof); + btScalar a33 = Dot(v3,u3,ndof); + m[0] = btVector3(a11, a12, a13); + m[1] = btVector3(a21, a22, a23); + m[2] = btVector3(a31, a32, a33); + return (m); +} + + // static inline btMatrix3x3 Add(const btMatrix3x3& a, const btMatrix3x3& b) @@ -879,21 +953,68 @@ struct btSoftColliders if (ms > 0) { psb->checkContact(m_colObj1Wrap, n.m_q, m, c.m_cti); - const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); - static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0); - const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; - const btVector3 ra = n.m_q - wtr.getOrigin(); - const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); + auto& cti = c.m_cti; c.m_node = &n; - c.m_c0 = ImpulseMatrix(psb->m_sst.sdt, ima, imb, iwi, ra); - c.m_c1 = ra; + const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); c.m_c2 = ima * psb->m_sst.sdt; - // c.m_c3 = fv.length2() < (dn * fc * dn * fc) ? 0 : 1 - fc; c.m_c3 = fc; c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR; + + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); + static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0); + const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; + const btVector3 ra = n.m_q - wtr.getOrigin(); + + c.m_c0 = ImpulseMatrix(psb->m_sst.sdt, ima, imb, iwi, ra); + c.m_c1 = ra; + if (m_rigidBody) + m_rigidBody->activate(); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + btMultiBodyLinkCollider* multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + btVector3 normal = cti.m_normal; + btVector3 t1 = generateUnitOrthogonalVector(normal); + btVector3 t2 = btCross(normal, t1); + btMultiBodyJacobianData jacobianData_normal, jacobianData_t1, jacobianData_t2; + findJacobian(multibodyLinkCol, jacobianData_normal, c.m_node->m_q, normal); + findJacobian(multibodyLinkCol, jacobianData_t1, c.m_node->m_q, t1); + findJacobian(multibodyLinkCol, jacobianData_t2, c.m_node->m_q, t2); + + btScalar* J_n = &jacobianData_normal.m_jacobians[0]; + btScalar* J_t1 = &jacobianData_t1.m_jacobians[0]; + btScalar* J_t2 = &jacobianData_t2.m_jacobians[0]; + + btScalar* u_n = &jacobianData_normal.m_deltaVelocitiesUnitImpulse[0]; + btScalar* u_t1 = &jacobianData_t1.m_deltaVelocitiesUnitImpulse[0]; + btScalar* u_t2 = &jacobianData_t2.m_deltaVelocitiesUnitImpulse[0]; + + btMatrix3x3 rot(normal, t1, t2); // world frame to local frame + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + btVector3 u_dot_J(0,0,0); + for (int i = 0; i < ndof; ++i) + { + u_dot_J += btVector3(J_n[i] * u_n[i], J_t1[i] * u_t1[i], J_t2[i] * u_t2[i]); + } + btVector3 impulse_matrix_diag; + btScalar dt = psb->m_sst.sdt; + impulse_matrix_diag.setX(1/((u_dot_J.getX() + n.m_im) * dt)); + impulse_matrix_diag.setY(1/((u_dot_J.getY() + n.m_im) * dt)); + impulse_matrix_diag.setZ(1/((u_dot_J.getZ() + n.m_im) * dt)); + btMatrix3x3 local_impulse_matrix = Diagonal(1/dt) * (Diagonal(n.m_im) + OuterProduct(J_n, J_t1, J_t2, u_n, u_t1, u_t2, ndof)).inverse(); + c.m_c0 = rot.transpose() * local_impulse_matrix * rot; + c.jacobianData_normal = jacobianData_normal; + c.jacobianData_t1 = jacobianData_t1; + c.jacobianData_t2 = jacobianData_t2; + c.t1 = t1; + c.t2 = t2; + } + } psb->m_rcontacts.push_back(c); - if (m_rigidBody) - m_rigidBody->activate(); } } } From ec403f790d271af9b33eabaab07cd454eb1437c3 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 25 Jul 2019 13:51:44 -0700 Subject: [PATCH 23/47] factor out force; now btDeformableLagrangianceForce can be specified at configuration time and to specific softbody --- .../DeformableContact/DeformableContact.cpp | 11 +- examples/DeformableDemo/DeformableDemo.cpp | 7 +- examples/Pinch/Pinch.cpp | 9 +- .../VolumetricDeformable.cpp | 7 +- src/BulletSoftBody/btBackwardEulerObjective.h | 100 ------------------ src/BulletSoftBody/btCGProjection.h | 21 +--- .../btDeformableBackwardEulerObjective.cpp | 13 +-- .../btDeformableBackwardEulerObjective.h | 19 ++++ .../btDeformableContactProjection.cpp | 17 +-- .../btDeformableContactProjection.h | 4 +- src/BulletSoftBody/btDeformableGravityForce.h | 11 +- .../btDeformableLagrangianForce.h | 39 +++---- .../btDeformableMassSpringForce.h | 24 +++-- .../btDeformableRigidDynamicsWorld.cpp | 33 ++++-- .../btDeformableRigidDynamicsWorld.h | 2 + src/BulletSoftBody/btSoftBody.cpp | 10 +- src/BulletSoftBody/btSoftBody.h | 2 +- src/BulletSoftBody/btSoftBodyInternals.h | 25 +++-- 18 files changed, 150 insertions(+), 204 deletions(-) delete mode 100644 src/BulletSoftBody/btBackwardEulerObjective.h diff --git a/examples/DeformableContact/DeformableContact.cpp b/examples/DeformableContact/DeformableContact.cpp index f51978ae3..c40564867 100644 --- a/examples/DeformableContact/DeformableContact.cpp +++ b/examples/DeformableContact/DeformableContact.cpp @@ -127,8 +127,9 @@ void DeformableContact::initPhysics() m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); deformableBodySolver->setWorld(getDeformableDynamicsWorld()); - m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); - getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + btVector3 gravity = btVector3(0, -10, 0); + m_dynamicsWorld->setGravity(gravity); + getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); { @@ -169,8 +170,8 @@ void DeformableContact::initPhysics() bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals bool canSleep = false; bool selfCollide = true; - btVector3 linkHalfExtents(1, 1, 1); - btVector3 baseHalfExtents(1, 1, 1); + btVector3 linkHalfExtents(.4, 1, .4); + btVector3 baseHalfExtents(.4, 1, .4); btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 10.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase); @@ -228,6 +229,8 @@ void DeformableContact::initPhysics() psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = .1; getDeformableDynamicsWorld()->addSoftBody(psb); + getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); + getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); diff --git a/examples/DeformableDemo/DeformableDemo.cpp b/examples/DeformableDemo/DeformableDemo.cpp index aa58fbd6f..2411670cf 100644 --- a/examples/DeformableDemo/DeformableDemo.cpp +++ b/examples/DeformableDemo/DeformableDemo.cpp @@ -168,8 +168,9 @@ void DeformableDemo::initPhysics() m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); deformableBodySolver->setWorld(getDeformableDynamicsWorld()); // m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality - m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); - getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + btVector3 gravity = btVector3(0, -10, 0); + m_dynamicsWorld->setGravity(gravity); + getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity; // getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); @@ -235,6 +236,8 @@ void DeformableDemo::initPhysics() psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = 1; getDeformableDynamicsWorld()->addSoftBody(psb); + getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); + getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); // add a few rigid bodies Ctor_RbUpStack(1); diff --git a/examples/Pinch/Pinch.cpp b/examples/Pinch/Pinch.cpp index cc3008f9c..4252a47b8 100644 --- a/examples/Pinch/Pinch.cpp +++ b/examples/Pinch/Pinch.cpp @@ -252,8 +252,9 @@ void Pinch::initPhysics() m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); deformableBodySolver->setWorld(getDeformableDynamicsWorld()); // m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality - m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); - getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + btVector3 gravity = btVector3(0, -10, 0); + m_dynamicsWorld->setGravity(gravity); + getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity; getDeformableDynamicsWorld()->m_beforeSolverCallbacks.push_back(dynamics); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); @@ -336,12 +337,14 @@ void Pinch::initPhysics() // psb->translate(btVector3(-2.5, 4, -2.5)); // psb->getCollisionShape()->setMargin(0.1); // psb->setTotalMass(1); - psb->setSpringStiffness(4); + psb->setSpringStiffness(2); psb->setDampingCoefficient(0.02); psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = 2; getDeformableDynamicsWorld()->addSoftBody(psb); + getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); + getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); // add a grippers createGrip(); } diff --git a/examples/VolumetricDeformable/VolumetricDeformable.cpp b/examples/VolumetricDeformable/VolumetricDeformable.cpp index b30e9bc24..15fb712f6 100644 --- a/examples/VolumetricDeformable/VolumetricDeformable.cpp +++ b/examples/VolumetricDeformable/VolumetricDeformable.cpp @@ -186,8 +186,9 @@ void VolumetricDeformable::initPhysics() m_dynamicsWorld = new btDeformableRigidDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); deformableBodySolver->setWorld(getDeformableDynamicsWorld()); // m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality - m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); - getDeformableDynamicsWorld()->getWorldInfo().m_gravity.setValue(0, -10, 0); + btVector3 gravity = btVector3(0, -10, 0); + m_dynamicsWorld->setGravity(gravity); + getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); { @@ -240,6 +241,8 @@ void VolumetricDeformable::initPhysics() psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = 0.5; + getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); + getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); } // add a few rigid bodies Ctor_RbUpStack(4); diff --git a/src/BulletSoftBody/btBackwardEulerObjective.h b/src/BulletSoftBody/btBackwardEulerObjective.h deleted file mode 100644 index 16ec0a542..000000000 --- a/src/BulletSoftBody/btBackwardEulerObjective.h +++ /dev/null @@ -1,100 +0,0 @@ -// -// btDeformableBackwardEulerObjective.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/1/19. -// - -#ifndef BT_BACKWARD_EULER_OBJECTIVE_H -#define BT_BACKWARD_EULER_OBJECTIVE_H -#include -#include "btConjugateGradient.h" -#include "btLagrangianForce.h" -#include "btMassSpring.h" -#include "btDeformableContactProjection.h" -#include "btPreconditioner.h" -#include "btDeformableRigidDynamicsWorld.h" - -class btDeformableRigidDynamicsWorld; -class btDeformableBackwardEulerObjective -{ -public: - using TVStack = btAlignedObjectArray; - btScalar m_dt; - btDeformableRigidDynamicsWorld* m_world; - btAlignedObjectArray m_lf; - btAlignedObjectArray& m_softBodies; - Preconditioner* m_preconditioner; - btDeformableContactProjection projection; - const TVStack& m_backupVelocity; - - btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v); - - virtual ~btDeformableBackwardEulerObjective() {} - - void initialize(){} - - // compute the rhs for CG solve, i.e, add the dt scaled implicit force to residual - void computeResidual(btScalar dt, TVStack& residual) const; - - // add explicit force to the velocity - void applyExplicitForce(TVStack& force); - - // apply force to velocity and optionally reset the force to zero - void applyForce(TVStack& force, bool setZero); - - // compute the norm of the residual - btScalar computeNorm(const TVStack& residual) const; - - // compute one step of the solve (there is only one solve if the system is linear) - void computeStep(TVStack& dv, const TVStack& residual, const btScalar& dt); - - // perform A*x = b - void multiply(const TVStack& x, TVStack& b) const; - - // set initial guess for CG solve - void initialGuess(TVStack& dv, const TVStack& residual); - - // reset data structure - void reinitialize(bool nodeUpdated); - - void setDt(btScalar dt); - - // enforce constraints in CG solve - void enforceConstraint(TVStack& x) - { - projection.enforceConstraint(x); - updateVelocity(x); - } - - // add dv to velocity - void updateVelocity(const TVStack& dv); - - //set constraints as projections - void setConstraints() - { - projection.setConstraints(); - } - - // update the projections and project the residual - void project(TVStack& r) - { - projection.update(); - // TODO rename - projection.project(r); - } - - // perform precondition M^(-1) x = b - void precondition(const TVStack& x, TVStack& b) - { - m_preconditioner->operator()(x,b); - } - - virtual void setWorld(btDeformableRigidDynamicsWorld* world) - { - m_world = world; - projection.setWorld(world); - } -}; - -#endif /* btBackwardEulerObjective_h */ diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 928ee46f8..b4a887fa6 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -109,12 +109,13 @@ public: using TArrayStack = btAlignedObjectArray >; btAlignedObjectArray m_softBodies; btDeformableRigidDynamicsWorld* m_world; - std::unordered_map m_indices; + const std::unordered_map* m_indices; const btScalar& m_dt; - btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) + btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt, const std::unordered_map* indices) : m_softBodies(softBodies) , m_dt(dt) + , m_indices(indices) { } @@ -132,22 +133,6 @@ public: virtual void reinitialize(bool nodeUpdated) { - if (nodeUpdated) - updateId(); - } - - void updateId() - { - size_t index = 0; - m_indices.clear(); - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - m_indices[&(psb->m_nodes[j])] = index++; - } - } } void setSoftBodies(btAlignedObjectArray softBodies) diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 31b0905ac..acc9db75f 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -9,21 +9,22 @@ btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) : m_softBodies(softBodies) -, projection(m_softBodies, m_dt) +, projection(m_softBodies, m_dt, &m_indices) , m_backupVelocity(backup_v) { // TODO: this should really be specified in initialization instead of here - btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(m_softBodies); - btDeformableGravityForce* gravity = new btDeformableGravityForce(m_softBodies, btVector3(0,-10,0)); +// btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(m_softBodies); +// btDeformableGravityForce* gravity = new btDeformableGravityForce(m_softBodies, btVector3(0,-10,0)); m_preconditioner = new DefaultPreconditioner(); - m_lf.push_back(mass_spring); - m_lf.push_back(gravity); +// m_lf.push_back(mass_spring); +// m_lf.push_back(gravity); } void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated) { if(nodeUpdated) { + updateId(); projection.setSoftBodies(m_softBodies); } for (int i = 0; i < m_lf.size(); ++i) @@ -69,7 +70,7 @@ void btDeformableBackwardEulerObjective::updateVelocity(const TVStack& dv) // only the velocity of the constrained nodes needs to be updated during CG solve for (auto it : projection.m_constraints) { - int i = projection.m_indices[it.first]; + int i = m_indices[it.first]; it.first->m_v = m_backupVelocity[i] + dv[i]; } } diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index bfd4ca3af..e22b42b0b 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -28,6 +28,7 @@ public: Preconditioner* m_preconditioner; btDeformableContactProjection projection; const TVStack& m_backupVelocity; + std::unordered_map m_indices; btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v); @@ -95,6 +96,24 @@ public: m_world = world; projection.setWorld(world); } + + virtual void updateId() + { + size_t index = 0; + for (int i = 0; i < m_softBodies.size(); ++i) + { + btSoftBody* psb = m_softBodies[i]; + for (int j = 0; j < psb->m_nodes.size(); ++j) + { + m_indices[&(psb->m_nodes[j])] = index++; + } + } + } + + std::unordered_map* getIndices() + { + return &m_indices; + } }; #endif /* btBackwardEulerObjective_h */ diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index 1a9cad120..4d6ea4e84 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -88,26 +88,27 @@ void btDeformableContactProjection::update() const btScalar* J_n = &c->jacobianData_normal.m_jacobians[0]; const btScalar* J_t1 = &c->jacobianData_t1.m_jacobians[0]; const btScalar* J_t2 = &c->jacobianData_t2.m_jacobians[0]; + const btScalar* local_v = multibodyLinkCol->m_multiBody->getVelocityVector(); deltaV_normal = &c->jacobianData_normal.m_deltaVelocitiesUnitImpulse[0]; - // add in the normal component of the va btScalar vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_n[k]; + vel += local_v[k] * J_n[k]; } va = cti.m_normal * vel * m_dt; + // add in the tangential components of the va vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_t1[k]; + vel += local_v[k] * J_t1[k]; } va += c->t1 * vel * m_dt; vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_t2[k]; + vel += local_v[k] * J_t2[k]; } va += c->t2 * vel * m_dt; } @@ -177,7 +178,7 @@ void btDeformableContactProjection::update() // the following is equivalent /* - btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices[c->m_node]]; + btVector3 dv = -impulse_normal * c->m_c2/m_dt + c->m_node->m_v - backupVelocity[m_indices->at(c->m_node)]; btScalar dvn = dv.dot(cti.m_normal); */ @@ -196,9 +197,11 @@ void btDeformableContactProjection::update() { if (multibodyLinkCol) { + // apply normal component of the impulse multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_normal, impulse.dot(cti.m_normal)); if (incremental_tangent.norm() > SIMD_EPSILON) { + // apply tangential component of the impulse const btScalar* deltaV_t1 = &c->jacobianData_t1.m_deltaVelocitiesUnitImpulse[0]; multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV_t1, impulse.dot(c->t1)); const btScalar* deltaV_t2 = &c->jacobianData_t2.m_deltaVelocitiesUnitImpulse[0]; @@ -336,7 +339,7 @@ void btDeformableContactProjection::enforceConstraint(TVStack& x) for (auto& it : m_constraints) { const btAlignedObjectArray& constraints = it.second; - size_t i = m_indices[it.first]; + size_t i = m_indices->at(it.first); const btAlignedObjectArray& frictions = m_frictions[it.first]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); @@ -399,7 +402,7 @@ void btDeformableContactProjection::project(TVStack& x) for (auto& it : m_constraints) { const btAlignedObjectArray& constraints = it.second; - size_t i = m_indices[it.first]; + size_t i = m_indices->at(it.first); btAlignedObjectArray& frictions = m_frictions[it.first]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); diff --git a/src/BulletSoftBody/btDeformableContactProjection.h b/src/BulletSoftBody/btDeformableContactProjection.h index e73d8faa4..ea3b00f62 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.h +++ b/src/BulletSoftBody/btDeformableContactProjection.h @@ -18,8 +18,8 @@ public: std::unordered_map > m_constraints; std::unordered_map > m_frictions; - btDeformableContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt) - : btCGProjection(softBodies, dt) + btDeformableContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt, const std::unordered_map* indices) + : btCGProjection(softBodies, dt, indices) { } diff --git a/src/BulletSoftBody/btDeformableGravityForce.h b/src/BulletSoftBody/btDeformableGravityForce.h index d8571fa73..398662e1f 100644 --- a/src/BulletSoftBody/btDeformableGravityForce.h +++ b/src/BulletSoftBody/btDeformableGravityForce.h @@ -16,7 +16,7 @@ public: using TVStack = btDeformableLagrangianForce::TVStack; btVector3 m_gravity; - btDeformableGravityForce(const btAlignedObjectArray& softBodies, const btVector3& g) : btDeformableLagrangianForce(softBodies), m_gravity(g) + btDeformableGravityForce(const btVector3& g) : m_gravity(g) { } @@ -39,14 +39,14 @@ public: virtual void addScaledGravityForce(btScalar scale, TVStack& force) { int numNodes = getNumNodes(); - btAssert(numNodes == force.size()) + btAssert(numNodes <= force.size()) for (int i = 0; i < m_softBodies.size(); ++i) { btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { btSoftBody::Node& n = psb->m_nodes[j]; - size_t id = m_indices[&n]; + size_t id = m_indices->at(&n); btScalar mass = (n.m_im == 0) ? 0 : 1. / n.m_im; btVector3 scaled_force = scale * m_gravity * mass; force[id] += scaled_force; @@ -54,7 +54,10 @@ public: } } - + virtual btDeformableLagrangianForceType getForceType() + { + return BT_GRAVITY_FORCE; + } }; diff --git a/src/BulletSoftBody/btDeformableLagrangianForce.h b/src/BulletSoftBody/btDeformableLagrangianForce.h index acb9a28ff..fa4184a14 100644 --- a/src/BulletSoftBody/btDeformableLagrangianForce.h +++ b/src/BulletSoftBody/btDeformableLagrangianForce.h @@ -10,16 +10,20 @@ #include "btSoftBody.h" #include +enum btDeformableLagrangianForceType +{ + BT_GRAVITY_FORCE = 1, + BT_MASSSPRING_FORCE = 2 +}; class btDeformableLagrangianForce { public: using TVStack = btAlignedObjectArray; - const btAlignedObjectArray& m_softBodies; - std::unordered_map m_indices; + btAlignedObjectArray m_softBodies; + const std::unordered_map* m_indices; - btDeformableLagrangianForce(const btAlignedObjectArray& softBodies) - : m_softBodies(softBodies) + btDeformableLagrangianForce() { } @@ -31,23 +35,10 @@ public: virtual void addScaledExplicitForce(btScalar scale, TVStack& force) = 0; + virtual btDeformableLagrangianForceType getForceType() = 0; + virtual void reinitialize(bool nodeUpdated) { - if (nodeUpdated) - updateId(); - } - - virtual void updateId() - { - size_t index = 0; - for (int i = 0; i < m_softBodies.size(); ++i) - { - btSoftBody* psb = m_softBodies[i]; - for (int j = 0; j < psb->m_nodes.size(); ++j) - { - m_indices[&(psb->m_nodes[j])] = index++; - } - } } virtual int getNumNodes() @@ -59,5 +50,15 @@ public: } return numNodes; } + + virtual void addSoftBody(btSoftBody* psb) + { + m_softBodies.push_back(psb); + } + + virtual void setIndices(const std::unordered_map* indices) + { + m_indices = indices; + } }; #endif /* BT_DEFORMABLE_LAGRANGIAN_FORCE */ diff --git a/src/BulletSoftBody/btDeformableMassSpringForce.h b/src/BulletSoftBody/btDeformableMassSpringForce.h index 70ad6e69c..c9fca134c 100644 --- a/src/BulletSoftBody/btDeformableMassSpringForce.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -14,15 +14,13 @@ class btDeformableMassSpringForce : public btDeformableLagrangianForce { public: using TVStack = btDeformableLagrangianForce::TVStack; - btDeformableMassSpringForce(const btAlignedObjectArray& softBodies) : btDeformableLagrangianForce(softBodies) + btDeformableMassSpringForce() { - } virtual void addScaledImplicitForce(btScalar scale, TVStack& force) { addScaledDampingForce(scale, force); -// addScaledElasticForce(scale, force); } virtual void addScaledExplicitForce(btScalar scale, TVStack& force) @@ -33,7 +31,7 @@ public: virtual void addScaledDampingForce(btScalar scale, TVStack& force) { int numNodes = getNumNodes(); - btAssert(numNodes == force.size()) + btAssert(numNodes <= force.size()) for (int i = 0; i < m_softBodies.size(); ++i) { const btSoftBody* psb = m_softBodies[i]; @@ -42,8 +40,8 @@ public: const auto& link = psb->m_links[j]; const auto node1 = link.m_n[0]; const auto node2 = link.m_n[1]; - size_t id1 = m_indices[node1]; - size_t id2 = m_indices[node2]; + size_t id1 = m_indices->at(node1); + size_t id2 = m_indices->at(node2); // damping force btVector3 v_diff = (node2->m_v - node1->m_v); @@ -58,7 +56,7 @@ public: virtual void addScaledElasticForce(btScalar scale, TVStack& force) { int numNodes = getNumNodes(); - btAssert(numNodes == force.size()) + btAssert(numNodes <= force.size()) for (int i = 0; i < m_softBodies.size(); ++i) { const btSoftBody* psb = m_softBodies[i]; @@ -69,8 +67,8 @@ public: const auto node2 = link.m_n[1]; btScalar kLST = link.Feature::m_material->m_kLST; btScalar r = link.m_rl; - size_t id1 = m_indices[node1]; - size_t id2 = m_indices[node2]; + size_t id1 = m_indices->at(node1); + size_t id2 = m_indices->at(node2); // elastic force // explicit elastic force @@ -95,8 +93,8 @@ public: const auto node1 = link.m_n[0]; const auto node2 = link.m_n[1]; btScalar k_damp = psb->m_dampingCoefficient; - size_t id1 = m_indices[node1]; - size_t id2 = m_indices[node2]; + size_t id1 = m_indices->at(node1); + size_t id2 = m_indices->at(node2); btVector3 local_scaled_df = scale * k_damp * (dv[id2] - dv[id1]); df[id1] += local_scaled_df; df[id2] -= local_scaled_df; @@ -104,6 +102,10 @@ public: } } + virtual btDeformableLagrangianForceType getForceType() + { + return BT_MASSSPRING_FORCE; + } }; diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index f9c9968c9..b91d9d2c4 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -60,13 +60,12 @@ void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) if (c == nullptr || c->m_node->m_im == 0) continue; const btSoftBody::sCti& cti = c->m_cti; - btRigidBody* rigidCol = 0; btVector3 va(0, 0, 0); // grab the velocity of the rigid body if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + btRigidBody* rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); va = rigidCol ? (rigidCol->getVelocityInLocalPoint(c->m_c1)): btVector3(0, 0, 0); } else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) @@ -78,25 +77,25 @@ void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) const btScalar* J_n = &c->jacobianData_normal.m_jacobians[0]; const btScalar* J_t1 = &c->jacobianData_t1.m_jacobians[0]; const btScalar* J_t2 = &c->jacobianData_t2.m_jacobians[0]; - + const btScalar* local_v = multibodyLinkCol->m_multiBody->getVelocityVector(); // add in the normal component of the va btScalar vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_n[k]; + vel += local_v[k] * J_n[k]; } va = cti.m_normal * vel; vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_t1[k]; + vel += local_v[k] * J_t1[k]; } va += c->t1 * vel; vel = 0.0; for (int k = 0; k < ndof; ++k) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[k] * J_t2[k]; + vel += local_v[k] * J_t2[k]; } va += c->t2 * vel; } @@ -110,7 +109,6 @@ void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) if (cti.m_colObj->hasContactResponse()) { btScalar dp = cti.m_offset; - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); if (friction.m_static[j] == true) { c->m_node->m_v = va; @@ -214,3 +212,24 @@ void btDeformableRigidDynamicsWorld::afterSolverCallbacks(btScalar timeStep) for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) m_beforeSolverCallbacks[i](m_internalTime, this); } + +void btDeformableRigidDynamicsWorld::addForce(btSoftBody* psb, btDeformableLagrangianForce* force) +{ + btAlignedObjectArray& forces = m_deformableBodySolver->m_objective->m_lf; + bool added = false; + for (int i = 0; i < forces.size(); ++i) + { + if (forces[i]->getForceType() == force->getForceType()) + { + forces[i]->addSoftBody(psb); + added = true; + break; + } + } + if (!added) + { + force->addSoftBody(psb); + force->setIndices(m_deformableBodySolver->m_objective->getIndices()); + forces.push_back(force); + } +} diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index f1be4fd85..c6b3dcbc6 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -126,6 +126,8 @@ public: void afterSolverCallbacks(btScalar timeStep); + void addForce(btSoftBody* psb, btDeformableLagrangianForce* force); + int getDrawFlags() const { return (m_drawFlags); } void setDrawFlags(int f) { m_drawFlags = f; } }; diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index bd7587c47..c31bdb7ed 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -2266,14 +2266,15 @@ btVector3 btSoftBody::evaluateCom() const bool btSoftBody::checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, - btSoftBody::sCti& cti) const + btSoftBody::sCti& cti, bool predict) const { btVector3 nrm; const btCollisionShape* shp = colObjWrap->getCollisionShape(); - const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); + const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); // get the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg - const btTransform &wtr = tmpRigid ? tmpRigid->getInterpolationWorldTransform() : colObjWrap->getWorldTransform(); + const btTransform &wtr = (tmpRigid&&predict) ? tmpRigid->getInterpolationWorldTransform() : colObjWrap->getWorldTransform(); +// const btTransform &wtr = predict ? colObjWrap->getInterpolationWorldTransform() : colObjWrap->getWorldTransform(); // TODO: get the correct transform for multibody btScalar dst = @@ -2282,11 +2283,10 @@ bool btSoftBody::checkContact(const btCollisionObjectWrapper* colObjWrap, shp, nrm, margin); - if (dst < 0) + if (dst < 0 || !predict) { cti.m_colObj = colObjWrap->getCollisionObject(); cti.m_normal = wtr.getBasis() * nrm; -// cti.m_offset = -btDot(cti.m_normal, x - cti.m_normal * dst); cti.m_offset = dst; return (true); } diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index 95249b093..5e33d74d0 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -1005,7 +1005,7 @@ public: btScalar& mint, eFeature::_& feature, int& index, bool bcountonly) const; void initializeFaceTree(); btVector3 evaluateCom() const; - bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti) const; + bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const; void updateNormals(); void updateBounds(); void updatePose(); diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 8cf0ed3c0..2ec8c1b55 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -945,14 +945,17 @@ struct btSoftColliders if (!n.m_battach) { - if (psb->checkContact(m_colObj1Wrap, n.m_x, m, c.m_cti)) + // check for collision at x_{n+1}^* + if (psb->checkContact(m_colObj1Wrap, n.m_x, m, c.m_cti, /*predicted = */ true)) +// if (psb->checkContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predicted = */ false)); { const btScalar ima = n.m_im; const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f; const btScalar ms = ima + imb; if (ms > 0) { - psb->checkContact(m_colObj1Wrap, n.m_q, m, c.m_cti); + // resolve contact at x_n + psb->checkContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predicted = */ false); auto& cti = c.m_cti; c.m_node = &n; const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); @@ -982,8 +985,13 @@ struct btSoftColliders btVector3 t2 = btCross(normal, t1); btMultiBodyJacobianData jacobianData_normal, jacobianData_t1, jacobianData_t2; findJacobian(multibodyLinkCol, jacobianData_normal, c.m_node->m_q, normal); - findJacobian(multibodyLinkCol, jacobianData_t1, c.m_node->m_q, t1); - findJacobian(multibodyLinkCol, jacobianData_t2, c.m_node->m_q, t2); + + // findJacobian is hella expensive, avoid calling if possible + if (fc != 0) + { + findJacobian(multibodyLinkCol, jacobianData_t1, c.m_node->m_q, t1); + findJacobian(multibodyLinkCol, jacobianData_t2, c.m_node->m_q, t2); + } btScalar* J_n = &jacobianData_normal.m_jacobians[0]; btScalar* J_t1 = &jacobianData_t1.m_jacobians[0]; @@ -995,16 +1003,7 @@ struct btSoftColliders btMatrix3x3 rot(normal, t1, t2); // world frame to local frame const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - btVector3 u_dot_J(0,0,0); - for (int i = 0; i < ndof; ++i) - { - u_dot_J += btVector3(J_n[i] * u_n[i], J_t1[i] * u_t1[i], J_t2[i] * u_t2[i]); - } - btVector3 impulse_matrix_diag; btScalar dt = psb->m_sst.sdt; - impulse_matrix_diag.setX(1/((u_dot_J.getX() + n.m_im) * dt)); - impulse_matrix_diag.setY(1/((u_dot_J.getY() + n.m_im) * dt)); - impulse_matrix_diag.setZ(1/((u_dot_J.getZ() + n.m_im) * dt)); btMatrix3x3 local_impulse_matrix = Diagonal(1/dt) * (Diagonal(n.m_im) + OuterProduct(J_n, J_t1, J_t2, u_n, u_t1, u_t2, ndof)).inverse(); c.m_c0 = rot.transpose() * local_impulse_matrix * rot; c.jacobianData_normal = jacobianData_normal; From f1e7ce9ce14ce220c80a572c555eef0150f76df7 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Wed, 31 Jul 2019 20:40:22 -0700 Subject: [PATCH 24/47] add multibody interpolation transform so that collision detection is consistent with rigidbody --- .../Featherstone/btMultiBody.cpp | 130 +++++++++++++++++- src/BulletDynamics/Featherstone/btMultiBody.h | 25 +++- .../Featherstone/btMultiBodyDynamicsWorld.cpp | 22 ++- .../Featherstone/btMultiBodyDynamicsWorld.h | 4 +- .../Featherstone/btMultiBodyLink.h | 35 +++-- .../btDeformableBackwardEulerObjective.cpp | 5 - .../btDeformableContactProjection.cpp | 2 +- .../btDeformableRigidDynamicsWorld.cpp | 2 +- src/BulletSoftBody/btSoftBody.cpp | 8 +- src/BulletSoftBody/btSoftBodyInternals.h | 9 +- 10 files changed, 196 insertions(+), 46 deletions(-) diff --git a/src/BulletDynamics/Featherstone/btMultiBody.cpp b/src/BulletDynamics/Featherstone/btMultiBody.cpp index 3e210d752..80ad19891 100644 --- a/src/BulletDynamics/Featherstone/btMultiBody.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBody.cpp @@ -27,6 +27,7 @@ #include "btMultiBodyJointFeedback.h" #include "LinearMath/btTransformUtil.h" #include "LinearMath/btSerializer.h" +#include //#include "Bullet3Common/b3Logging.h" // #define INCLUDE_GYRO_TERM @@ -100,6 +101,8 @@ btMultiBody::btMultiBody(int n_links, m_baseName(0), m_basePos(0, 0, 0), m_baseQuat(0, 0, 0, 1), + m_basePos_interpolate(0, 0, 0), + m_baseQuat_interpolate(0, 0, 0, 1), m_baseMass(mass), m_baseInertia(inertia), @@ -449,6 +452,16 @@ const btQuaternion &btMultiBody::getParentToLocalRot(int i) const return m_links[i].m_cachedRotParentToThis; } +const btVector3 &btMultiBody::getInterpolateRVector(int i) const +{ + return m_links[i].m_cachedRVector_interpolate; +} + +const btQuaternion &btMultiBody::getInterpolateParentToLocalRot(int i) const +{ + return m_links[i].m_cachedRotParentToThis_interpolate; +} + btVector3 btMultiBody::localPosToWorld(int i, const btVector3 &local_pos) const { btAssert(i >= -1); @@ -1581,17 +1594,37 @@ void btMultiBody::calcAccelerationDeltasMultiDof(const btScalar *force, btScalar //printf("]\n"); ///////////////// } +void btMultiBody::predictPositionsMultiDof(btScalar dt) +{ + stepPositionsMultiDof(dt, 0, 0, true); +} -void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd) +void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd, bool predict) { int num_links = getNumLinks(); // step position by adding dt * velocity //btVector3 v = getBaseVel(); //m_basePos += dt * v; // - btScalar *pBasePos = (pq ? &pq[4] : m_basePos); - btScalar *pBaseVel = (pqd ? &pqd[3] : &m_realBuf[3]); //note: the !pqd case assumes m_realBuf holds with base velocity at 3,4,5 (should be wrapped for safety) - // + btScalar *pBasePos; + btScalar *pBaseVel = (pqd ? &pqd[3] : &m_realBuf[3]); //note: the !pqd case assumes m_realBuf holds with base velocity at 3,4,5 (should be wrapped for safety) + + if (!predict) + { + pBasePos = (pq ? &pq[4] : m_basePos); + } // + else + { + // reset to current position + for (int i = 0; i < 3; ++i) + { + m_basePos_interpolate[i] = m_basePos[i]; + } + pBasePos = m_basePos_interpolate; + } + + + pBasePos[0] += dt * pBaseVel[0]; pBasePos[1] += dt * pBaseVel[1]; pBasePos[2] += dt * pBaseVel[2]; @@ -1645,7 +1678,18 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd //pQuatUpdateFun(getBaseOmega(), m_baseQuat, true, dt); // - btScalar *pBaseQuat = pq ? pq : m_baseQuat; + btScalar *pBaseQuat; + if (!predict) + pBaseQuat = pq ? pq : m_baseQuat; + else + { + // reset to current orientation + for (int i = 0; i < 4; ++i) + { + m_baseQuat_interpolate[i] = m_baseQuat[i]; + } + pBaseQuat = m_baseQuat_interpolate; + } btScalar *pBaseOmega = pqd ? pqd : &m_realBuf[0]; //note: the !pqd case assumes m_realBuf starts with base omega (should be wrapped for safety) // btQuaternion baseQuat; @@ -1670,7 +1714,12 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd // Finally we can update m_jointPos for each of the m_links for (int i = 0; i < num_links; ++i) { - btScalar *pJointPos = (pq ? pq : &m_links[i].m_jointPos[0]); + btScalar *pJointPos; + if (!predict) + pJointPos= (pq ? pq : &m_links[i].m_jointPos[0]); + else + pJointPos = &m_links[i].m_jointPos_interpolate[0]; + btScalar *pJointVel = (pqd ? pqd : getJointVelMultiDof(i)); switch (m_links[i].m_jointType) @@ -1678,12 +1727,23 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd case btMultibodyLink::ePrismatic: case btMultibodyLink::eRevolute: { + //reset to current pos + if (predict) + { + pJointPos[0] = m_links[i].m_jointPos[0]; + } btScalar jointVel = pJointVel[0]; pJointPos[0] += dt * jointVel; break; } case btMultibodyLink::eSpherical: { + //reset to current pos + if (predict) + { + for (int i = 0; i < 4; ++i) + pJointPos[i] = m_links[i].m_jointPos[i]; + } btVector3 jointVel; jointVel.setValue(pJointVel[0], pJointVel[1], pJointVel[2]); btQuaternion jointOri; @@ -1697,6 +1757,11 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd } case btMultibodyLink::ePlanar: { + if (predict) + { + for (int i = 0; i < 3; ++i) + pJointPos[i] = m_links[i].m_jointPos[i]; + } pJointPos[0] += dt * getJointVelMultiDof(i)[0]; btVector3 q0_coors_qd1qd2 = getJointVelMultiDof(i)[1] * m_links[i].getAxisBottom(1) + getJointVelMultiDof(i)[2] * m_links[i].getAxisBottom(2); @@ -1711,7 +1776,7 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd } } - m_links[i].updateCacheMultiDof(pq); + m_links[i].updateCacheMultiDof(pq, predict); if (pq) pq += m_links[i].m_posVarCount; @@ -2006,6 +2071,57 @@ void btMultiBody::updateCollisionObjectWorldTransforms(btAlignedObjectArray &world_to_local, btAlignedObjectArray &local_origin) +{ + world_to_local.resize(getNumLinks() + 1); + local_origin.resize(getNumLinks() + 1); + + world_to_local[0] = getInterpolateWorldToBaseRot(); + local_origin[0] = getInterpolateBasePos(); + + if (getBaseCollider()) + { + btVector3 posr = local_origin[0]; + // float pos[4]={posr.x(),posr.y(),posr.z(),1}; + btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()}; + btTransform tr; + tr.setIdentity(); + tr.setOrigin(posr); + tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3])); + + getBaseCollider()->setInterpolationWorldTransform(tr); + } + + for (int k = 0; k < getNumLinks(); k++) + { + const int parent = getParent(k); + world_to_local[k + 1] = getInterpolateParentToLocalRot(k) * world_to_local[parent + 1]; + local_origin[k + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[k + 1].inverse(), getInterpolateRVector(k))); + } + + for (int m = 0; m < getNumLinks(); m++) + { + btMultiBodyLinkCollider *col = getLink(m).m_collider; + if (col) + { + int link = col->m_link; + btAssert(link == m); + + int index = link + 1; + + btVector3 posr = local_origin[index]; + // float pos[4]={posr.x(),posr.y(),posr.z(),1}; + btScalar quat[4] = {-world_to_local[index].x(), -world_to_local[index].y(), -world_to_local[index].z(), world_to_local[index].w()}; + btTransform tr; + tr.setIdentity(); + tr.setOrigin(posr); + tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3])); + + col->setInterpolationWorldTransform(tr); + } + } +} + int btMultiBody::calculateSerializeBufferSize() const { int sz = sizeof(btMultiBodyData); diff --git a/src/BulletDynamics/Featherstone/btMultiBody.h b/src/BulletDynamics/Featherstone/btMultiBody.h index c0b0d003b..fe60af991 100644 --- a/src/BulletDynamics/Featherstone/btMultiBody.h +++ b/src/BulletDynamics/Featherstone/btMultiBody.h @@ -193,12 +193,24 @@ public: const btQuaternion &getWorldToBaseRot() const { return m_baseQuat; - } // rotates world vectors into base frame + } + + const btVector3 &getInterpolateBasePos() const + { + return m_basePos_interpolate; + } // in world frame + const btQuaternion &getInterpolateWorldToBaseRot() const + { + return m_baseQuat_interpolate; + } + + // rotates world vectors into base frame btVector3 getBaseOmega() const { return btVector3(m_realBuf[0], m_realBuf[1], m_realBuf[2]); } // in world frame void setBasePos(const btVector3 &pos) { m_basePos = pos; + m_basePos_interpolate = pos; } void setBaseWorldTransform(const btTransform &tr) @@ -224,6 +236,7 @@ public: void setWorldToBaseRot(const btQuaternion &rot) { m_baseQuat = rot; //m_baseQuat asumed to ba alias!? + m_baseQuat_interpolate = rot; } void setBaseOmega(const btVector3 &omega) { @@ -273,6 +286,8 @@ public: const btVector3 &getRVector(int i) const; // vector from COM(parent(i)) to COM(i), in frame i's coords const btQuaternion &getParentToLocalRot(int i) const; // rotates vectors in frame parent(i) to vectors in frame i. + const btVector3 &getInterpolateRVector(int i) const; // vector from COM(parent(i)) to COM(i), in frame i's coords + const btQuaternion &getInterpolateParentToLocalRot(int i) const; // rotates vectors in frame parent(i) to vectors in frame i. // // transform vectors in local frame of link i to world frame (or vice versa) @@ -420,7 +435,10 @@ public: } // timestep the positions (given current velocities). - void stepPositionsMultiDof(btScalar dt, btScalar *pq = 0, btScalar *pqd = 0); + void stepPositionsMultiDof(btScalar dt, btScalar *pq = 0, btScalar *pqd = 0, bool predict = false); + + // predict the positions + void predictPositionsMultiDof(btScalar dt); // // contacts @@ -581,6 +599,7 @@ public: void compTreeLinkVelocities(btVector3 * omega, btVector3 * vel) const; void updateCollisionObjectWorldTransforms(btAlignedObjectArray & world_to_local, btAlignedObjectArray & local_origin); + void updateCollisionObjectInterpolationWorldTransforms(btAlignedObjectArray & world_to_local, btAlignedObjectArray & local_origin); virtual int calculateSerializeBufferSize() const; @@ -664,7 +683,9 @@ private: const char *m_baseName; //memory needs to be manager by user! btVector3 m_basePos; // position of COM of base (world frame) + btVector3 m_basePos_interpolate; // position of interpolated COM of base (world frame) btQuaternion m_baseQuat; // rotates world points into base frame + btQuaternion m_baseQuat_interpolate; btScalar m_baseMass; // mass of the base btVector3 m_baseInertia; // inertia of the base (in local frame; diagonal) diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index d4a9a754f..d1ac5e26f 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -33,6 +33,12 @@ void btMultiBodyDynamicsWorld::removeMultiBody(btMultiBody* body) m_multiBodies.remove(body); } +void btMultiBodyDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +{ + btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); + integrateMultiBodyTransforms(timeStep, /*predict = */ true); + +} void btMultiBodyDynamicsWorld::calculateSimulationIslands() { BT_PROFILE("calculateSimulationIslands"); @@ -778,8 +784,11 @@ void btMultiBodyDynamicsWorld::solveExternalForces(btContactSolverInfo& solverIn void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) { btDiscreteDynamicsWorld::integrateTransforms(timeStep); + integrateMultiBodyTransforms(timeStep); +} - { +void btMultiBodyDynamicsWorld::integrateMultiBodyTransforms(btScalar timeStep, bool predict) +{ BT_PROFILE("btMultiBody stepPositions"); //integrate and update the Featherstone hierarchies @@ -802,7 +811,7 @@ void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) int nLinks = bod->getNumLinks(); ///base + num m_links - + if (!predict) { if (!bod->isPosUpdated()) bod->stepPositionsMultiDof(timeStep); @@ -815,18 +824,21 @@ void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) bod->setPosUpdated(false); } } + else + bod->predictPositionsMultiDof(timeStep); m_scratch_world_to_local.resize(nLinks + 1); m_scratch_local_origin.resize(nLinks + 1); - - bod->updateCollisionObjectWorldTransforms(m_scratch_world_to_local, m_scratch_local_origin); + if (predict) + bod->updateCollisionObjectInterpolationWorldTransforms(m_scratch_world_to_local, m_scratch_local_origin); + else + bod->updateCollisionObjectWorldTransforms(m_scratch_world_to_local, m_scratch_local_origin); } else { bod->clearVelocities(); } } - } } void btMultiBodyDynamicsWorld::addMultiBodyConstraint(btMultiBodyConstraint* constraint) diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h index 4f48f07d2..e82c17b31 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h @@ -96,7 +96,9 @@ public: virtual void removeMultiBodyConstraint(btMultiBodyConstraint* constraint); virtual void integrateTransforms(btScalar timeStep); - + void integrateMultiBodyTransforms(btScalar timeStep,bool predict = false); + + virtual void predictUnconstraintMotion(btScalar timeStep); virtual void debugDrawWorld(); virtual void debugDrawMultiBodyConstraint(btMultiBodyConstraint* constraint); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyLink.h b/src/BulletDynamics/Featherstone/btMultiBodyLink.h index 92d41dfac..e7966b852 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyLink.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyLink.h @@ -111,6 +111,10 @@ struct btMultibodyLink btQuaternion m_cachedRotParentToThis; // rotates vectors in parent frame to vectors in local frame btVector3 m_cachedRVector; // vector from COM of parent to COM of this link, in local frame. + + // predicted verstion + btQuaternion m_cachedRotParentToThis_interpolate; // rotates vectors in parent frame to vectors in local frame + btVector3 m_cachedRVector_interpolate; // vector from COM of parent to COM of this link, in local frame. btVector3 m_appliedForce; // In WORLD frame btVector3 m_appliedTorque; // In WORLD frame @@ -119,6 +123,7 @@ struct btMultibodyLink btVector3 m_appliedConstraintTorque; // In WORLD frame btScalar m_jointPos[7]; + btScalar m_jointPos_interpolate[7]; //m_jointTorque is the joint torque applied by the user using 'addJointTorque'. //It gets set to zero after each internal stepSimulation call @@ -186,44 +191,50 @@ struct btMultibodyLink } // routine to update m_cachedRotParentToThis and m_cachedRVector - void updateCacheMultiDof(btScalar *pq = 0) + void updateCacheMultiDof(btScalar *pq = 0, bool predict = false) { - btScalar *pJointPos = (pq ? pq : &m_jointPos[0]); - + btScalar *pJointPos; + + if (!predict) + pJointPos = (pq ? pq : &m_jointPos[0]); + else + pJointPos = &m_jointPos_interpolate[0]; + btQuaternion& cachedRot = predict ? m_cachedRotParentToThis_interpolate : m_cachedRotParentToThis; + btVector3& cachedVector = predict ? m_cachedRVector_interpolate : m_cachedRVector; switch (m_jointType) { case eRevolute: { - m_cachedRotParentToThis = btQuaternion(getAxisTop(0), -pJointPos[0]) * m_zeroRotParentToThis; - m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector); + cachedRot = btQuaternion(getAxisTop(0), -pJointPos[0]) * m_zeroRotParentToThis; + cachedVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector); break; } case ePrismatic: { // m_cachedRotParentToThis never changes, so no need to update - m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector) + pJointPos[0] * getAxisBottom(0); + cachedVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector) + pJointPos[0] * getAxisBottom(0); break; } case eSpherical: { - m_cachedRotParentToThis = btQuaternion(pJointPos[0], pJointPos[1], pJointPos[2], -pJointPos[3]) * m_zeroRotParentToThis; - m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector); + cachedRot = btQuaternion(pJointPos[0], pJointPos[1], pJointPos[2], -pJointPos[3]) * m_zeroRotParentToThis; + cachedVector = m_dVector + quatRotate(cachedRot, m_eVector); break; } case ePlanar: { - m_cachedRotParentToThis = btQuaternion(getAxisTop(0), -pJointPos[0]) * m_zeroRotParentToThis; - m_cachedRVector = quatRotate(btQuaternion(getAxisTop(0), -pJointPos[0]), pJointPos[1] * getAxisBottom(1) + pJointPos[2] * getAxisBottom(2)) + quatRotate(m_cachedRotParentToThis, m_eVector); + cachedRot = btQuaternion(getAxisTop(0), -pJointPos[0]) * m_zeroRotParentToThis; + cachedVector = quatRotate(btQuaternion(getAxisTop(0), -pJointPos[0]), pJointPos[1] * getAxisBottom(1) + pJointPos[2] * getAxisBottom(2)) + quatRotate(cachedRot, m_eVector); break; } case eFixed: { - m_cachedRotParentToThis = m_zeroRotParentToThis; - m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector); + cachedRot = m_zeroRotParentToThis; + cachedVector = m_dVector + quatRotate(cachedRot, m_eVector); break; } diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index acc9db75f..9ffd63a3c 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -12,12 +12,7 @@ btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAligned , projection(m_softBodies, m_dt, &m_indices) , m_backupVelocity(backup_v) { - // TODO: this should really be specified in initialization instead of here -// btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(m_softBodies); -// btDeformableGravityForce* gravity = new btDeformableGravityForce(m_softBodies, btVector3(0,-10,0)); m_preconditioner = new DefaultPreconditioner(); -// m_lf.push_back(mass_spring); -// m_lf.push_back(gravity); } void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated) diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index 4d6ea4e84..734fbb451 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -44,7 +44,7 @@ static btVector3 generateUnitOrthogonalVector(const btVector3& u) void btDeformableContactProjection::update() { ///solve rigid body constraints - m_world->getSolverInfo().m_numIterations = 10; + m_world->getSolverInfo().m_numIterations = 1; m_world->btMultiBodyDynamicsWorld::solveInternalConstraints(m_world->getSolverInfo()); // loop through constraints to set constrained values diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index b91d9d2c4..6ff5a9a41 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -161,7 +161,7 @@ void btDeformableRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collision void btDeformableRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) { - btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); + btMultiBodyDynamicsWorld::predictUnconstraintMotion(timeStep); m_deformableBodySolver->predictMotion(float(timeStep)); } diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index c31bdb7ed..06e0b41d0 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -2270,12 +2270,10 @@ bool btSoftBody::checkContact(const btCollisionObjectWrapper* colObjWrap, { btVector3 nrm; const btCollisionShape* shp = colObjWrap->getCollisionShape(); - const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); - + const btCollisionObject* tmpCollisionObj = colObjWrap->getCollisionObject(); // get the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg - const btTransform &wtr = (tmpRigid&&predict) ? tmpRigid->getInterpolationWorldTransform() : colObjWrap->getWorldTransform(); -// const btTransform &wtr = predict ? colObjWrap->getInterpolationWorldTransform() : colObjWrap->getWorldTransform(); - // TODO: get the correct transform for multibody + const btTransform &wtr = (predict) ? tmpCollisionObj->getInterpolationWorldTransform() : colObjWrap->getWorldTransform(); +// const btTransform &wtr = colObjWrap->getWorldTransform(); btScalar dst = m_worldInfo->m_sparsesdf.Evaluate( diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 2ec8c1b55..34302ccc4 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -985,13 +985,8 @@ struct btSoftColliders btVector3 t2 = btCross(normal, t1); btMultiBodyJacobianData jacobianData_normal, jacobianData_t1, jacobianData_t2; findJacobian(multibodyLinkCol, jacobianData_normal, c.m_node->m_q, normal); - - // findJacobian is hella expensive, avoid calling if possible - if (fc != 0) - { - findJacobian(multibodyLinkCol, jacobianData_t1, c.m_node->m_q, t1); - findJacobian(multibodyLinkCol, jacobianData_t2, c.m_node->m_q, t2); - } + findJacobian(multibodyLinkCol, jacobianData_t1, c.m_node->m_q, t1); + findJacobian(multibodyLinkCol, jacobianData_t2, c.m_node->m_q, t2); btScalar* J_n = &jacobianData_normal.m_jacobians[0]; btScalar* J_t1 = &jacobianData_t1.m_jacobians[0]; From 3dc8abcf36b03aeeedb7643a4fea9c238a59bfba Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 10:19:31 -0700 Subject: [PATCH 25/47] only call buildIslands once for multibody in each timestep --- .../CollisionDispatch/btSimulationIslandManager.cpp | 6 +++--- .../Featherstone/btMultiBodyDynamicsWorld.cpp | 8 ++++++-- .../Featherstone/btMultiBodyDynamicsWorld.h | 1 + src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp | 8 ++++++++ src/BulletSoftBody/btDeformableBackwardEulerObjective.h | 5 +---- src/BulletSoftBody/btDeformableBodySolver.cpp | 2 +- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp index 11fa97cdd..57e1bb494 100644 --- a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp +++ b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp @@ -233,7 +233,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher, btCollisi // printf("error in island management\n"); } -// btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { if (colObj0->getActivationState() == ACTIVE_TAG || @@ -257,7 +257,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher, btCollisi // printf("error in island management\n"); } -// btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { @@ -278,7 +278,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher, btCollisi // printf("error in island management\n"); } -// btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); + btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index d1ac5e26f..2e6dbc440 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -428,14 +428,18 @@ void btMultiBodyDynamicsWorld::forwardKinematics() void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { solveExternalForces(solverInfo); + buildIslands(); solveInternalConstraints(solverInfo); } +void btMultiBodyDynamicsWorld::buildIslands() +{ + m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_solverMultiBodyIslandCallback); +} + void btMultiBodyDynamicsWorld::solveInternalConstraints(btContactSolverInfo& solverInfo) { /// solve all the constraints for this island - m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_solverMultiBodyIslandCallback); - m_solverMultiBodyIslandCallback->processConstraints(); m_constraintSolver->allSolved(solverInfo, m_debugDrawer); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h index e82c17b31..04707bf2d 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h @@ -116,6 +116,7 @@ public: virtual void solveExternalForces(btContactSolverInfo& solverInfo); virtual void solveInternalConstraints(btContactSolverInfo& solverInfo); + void buildIslands(); }; #endif //BT_MULTIBODY_DYNAMICS_WORLD_H diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 9ffd63a3c..7b084af0e 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -128,3 +128,11 @@ void btDeformableBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack } } } + +//set constraints as projections +void btDeformableBackwardEulerObjective::setConstraints() +{ + // build islands for multibody solve + m_world->btMultiBodyDynamicsWorld::buildIslands(); + projection.setConstraints(); +} diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index e22b42b0b..a736315b7 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -73,10 +73,7 @@ public: void updateVelocity(const TVStack& dv); //set constraints as projections - void setConstraints() - { - projection.setConstraints(); - } + void setConstraints(); // update the projections and project the residual void project(TVStack& r) diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index e3009dcbb..a1616a460 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -31,7 +31,7 @@ void btDeformableBodySolver::solveConstraints(float solverdt) backupVelocity(); m_objective->computeResidual(solverdt, m_residual); -// m_objective->initialGuess(m_dv, m_residual); + computeStep(m_dv, m_residual); updateVelocity(); } From 54303e02b10f3fd5bb3624e0cc0ccdfc0de23016 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 13:21:06 -0700 Subject: [PATCH 26/47] perform position correction only when objects are penetrating --- src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp | 10 ++++++---- src/BulletSoftBody/btSoftBody.cpp | 9 +++++---- src/BulletSoftBody/btSoftBodyInternals.h | 1 - 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 6ff5a9a41..0b8807366 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -109,12 +109,14 @@ void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) if (cti.m_colObj->hasContactResponse()) { btScalar dp = cti.m_offset; - if (friction.m_static[j] == true) - { - c->m_node->m_v = va; - } + + // only perform position correction when penetrating if (dp < 0) { + if (friction.m_static[j] == true) + { + c->m_node->m_v = va; + } c->m_node->m_v -= dp * cti.m_normal / dt; } } diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 06e0b41d0..8a62d31bb 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -2271,9 +2271,9 @@ bool btSoftBody::checkContact(const btCollisionObjectWrapper* colObjWrap, btVector3 nrm; const btCollisionShape* shp = colObjWrap->getCollisionShape(); const btCollisionObject* tmpCollisionObj = colObjWrap->getCollisionObject(); - // get the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg + // use the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg for collision detect + // but resolve contact at x_n const btTransform &wtr = (predict) ? tmpCollisionObj->getInterpolationWorldTransform() : colObjWrap->getWorldTransform(); -// const btTransform &wtr = colObjWrap->getWorldTransform(); btScalar dst = m_worldInfo->m_sparsesdf.Evaluate( @@ -2281,13 +2281,14 @@ bool btSoftBody::checkContact(const btCollisionObjectWrapper* colObjWrap, shp, nrm, margin); - if (dst < 0 || !predict) + if (!predict) { cti.m_colObj = colObjWrap->getCollisionObject(); cti.m_normal = wtr.getBasis() * nrm; cti.m_offset = dst; - return (true); } + if (dst < 0) + return true; return (false); } diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 34302ccc4..61dff4234 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -947,7 +947,6 @@ struct btSoftColliders { // check for collision at x_{n+1}^* if (psb->checkContact(m_colObj1Wrap, n.m_x, m, c.m_cti, /*predicted = */ true)) -// if (psb->checkContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predicted = */ false)); { const btScalar ima = n.m_im; const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f; From 8cc7cb59d7af86084018608968cf5f6e5c5b18dd Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 14:06:42 -0700 Subject: [PATCH 27/47] clean up examples --- examples/BasicDemo/BasicExample.cpp | 6 +++--- examples/ExampleBrowser/ExampleEntries.cpp | 13 +++++++------ src/BulletDynamics/Featherstone/btMultiBody.cpp | 1 - src/BulletSoftBody/btDeformableBodySolver.h | 2 +- src/BulletSoftBody/btDeformableContactProjection.h | 1 - src/BulletSoftBody/btSoftBodyInternals.h | 1 - 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/examples/BasicDemo/BasicExample.cpp b/examples/BasicDemo/BasicExample.cpp index 136aefb20..67f670d07 100644 --- a/examples/BasicDemo/BasicExample.cpp +++ b/examples/BasicDemo/BasicExample.cpp @@ -16,9 +16,9 @@ subject to the following restrictions: #include "BasicExample.h" #include "btBulletDynamicsCommon.h" -#define ARRAY_SIZE_Y 1 -#define ARRAY_SIZE_X 1 -#define ARRAY_SIZE_Z 1 +#define ARRAY_SIZE_Y 5 +#define ARRAY_SIZE_X 5 +#define ARRAY_SIZE_Z 5 #include "LinearMath/btVector3.h" #include "LinearMath/btAlignedObjectArray.h" diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp index 1bbadd941..f186f642a 100644 --- a/examples/ExampleBrowser/ExampleEntries.cpp +++ b/examples/ExampleBrowser/ExampleEntries.cpp @@ -122,12 +122,6 @@ static ExampleEntry gDefaultExamples[] = ExampleEntry(1, "Basic Example", "Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc), ExampleEntry(1, "Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc), - - ExampleEntry(0, "Deformable-RigidBody Contact", "Deformable test", DeformableCreateFunc), - ExampleEntry(0, "Grasp Deformable Cube", "Grasping test", PinchCreateFunc), - ExampleEntry(0, "Volumetric Deformable Objects", "Volumetric Deformable test", VolumetricDeformableCreateFunc), - ExampleEntry(0, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableContactCreateFunc), - ExampleEntry(0, "MultiBody Baseline", "MultiBody Baseline", MultiBodyBaselineCreateFunc), ExampleEntry(1, "Constraints", "Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.", AllConstraintCreateFunc), @@ -201,6 +195,13 @@ static ExampleEntry gDefaultExamples[] = ExampleEntry(1, "Spheres & Plane C-API (Bullet2)", "Collision C-API using Bullet 2.x backend", CollisionTutorialBullet2CreateFunc, TUT_SPHERE_PLANE_BULLET2), //ExampleEntry(1, "Spheres & Plane C-API (Bullet3)", "Collision C-API using Bullet 3.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_RTB3), + ExampleEntry(0, "Deformabe Body"), + ExampleEntry(1, "Deformable-RigidBody Contact", "Deformable test", DeformableCreateFunc), + ExampleEntry(1, "Grasp Deformable Cube", "Grasping test", PinchCreateFunc), + ExampleEntry(1, "Volumetric Deformable Objects", "Volumetric Deformable test", VolumetricDeformableCreateFunc), + ExampleEntry(1, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableContactCreateFunc), + // ExampleEntry(1, "MultiBody Baseline", "MultiBody Baseline", MultiBodyBaselineCreateFunc), + #ifdef INCLUDE_CLOTH_DEMOS ExampleEntry(0, "Soft Body"), ExampleEntry(1, "Cloth", "Simulate a patch of cloth.", SoftDemoCreateFunc, 0), diff --git a/src/BulletDynamics/Featherstone/btMultiBody.cpp b/src/BulletDynamics/Featherstone/btMultiBody.cpp index 80ad19891..1857bd55f 100644 --- a/src/BulletDynamics/Featherstone/btMultiBody.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBody.cpp @@ -27,7 +27,6 @@ #include "btMultiBodyJointFeedback.h" #include "LinearMath/btTransformUtil.h" #include "LinearMath/btSerializer.h" -#include //#include "Bullet3Common/b3Logging.h" // #define INCLUDE_GYRO_TERM diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 0b4a4819f..d721869a1 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -8,7 +8,7 @@ #ifndef BT_DEFORMABLE_BODY_SOLVERS_H #define BT_DEFORMABLE_BODY_SOLVERS_H -#include + #include "btSoftBodySolvers.h" #include "btDeformableBackwardEulerObjective.h" #include "btDeformableRigidDynamicsWorld.h" diff --git a/src/BulletSoftBody/btDeformableContactProjection.h b/src/BulletSoftBody/btDeformableContactProjection.h index ea3b00f62..2ca571195 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.h +++ b/src/BulletSoftBody/btDeformableContactProjection.h @@ -11,7 +11,6 @@ #include "btSoftBody.h" #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" -#include class btDeformableContactProjection : public btCGProjection { public: diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 61dff4234..5756fffc7 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -28,7 +28,6 @@ subject to the following restrictions: #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" #include //for memset -#include static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, btMultiBodyJacobianData& jacobianData, const btVector3& contact_point, From 753b2d9f156bfa7fcf35be0da3c3fbc0b9c85ee3 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 15:02:15 -0700 Subject: [PATCH 28/47] add new demos to CMakeList --- examples/ExampleBrowser/CMakeLists.txt | 8 ++++++++ examples/ExampleBrowser/premake4.lua | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/examples/ExampleBrowser/CMakeLists.txt b/examples/ExampleBrowser/CMakeLists.txt index a04e9f9b4..cfae5fcc5 100644 --- a/examples/ExampleBrowser/CMakeLists.txt +++ b/examples/ExampleBrowser/CMakeLists.txt @@ -359,6 +359,14 @@ SET(BulletExampleBrowser_SRCS ../MultiBody/MultiBodyConstraintFeedback.cpp ../SoftDemo/SoftDemo.cpp ../SoftDemo/SoftDemo.h + ../Pinch/Pinch.cpp + ../Pinch/Pinch.h + ../DeformableContact/DeformableContact.cpp + ../DeformableContact/DeformableContact.h + ../DeformableDemo/DeformableDemo.cpp + ../DeformableDemo/DeformableDemo.h + ../VolumetricDeformable/VolumetricDeformable.cpp + ../VolumetricDeformable/VolumetricDeformable.h ../MultiBody/MultiDofDemo.cpp ../MultiBody/MultiDofDemo.h ../RigidBody/RigidBodySoftContact.cpp diff --git a/examples/ExampleBrowser/premake4.lua b/examples/ExampleBrowser/premake4.lua index b976136df..ff81b34b7 100644 --- a/examples/ExampleBrowser/premake4.lua +++ b/examples/ExampleBrowser/premake4.lua @@ -188,6 +188,10 @@ project "App_BulletExampleBrowser" "../RenderingExamples/*", "../VoronoiFracture/*", "../SoftDemo/*", + "../DeformableDemo/*", + "../DeformableContact/*", + "../VolumetricDeformable/*", + "../Pinch/*", "../RollingFrictionDemo/*", "../rbdl/*", "../FractureDemo/*", From f624b60c198ca4f39f349ece1230ba5ce60ee7e6 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 15:19:37 -0700 Subject: [PATCH 29/47] get rid of auto --- .../btDeformableBackwardEulerObjective.cpp | 2 +- .../btDeformableContactProjection.cpp | 1 + .../btDeformableMassSpringForce.h | 18 +++++++++--------- .../btDeformableRigidDynamicsWorld.cpp | 2 +- src/BulletSoftBody/btSoftBodyInternals.h | 3 ++- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 7b084af0e..a9b77e368 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -47,7 +47,7 @@ void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { - const auto& node = psb->m_nodes[j]; + const btSoftBody::Node& node = psb->m_nodes[j]; b[counter] += (node.m_im == 0) ? btVector3(0,0,0) : x[counter] / node.m_im; ++counter; } diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index 734fbb451..4ae07290c 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -8,6 +8,7 @@ #include "btDeformableContactProjection.h" #include "btDeformableRigidDynamicsWorld.h" #include +#include static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, btMultiBodyJacobianData& jacobianData, const btVector3& contact_point, diff --git a/src/BulletSoftBody/btDeformableMassSpringForce.h b/src/BulletSoftBody/btDeformableMassSpringForce.h index c9fca134c..549985321 100644 --- a/src/BulletSoftBody/btDeformableMassSpringForce.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -37,9 +37,9 @@ public: const btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_links.size(); ++j) { - const auto& link = psb->m_links[j]; - const auto node1 = link.m_n[0]; - const auto node2 = link.m_n[1]; + const btSoftBody::Link& link = psb->m_links[j]; + btSoftBody::Node* node1 = link.m_n[0]; + btSoftBody::Node* node2 = link.m_n[1]; size_t id1 = m_indices->at(node1); size_t id2 = m_indices->at(node2); @@ -62,9 +62,9 @@ public: const btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_links.size(); ++j) { - const auto& link = psb->m_links[j]; - const auto node1 = link.m_n[0]; - const auto node2 = link.m_n[1]; + const btSoftBody::Link& link = psb->m_links[j]; + btSoftBody::Node* node1 = link.m_n[0]; + btSoftBody::Node* node2 = link.m_n[1]; btScalar kLST = link.Feature::m_material->m_kLST; btScalar r = link.m_rl; size_t id1 = m_indices->at(node1); @@ -89,9 +89,9 @@ public: const btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_links.size(); ++j) { - const auto& link = psb->m_links[j]; - const auto node1 = link.m_n[0]; - const auto node2 = link.m_n[1]; + const btSoftBody::Link& link = psb->m_links[j]; + btSoftBody::Node* node1 = link.m_n[0]; + btSoftBody::Node* node2 = link.m_n[1]; btScalar k_damp = psb->m_dampingCoefficient; size_t id1 = m_indices->at(node1); size_t id2 = m_indices->at(node2); diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 0b8807366..78c5f24a9 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -136,7 +136,7 @@ void btDeformableRigidDynamicsWorld::integrateTransforms(btScalar dt) btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { - auto& node = psb->m_nodes[j]; + btSoftBody::Node& node = psb->m_nodes[j]; node.m_x = node.m_q + dt * node.m_v; } } diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 5756fffc7..9c732250b 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -28,6 +28,7 @@ subject to the following restrictions: #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" #include //for memset +#include static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, btMultiBodyJacobianData& jacobianData, const btVector3& contact_point, @@ -954,7 +955,7 @@ struct btSoftColliders { // resolve contact at x_n psb->checkContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predicted = */ false); - auto& cti = c.m_cti; + btSoftBody::sCti& cti = c.m_cti; c.m_node = &n; const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); c.m_c2 = ima * psb->m_sst.sdt; From 7f33d8cdb9acde79144030544c7f039403c113c6 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 15:27:10 -0700 Subject: [PATCH 30/47] get rid of 'using' --- src/BulletSoftBody/btCGProjection.h | 9 ++++++--- src/BulletSoftBody/btConjugateGradient.h | 3 ++- src/BulletSoftBody/btDeformableBackwardEulerObjective.h | 3 ++- src/BulletSoftBody/btDeformableBodySolver.h | 3 ++- src/BulletSoftBody/btDeformableGravityForce.h | 3 ++- src/BulletSoftBody/btDeformableLagrangianForce.h | 3 ++- src/BulletSoftBody/btDeformableMassSpringForce.h | 3 ++- src/BulletSoftBody/btDeformableRigidDynamicsWorld.h | 3 ++- src/BulletSoftBody/btPreconditioner.h | 3 ++- 9 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index b4a887fa6..ca7417f8f 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -104,9 +104,12 @@ class btCGProjection { public: // static const int dim = 3; - using TVStack = btAlignedObjectArray; - using TVArrayStack = btAlignedObjectArray >; - using TArrayStack = btAlignedObjectArray >; + typedef btAlignedObjectArray TVStack; + typedef btAlignedObjectArray > TVArrayStack; + typedef btAlignedObjectArray > TArrayStack; +// using TVStack = btAlignedObjectArray; +// using TVArrayStack = btAlignedObjectArray >; +// using TArrayStack = btAlignedObjectArray >; btAlignedObjectArray m_softBodies; btDeformableRigidDynamicsWorld* m_world; const std::unordered_map* m_indices; diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index 0c8384a00..fdef6b22d 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -15,7 +15,8 @@ template class btConjugateGradient { - using TVStack = btAlignedObjectArray; +// using TVStack = btAlignedObjectArray; + typedef btAlignedObjectArray TVStack; TVStack r,p,z,temp; int max_iterations; diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index a736315b7..22a685631 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -20,7 +20,8 @@ class btDeformableRigidDynamicsWorld; class btDeformableBackwardEulerObjective { public: - using TVStack = btAlignedObjectArray; +// using TVStack = btAlignedObjectArray; + typedef btAlignedObjectArray TVStack; btScalar m_dt; btDeformableRigidDynamicsWorld* m_world; btAlignedObjectArray m_lf; diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index d721869a1..5528d8f84 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -21,7 +21,8 @@ class btDeformableRigidDynamicsWorld; class btDeformableBodySolver : public btSoftBodySolver { - using TVStack = btAlignedObjectArray; +// using TVStack = btAlignedObjectArray; + typedef btAlignedObjectArray TVStack; protected: int m_numNodes; TVStack m_dv; diff --git a/src/BulletSoftBody/btDeformableGravityForce.h b/src/BulletSoftBody/btDeformableGravityForce.h index 398662e1f..88d9107e1 100644 --- a/src/BulletSoftBody/btDeformableGravityForce.h +++ b/src/BulletSoftBody/btDeformableGravityForce.h @@ -13,7 +13,8 @@ class btDeformableGravityForce : public btDeformableLagrangianForce { public: - using TVStack = btDeformableLagrangianForce::TVStack; +// using TVStack = btDeformableLagrangianForce::TVStack; + typedef btAlignedObjectArray TVStack; btVector3 m_gravity; btDeformableGravityForce(const btVector3& g) : m_gravity(g) diff --git a/src/BulletSoftBody/btDeformableLagrangianForce.h b/src/BulletSoftBody/btDeformableLagrangianForce.h index fa4184a14..ff75eeb1c 100644 --- a/src/BulletSoftBody/btDeformableLagrangianForce.h +++ b/src/BulletSoftBody/btDeformableLagrangianForce.h @@ -19,7 +19,8 @@ enum btDeformableLagrangianForceType class btDeformableLagrangianForce { public: - using TVStack = btAlignedObjectArray; +// using TVStack = btAlignedObjectArray; + typedef btAlignedObjectArray TVStack; btAlignedObjectArray m_softBodies; const std::unordered_map* m_indices; diff --git a/src/BulletSoftBody/btDeformableMassSpringForce.h b/src/BulletSoftBody/btDeformableMassSpringForce.h index 549985321..d3ccd70dc 100644 --- a/src/BulletSoftBody/btDeformableMassSpringForce.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -13,7 +13,8 @@ class btDeformableMassSpringForce : public btDeformableLagrangianForce { public: - using TVStack = btDeformableLagrangianForce::TVStack; +// using TVStack = btDeformableLagrangianForce::TVStack; + typedef btAlignedObjectArray TVStack; btDeformableMassSpringForce() { } diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index c6b3dcbc6..779a88ee3 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -30,7 +30,8 @@ typedef btAlignedObjectArray btSoftBodyArray; class btDeformableRigidDynamicsWorld : public btMultiBodyDynamicsWorld { - using TVStack = btAlignedObjectArray; + typedef btAlignedObjectArray TVStack; +// using TVStack = btAlignedObjectArray; ///Solver classes that encapsulate multiple deformable bodies for solving btDeformableBodySolver* m_deformableBodySolver; btSoftBodyArray m_softBodies; diff --git a/src/BulletSoftBody/btPreconditioner.h b/src/BulletSoftBody/btPreconditioner.h index ad190a3a8..97cec43c5 100644 --- a/src/BulletSoftBody/btPreconditioner.h +++ b/src/BulletSoftBody/btPreconditioner.h @@ -11,7 +11,8 @@ class Preconditioner { public: - using TVStack = btAlignedObjectArray; + typedef btAlignedObjectArray TVStack; +// using TVStack = btAlignedObjectArray; virtual void operator()(const TVStack& x, TVStack& b) = 0; virtual void reinitialize(bool nodeUpdated) = 0; }; From 9a5ef6c8494668c54ced7a523a07934678049cf3 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 15:41:10 -0700 Subject: [PATCH 31/47] update CMakeList --- src/BulletSoftBody/CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/BulletSoftBody/CMakeLists.txt b/src/BulletSoftBody/CMakeLists.txt index d43df1c67..ec5fd447e 100644 --- a/src/BulletSoftBody/CMakeLists.txt +++ b/src/BulletSoftBody/CMakeLists.txt @@ -17,6 +17,11 @@ SET(BulletSoftBody_SRCS btSoftSoftCollisionAlgorithm.cpp btDefaultSoftBodySolver.cpp + btDeformableBackwardEulerObjective.cpp + btDeformableBodySolver.cpp + btDeformableContactProjection.cpp + btDeformableRigidDynamicsWorld.cpp + ) SET(BulletSoftBody_HDRS @@ -33,6 +38,18 @@ SET(BulletSoftBody_HDRS btSoftBodySolvers.h btDefaultSoftBodySolver.h + + btCGrojection.h + btConjugateGradient.h + btDeformableGravityForce.h + btDeformableMassSpringForce.h + btDeformableLagrangianForce.h + btPreconditioner.h + + btDeformableBackwardEulerObjective.h + btDeformableBodySolver.h + btDeformableContactProjection.h + btDeformableRigidDynamicsWorld.h btSoftBodySolverVertexBuffer.h ) From dae230912b2ddc69f8ce5ec813fa6178e1269449 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 15:51:38 -0700 Subject: [PATCH 32/47] typo fix --- src/BulletSoftBody/CMakeLists.txt | 2 +- src/BulletSoftBody/btSoftBodyInternals.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BulletSoftBody/CMakeLists.txt b/src/BulletSoftBody/CMakeLists.txt index ec5fd447e..40155786e 100644 --- a/src/BulletSoftBody/CMakeLists.txt +++ b/src/BulletSoftBody/CMakeLists.txt @@ -39,7 +39,7 @@ SET(BulletSoftBody_HDRS btSoftBodySolvers.h btDefaultSoftBodySolver.h - btCGrojection.h + btCGProjection.h btConjugateGradient.h btDeformableGravityForce.h btDeformableMassSpringForce.h diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 9c732250b..77bcdc5d8 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -28,7 +28,7 @@ subject to the following restrictions: #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" #include //for memset -#include +#include static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, btMultiBodyJacobianData& jacobianData, const btVector3& contact_point, From 8c04a78c9b84bfd13235c1a1333c70f32d231059 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 17:46:26 -0700 Subject: [PATCH 33/47] switch from std::unordered_map to btHashMap --- src/BulletSoftBody/btCGProjection.h | 14 +++---- .../btDeformableBackwardEulerObjective.cpp | 9 +++-- .../btDeformableBackwardEulerObjective.h | 13 ++++--- src/BulletSoftBody/btDeformableBodySolver.cpp | 2 +- src/BulletSoftBody/btDeformableBodySolver.h | 1 + .../btDeformableContactProjection.cpp | 38 +++++++++---------- .../btDeformableContactProjection.h | 13 +++++-- src/BulletSoftBody/btDeformableGravityForce.h | 2 +- .../btDeformableLagrangianForce.h | 9 +++-- .../btDeformableMassSpringForce.h | 12 +++--- .../btDeformableRigidDynamicsWorld.cpp | 7 ++-- src/BulletSoftBody/btSoftBody.h | 1 + src/BulletSoftBody/btSoftBodyInternals.h | 4 +- 13 files changed, 68 insertions(+), 57 deletions(-) diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index ca7417f8f..144208908 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -10,7 +10,6 @@ #include "btSoftBody.h" #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" -#include class btDeformableRigidDynamicsWorld; @@ -21,6 +20,7 @@ struct DeformableContactConstraint btAlignedObjectArray m_value; // the magnitude of the total impulse the node applied to the rb in the normal direction in the cg solve btAlignedObjectArray m_accumulated_normal_impulse; + btSoftBody::Node* node; DeformableContactConstraint(const btSoftBody::RContact& rcontact) { @@ -58,7 +58,6 @@ struct DeformableContactConstraint struct DeformableFrictionConstraint { - btAlignedObjectArray m_static; // whether the friction is static btAlignedObjectArray m_impulse; // the impulse magnitude the node feels btAlignedObjectArray m_dv; // the dv magnitude of the node @@ -75,6 +74,7 @@ struct DeformableFrictionConstraint // the total impulse the node applied to the rb in the tangential direction in the cg solve btAlignedObjectArray m_accumulated_tangent_impulse; + btSoftBody::Node* node; DeformableFrictionConstraint() { @@ -103,22 +103,18 @@ struct DeformableFrictionConstraint class btCGProjection { public: -// static const int dim = 3; typedef btAlignedObjectArray TVStack; typedef btAlignedObjectArray > TVArrayStack; typedef btAlignedObjectArray > TArrayStack; -// using TVStack = btAlignedObjectArray; -// using TVArrayStack = btAlignedObjectArray >; -// using TArrayStack = btAlignedObjectArray >; btAlignedObjectArray m_softBodies; btDeformableRigidDynamicsWorld* m_world; - const std::unordered_map* m_indices; + const btAlignedObjectArray* m_nodes; const btScalar& m_dt; - btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt, const std::unordered_map* indices) + btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt, const btAlignedObjectArray* nodes) : m_softBodies(softBodies) , m_dt(dt) - , m_indices(indices) + , m_nodes(nodes) { } diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index a9b77e368..50db01ec9 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -9,7 +9,7 @@ btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) : m_softBodies(softBodies) -, projection(m_softBodies, m_dt, &m_indices) +, projection(m_softBodies, m_dt, &m_nodes) , m_backupVelocity(backup_v) { m_preconditioner = new DefaultPreconditioner(); @@ -63,10 +63,11 @@ void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) void btDeformableBackwardEulerObjective::updateVelocity(const TVStack& dv) { // only the velocity of the constrained nodes needs to be updated during CG solve - for (auto it : projection.m_constraints) +// for (auto it : projection.m_constraints) + for (int i = 0; i < projection.m_constraints.size(); ++i) { - int i = m_indices[it.first]; - it.first->m_v = m_backupVelocity[i] + dv[i]; + int index = projection.m_constraints.getKeyAtIndex(i).getUid1(); + m_nodes[index]->m_v = m_backupVelocity[index] + dv[index]; } } diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index 22a685631..42d85f538 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -29,7 +29,7 @@ public: Preconditioner* m_preconditioner; btDeformableContactProjection projection; const TVStack& m_backupVelocity; - std::unordered_map m_indices; + btAlignedObjectArray m_nodes; btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v); @@ -97,20 +97,23 @@ public: virtual void updateId() { - size_t index = 0; + size_t id = 0; + m_nodes.clear(); for (int i = 0; i < m_softBodies.size(); ++i) { btSoftBody* psb = m_softBodies[i]; for (int j = 0; j < psb->m_nodes.size(); ++j) { - m_indices[&(psb->m_nodes[j])] = index++; + psb->m_nodes[j].index = id; + m_nodes.push_back(&psb->m_nodes[j]); + ++id; } } } - std::unordered_map* getIndices() + const btAlignedObjectArray* getIndices() const { - return &m_indices; + return &m_nodes; } }; diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index a1616a460..4be5d4680 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -50,6 +50,7 @@ void btDeformableBodySolver::reinitialize(const btAlignedObjectArray cg; + public: btDeformableBackwardEulerObjective* m_objective; diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index 4ae07290c..5a3f9e555 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -8,7 +8,7 @@ #include "btDeformableContactProjection.h" #include "btDeformableRigidDynamicsWorld.h" #include -#include +#include static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol, btMultiBodyJacobianData& jacobianData, const btVector3& contact_point, @@ -49,10 +49,10 @@ void btDeformableContactProjection::update() m_world->btMultiBodyDynamicsWorld::solveInternalConstraints(m_world->getSolverInfo()); // loop through constraints to set constrained values - for (auto& it : m_constraints) + for (int index = 0; index < m_constraints.size(); ++index) { - btAlignedObjectArray& frictions = m_frictions[it.first]; - btAlignedObjectArray& constraints = it.second; + btAlignedObjectArray& frictions = *m_frictions[m_constraints.getKeyAtIndex(index)]; + btAlignedObjectArray& constraints = *m_constraints.getAtIndex(index); for (int i = 0; i < constraints.size(); ++i) { DeformableContactConstraint& constraint = constraints[i]; @@ -230,13 +230,13 @@ void btDeformableContactProjection::setConstraints() c.push_back(DeformableContactConstraint(btVector3(1,0,0))); c.push_back(DeformableContactConstraint(btVector3(0,1,0))); c.push_back(DeformableContactConstraint(btVector3(0,0,1))); - m_constraints[&(psb->m_nodes[j])] = c; + m_constraints.insert(psb->m_nodes[j].index, c); btAlignedObjectArray f; f.push_back(DeformableFrictionConstraint()); f.push_back(DeformableFrictionConstraint()); f.push_back(DeformableFrictionConstraint()); - m_frictions[&(psb->m_nodes[j])] = f; + m_frictions.insert(psb->m_nodes[j].index, f); } } } @@ -290,22 +290,22 @@ void btDeformableContactProjection::setConstraints() const btScalar dn = btDot(vr, cti.m_normal); if (dn < SIMD_EPSILON) { - if (m_constraints.find(c.m_node) == m_constraints.end()) + if (m_constraints.find(c.m_node->index) == NULL) { btAlignedObjectArray constraints; constraints.push_back(DeformableContactConstraint(c)); - m_constraints[c.m_node] = constraints; + m_constraints.insert(c.m_node->index,constraints); btAlignedObjectArray frictions; frictions.push_back(DeformableFrictionConstraint()); - m_frictions[c.m_node] = frictions; + m_frictions.insert(c.m_node->index,frictions); } else { // group colinear constraints into one const btScalar angle_epsilon = 0.015192247; // less than 10 degree bool merged = false; - btAlignedObjectArray& constraints = m_constraints[c.m_node]; - btAlignedObjectArray& frictions = m_frictions[c.m_node]; + btAlignedObjectArray& constraints = *m_constraints[c.m_node->index]; + btAlignedObjectArray& frictions = *m_frictions[c.m_node->index]; for (int j = 0; j < constraints.size(); ++j) { const btAlignedObjectArray& dirs = constraints[j].m_direction; @@ -337,11 +337,11 @@ void btDeformableContactProjection::setConstraints() void btDeformableContactProjection::enforceConstraint(TVStack& x) { const int dim = 3; - for (auto& it : m_constraints) + for (int index = 0; index < m_constraints.size(); ++index) { - const btAlignedObjectArray& constraints = it.second; - size_t i = m_indices->at(it.first); - const btAlignedObjectArray& frictions = m_frictions[it.first]; + const btAlignedObjectArray& constraints = *m_constraints.getAtIndex(index); + size_t i = m_constraints.getKeyAtIndex(index).getUid1(); + const btAlignedObjectArray& frictions = *m_frictions[m_constraints.getKeyAtIndex(index)]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); if (constraints.size() == 1) @@ -400,11 +400,11 @@ void btDeformableContactProjection::enforceConstraint(TVStack& x) void btDeformableContactProjection::project(TVStack& x) { const int dim = 3; - for (auto& it : m_constraints) + for (int index = 0; index < m_constraints.size(); ++index) { - const btAlignedObjectArray& constraints = it.second; - size_t i = m_indices->at(it.first); - btAlignedObjectArray& frictions = m_frictions[it.first]; + const btAlignedObjectArray& constraints = *m_constraints.getAtIndex(index); + size_t i = m_constraints.getKeyAtIndex(index).getUid1(); + btAlignedObjectArray& frictions = *m_frictions[m_constraints.getKeyAtIndex(index)]; btAssert(constraints.size() <= dim); btAssert(constraints.size() > 0); if (constraints.size() == 1) diff --git a/src/BulletSoftBody/btDeformableContactProjection.h b/src/BulletSoftBody/btDeformableContactProjection.h index 2ca571195..9e61fed34 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.h +++ b/src/BulletSoftBody/btDeformableContactProjection.h @@ -11,14 +11,19 @@ #include "btSoftBody.h" #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" +#include "LinearMath/btHashMap.h" class btDeformableContactProjection : public btCGProjection { public: - std::unordered_map > m_constraints; - std::unordered_map > m_frictions; +// std::unordered_map > m_constraints; +// std::unordered_map > m_frictions; - btDeformableContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt, const std::unordered_map* indices) - : btCGProjection(softBodies, dt, indices) + // map from node index to constraints + btHashMap > m_constraints; + btHashMap >m_frictions; + + btDeformableContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt, const btAlignedObjectArray* nodes) + : btCGProjection(softBodies, dt, nodes) { } diff --git a/src/BulletSoftBody/btDeformableGravityForce.h b/src/BulletSoftBody/btDeformableGravityForce.h index 88d9107e1..0c2ae535d 100644 --- a/src/BulletSoftBody/btDeformableGravityForce.h +++ b/src/BulletSoftBody/btDeformableGravityForce.h @@ -47,7 +47,7 @@ public: for (int j = 0; j < psb->m_nodes.size(); ++j) { btSoftBody::Node& n = psb->m_nodes[j]; - size_t id = m_indices->at(&n); + size_t id = n.index; btScalar mass = (n.m_im == 0) ? 0 : 1. / n.m_im; btVector3 scaled_force = scale * m_gravity * mass; force[id] += scaled_force; diff --git a/src/BulletSoftBody/btDeformableLagrangianForce.h b/src/BulletSoftBody/btDeformableLagrangianForce.h index ff75eeb1c..6e1c54352 100644 --- a/src/BulletSoftBody/btDeformableLagrangianForce.h +++ b/src/BulletSoftBody/btDeformableLagrangianForce.h @@ -9,7 +9,8 @@ #define BT_DEFORMABLE_LAGRANGIAN_FORCE_H #include "btSoftBody.h" -#include +#include + enum btDeformableLagrangianForceType { BT_GRAVITY_FORCE = 1, @@ -22,7 +23,7 @@ public: // using TVStack = btAlignedObjectArray; typedef btAlignedObjectArray TVStack; btAlignedObjectArray m_softBodies; - const std::unordered_map* m_indices; + const btAlignedObjectArray* m_nodes; btDeformableLagrangianForce() { @@ -57,9 +58,9 @@ public: m_softBodies.push_back(psb); } - virtual void setIndices(const std::unordered_map* indices) + virtual void setIndices(const btAlignedObjectArray* nodes) { - m_indices = indices; + m_nodes = nodes; } }; #endif /* BT_DEFORMABLE_LAGRANGIAN_FORCE */ diff --git a/src/BulletSoftBody/btDeformableMassSpringForce.h b/src/BulletSoftBody/btDeformableMassSpringForce.h index d3ccd70dc..841101c8f 100644 --- a/src/BulletSoftBody/btDeformableMassSpringForce.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -41,8 +41,8 @@ public: const btSoftBody::Link& link = psb->m_links[j]; btSoftBody::Node* node1 = link.m_n[0]; btSoftBody::Node* node2 = link.m_n[1]; - size_t id1 = m_indices->at(node1); - size_t id2 = m_indices->at(node2); + size_t id1 = node1->index; + size_t id2 = node2->index; // damping force btVector3 v_diff = (node2->m_v - node1->m_v); @@ -68,8 +68,8 @@ public: btSoftBody::Node* node2 = link.m_n[1]; btScalar kLST = link.Feature::m_material->m_kLST; btScalar r = link.m_rl; - size_t id1 = m_indices->at(node1); - size_t id2 = m_indices->at(node2); + size_t id1 = node1->index; + size_t id2 = node2->index; // elastic force // explicit elastic force @@ -94,8 +94,8 @@ public: btSoftBody::Node* node1 = link.m_n[0]; btSoftBody::Node* node2 = link.m_n[1]; btScalar k_damp = psb->m_dampingCoefficient; - size_t id1 = m_indices->at(node1); - size_t id2 = m_indices->at(node2); + size_t id1 = node1->index; + size_t id2 = node2->index; btVector3 local_scaled_df = scale * k_damp * (dv[id2] - dv[id1]); df[id1] += local_scaled_df; df[id2] -= local_scaled_df; diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 78c5f24a9..6e1ed75bd 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -45,10 +45,11 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) { // perform position correction for all constraints - for (auto& it : m_deformableBodySolver->m_objective->projection.m_constraints) +// for (auto& it : m_deformableBodySolver->m_objective->projection.m_constraints) + for (int index = 0; index < m_deformableBodySolver->m_objective->projection.m_constraints.size(); ++index) { - btAlignedObjectArray& frictions = m_deformableBodySolver->m_objective->projection.m_frictions[it.first]; - btAlignedObjectArray& constraints = it.second; + btAlignedObjectArray& frictions = *m_deformableBodySolver->m_objective->projection.m_frictions[m_deformableBodySolver->m_objective->projection.m_constraints.getKeyAtIndex(index)]; + btAlignedObjectArray& constraints = *m_deformableBodySolver->m_objective->projection.m_constraints.getAtIndex(index); for (int i = 0; i < constraints.size(); ++i) { DeformableContactConstraint& constraint = constraints[i]; diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index 5e33d74d0..87633a83c 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -258,6 +258,7 @@ public: btScalar m_area; // Area btDbvtNode* m_leaf; // Leaf data int m_battach : 1; // Attached + int index; }; /* Link */ ATTRIBUTE_ALIGNED16(struct) diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 77bcdc5d8..eb487a56f 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -995,7 +995,9 @@ struct btSoftColliders btScalar* u_t1 = &jacobianData_t1.m_deltaVelocitiesUnitImpulse[0]; btScalar* u_t2 = &jacobianData_t2.m_deltaVelocitiesUnitImpulse[0]; - btMatrix3x3 rot(normal, t1, t2); // world frame to local frame + btMatrix3x3 rot(normal.getX(), normal.getY(), normal.getZ(), + t1.getX(), t1.getY(), t1.getZ(), + t2.getX(), t2.getY(), t2.getZ()); // world frame to local frame const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; btScalar dt = psb->m_sst.sdt; btMatrix3x3 local_impulse_matrix = Diagonal(1/dt) * (Diagonal(n.m_im) + OuterProduct(J_n, J_t1, J_t2, u_n, u_t1, u_t2, ndof)).inverse(); From 021cbb2a0ea0e5e7a4b19908bfd8663b2300b82a Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 2 Aug 2019 23:50:15 -0700 Subject: [PATCH 34/47] include numeric_limits --- src/BulletSoftBody/btDeformableBodySolver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index 4be5d4680..df12c213a 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -6,6 +6,7 @@ // #include +#include #include "btDeformableBodySolver.h" btDeformableBodySolver::btDeformableBodySolver() From c5d84c1a0b5f1120f0a392b8894b0d685193864b Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Sat, 3 Aug 2019 00:10:36 -0700 Subject: [PATCH 35/47] get rid of nullptr and std::function --- examples/Pinch/Pinch.cpp | 2 +- src/BulletSoftBody/btCGProjection.h | 4 ++-- .../btDeformableContactProjection.cpp | 2 +- .../btDeformableRigidDynamicsWorld.cpp | 20 ++++++++++++++----- .../btDeformableRigidDynamicsWorld.h | 10 +++++++++- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/examples/Pinch/Pinch.cpp b/examples/Pinch/Pinch.cpp index 4252a47b8..1e4afb748 100644 --- a/examples/Pinch/Pinch.cpp +++ b/examples/Pinch/Pinch.cpp @@ -256,7 +256,7 @@ void Pinch::initPhysics() m_dynamicsWorld->setGravity(gravity); getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity; - getDeformableDynamicsWorld()->m_beforeSolverCallbacks.push_back(dynamics); + getDeformableDynamicsWorld()->setSolverCallback(dynamics); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); //create a ground diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 144208908..e11ecf817 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -29,7 +29,7 @@ struct DeformableContactConstraint DeformableContactConstraint(const btVector3 dir) { - m_contact.push_back(nullptr); + m_contact.push_back(NULL); m_direction.push_back(dir); m_value.push_back(0); m_accumulated_normal_impulse.push_back(0); @@ -37,7 +37,7 @@ struct DeformableContactConstraint DeformableContactConstraint() { - m_contact.push_back(nullptr); + m_contact.push_back(NULL); m_direction.push_back(btVector3(0,0,0)); m_value.push_back(0); m_accumulated_normal_impulse.push_back(0); diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index 5a3f9e555..edee3126e 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -59,7 +59,7 @@ void btDeformableContactProjection::update() DeformableFrictionConstraint& friction = frictions[i]; for (int j = 0; j < constraint.m_contact.size(); ++j) { - if (constraint.m_contact[j] == nullptr) + if (constraint.m_contact[j] == NULL) { // nothing needs to be done for dirichelet constraints continue; diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 6e1ed75bd..de39778ad 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -58,7 +58,7 @@ void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) { const btSoftBody::RContact* c = constraint.m_contact[j]; // skip anchor points - if (c == nullptr || c->m_node->m_im == 0) + if (c == NULL || c->m_node->m_im == 0) continue; const btSoftBody::sCti& cti = c->m_cti; btVector3 va(0, 0, 0); @@ -206,14 +206,24 @@ void btDeformableRigidDynamicsWorld::beforeSolverCallbacks(btScalar timeStep) { (*m_internalTickCallback)(this, timeStep); } - for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) - m_beforeSolverCallbacks[i](m_internalTime, this); + + if (0 != m_solverCallback) + { + (*m_solverCallback)(m_internalTime, this); + } + +// for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) +// m_beforeSolverCallbacks[i](m_internalTime, this); } void btDeformableRigidDynamicsWorld::afterSolverCallbacks(btScalar timeStep) { - for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) - m_beforeSolverCallbacks[i](m_internalTime, this); + if (0 != m_solverCallback) + { + (*m_solverCallback)(m_internalTime, this); + } +// for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) +// m_beforeSolverCallbacks[i](m_internalTime, this); } void btDeformableRigidDynamicsWorld::addForce(btSoftBody* psb, btDeformableLagrangianForce* force) diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 779a88ee3..47284e7fb 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -75,7 +75,15 @@ public: m_sbi.m_sparsesdf.Initialize(); m_internalTime = 0.0; } - btAlignedObjectArray > m_beforeSolverCallbacks; +// btAlignedObjectArray > m_beforeSolverCallbacks; + typedef void (*btSolverCallback)(btScalar time, btDeformableRigidDynamicsWorld* world); + btSolverCallback m_solverCallback; + + void setSolverCallback(btSolverCallback cb) + { + m_solverCallback = cb; + } + virtual ~btDeformableRigidDynamicsWorld() { } From 02d3a9469f7431d9e4e120eafcf7ccba76596e6a Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Mon, 5 Aug 2019 11:54:17 -0700 Subject: [PATCH 36/47] code clean up + Zlib copyright header --- src/BulletSoftBody/btCGProjection.h | 19 +++++++----- src/BulletSoftBody/btConjugateGradient.h | 22 +++++++++----- .../btDeformableBackwardEulerObjective.cpp | 21 +++++++++----- .../btDeformableBackwardEulerObjective.h | 18 ++++++++---- src/BulletSoftBody/btDeformableBodySolver.cpp | 22 +++++++++----- src/BulletSoftBody/btDeformableBodySolver.h | 20 ++++++++----- .../btDeformableContactProjection.cpp | 18 ++++++++---- .../btDeformableContactProjection.h | 21 ++++++++------ src/BulletSoftBody/btDeformableGravityForce.h | 21 ++++++++------ .../btDeformableLagrangianForce.h | 18 ++++++++---- .../btDeformableMassSpringForce.h | 18 ++++++++---- .../btDeformableRigidDynamicsWorld.cpp | 29 +++++++++---------- .../btDeformableRigidDynamicsWorld.h | 8 +++-- src/BulletSoftBody/btPreconditioner.h | 18 ++++++++---- 14 files changed, 170 insertions(+), 103 deletions(-) diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index e11ecf817..667c715c0 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -1,8 +1,15 @@ -// btCGProjection.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/4/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_CG_PROJECTION_H #define BT_CG_PROJECTION_H @@ -20,7 +27,6 @@ struct DeformableContactConstraint btAlignedObjectArray m_value; // the magnitude of the total impulse the node applied to the rb in the normal direction in the cg solve btAlignedObjectArray m_accumulated_normal_impulse; - btSoftBody::Node* node; DeformableContactConstraint(const btSoftBody::RContact& rcontact) { @@ -74,7 +80,6 @@ struct DeformableFrictionConstraint // the total impulse the node applied to the rb in the tangential direction in the cg solve btAlignedObjectArray m_accumulated_tangent_impulse; - btSoftBody::Node* node; DeformableFrictionConstraint() { diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index fdef6b22d..dfec3dde5 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -1,9 +1,15 @@ -// -// btConjugateGradient.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/1/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_CONJUGATE_GRADIENT_H #define BT_CONJUGATE_GRADIENT_H @@ -12,7 +18,7 @@ #include #include -template +template class btConjugateGradient { // using TVStack = btAlignedObjectArray; @@ -29,7 +35,7 @@ public: virtual ~btConjugateGradient(){} // return the number of iterations taken - int solve(TM& A, TVStack& x, const TVStack& b, btScalar tolerance) + int solve(MatrixX& A, TVStack& x, const TVStack& b, btScalar tolerance) { btAssert(x.size() == b.size()); reinitialize(b); diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 50db01ec9..618648b47 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -1,9 +1,15 @@ -// -// btDeformableBackwardEulerObjective.cpp -// BulletSoftBody -// -// Created by Xuchen Han on 7/9/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 "btDeformableBackwardEulerObjective.h" @@ -63,7 +69,6 @@ void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) void btDeformableBackwardEulerObjective::updateVelocity(const TVStack& dv) { // only the velocity of the constrained nodes needs to be updated during CG solve -// for (auto it : projection.m_constraints) for (int i = 0; i < projection.m_constraints.size(); ++i) { int index = projection.m_constraints.getKeyAtIndex(i).getUid1(); @@ -112,7 +117,9 @@ btScalar btDeformableBackwardEulerObjective::computeNorm(const TVStack& residual void btDeformableBackwardEulerObjective::applyExplicitForce(TVStack& force) { for (int i = 0; i < m_lf.size(); ++i) + { m_lf[i]->addScaledExplicitForce(m_dt, force); + } applyForce(force, true); } diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index 42d85f538..db448ebe9 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -1,9 +1,15 @@ -// -// btDeformableBackwardEulerObjective.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/1/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_BACKWARD_EULER_OBJECTIVE_H #define BT_BACKWARD_EULER_OBJECTIVE_H diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index df12c213a..27cb8e467 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -1,9 +1,15 @@ -// -// btDeformableBodySolver.cpp -// BulletSoftBody -// -// Created by Xuchen Han on 7/9/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 @@ -11,7 +17,7 @@ btDeformableBodySolver::btDeformableBodySolver() : m_numNodes(0) -, cg(10) +, m_cg(10) { m_objective = new btDeformableBackwardEulerObjective(m_softBodySet, m_backupVelocity); } @@ -40,7 +46,7 @@ void btDeformableBodySolver::solveConstraints(float solverdt) void btDeformableBodySolver::computeStep(TVStack& dv, const TVStack& residual) { btScalar tolerance = std::numeric_limits::epsilon()* 1024 * m_objective->computeNorm(residual); - cg.solve(*m_objective, dv, residual, tolerance); + m_cg.solve(*m_objective, dv, residual, tolerance); } void btDeformableBodySolver::reinitialize(const btAlignedObjectArray& softBodies) diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 9f1216eab..7186f8fb2 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -1,9 +1,15 @@ -// -// btDeformableBodySolver.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/1/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_DEFORMABLE_BODY_SOLVERS_H #define BT_DEFORMABLE_BODY_SOLVERS_H @@ -31,7 +37,7 @@ protected: btAlignedObjectArray m_backupVelocity; btScalar m_dt; - btConjugateGradient cg; + btConjugateGradient m_cg; public: diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index edee3126e..dff5398c9 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -1,9 +1,15 @@ -// -// btDeformableContactProjection.cpp -// BulletSoftBody -// -// Created by Xuchen Han on 7/4/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 "btDeformableContactProjection.h" #include "btDeformableRigidDynamicsWorld.h" diff --git a/src/BulletSoftBody/btDeformableContactProjection.h b/src/BulletSoftBody/btDeformableContactProjection.h index 9e61fed34..51ea92689 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.h +++ b/src/BulletSoftBody/btDeformableContactProjection.h @@ -1,9 +1,15 @@ -// -// btDeformableContactProjection.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/4/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_CONTACT_PROJECTION_H #define BT_CONTACT_PROJECTION_H @@ -15,9 +21,6 @@ class btDeformableContactProjection : public btCGProjection { public: -// std::unordered_map > m_constraints; -// std::unordered_map > m_frictions; - // map from node index to constraints btHashMap > m_constraints; btHashMap >m_frictions; diff --git a/src/BulletSoftBody/btDeformableGravityForce.h b/src/BulletSoftBody/btDeformableGravityForce.h index 0c2ae535d..d18eac57d 100644 --- a/src/BulletSoftBody/btDeformableGravityForce.h +++ b/src/BulletSoftBody/btDeformableGravityForce.h @@ -1,9 +1,15 @@ -// -// btDeformableGravityForce.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/21/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_DEFORMABLE_GRAVITY_FORCE_H #define BT_DEFORMABLE_GRAVITY_FORCE_H @@ -13,18 +19,15 @@ class btDeformableGravityForce : public btDeformableLagrangianForce { public: -// using TVStack = btDeformableLagrangianForce::TVStack; typedef btAlignedObjectArray TVStack; btVector3 m_gravity; btDeformableGravityForce(const btVector3& g) : m_gravity(g) { - } virtual void addScaledImplicitForce(btScalar scale, TVStack& force) { -// addScaledGravityForce(scale, force); } virtual void addScaledExplicitForce(btScalar scale, TVStack& force) diff --git a/src/BulletSoftBody/btDeformableLagrangianForce.h b/src/BulletSoftBody/btDeformableLagrangianForce.h index 6e1c54352..d2bbcef40 100644 --- a/src/BulletSoftBody/btDeformableLagrangianForce.h +++ b/src/BulletSoftBody/btDeformableLagrangianForce.h @@ -1,9 +1,15 @@ -// -// btDeformableLagrangianForce.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/1/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_DEFORMABLE_LAGRANGIAN_FORCE_H #define BT_DEFORMABLE_LAGRANGIAN_FORCE_H diff --git a/src/BulletSoftBody/btDeformableMassSpringForce.h b/src/BulletSoftBody/btDeformableMassSpringForce.h index 841101c8f..2d70ef0ae 100644 --- a/src/BulletSoftBody/btDeformableMassSpringForce.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -1,9 +1,15 @@ -// -// btDeformableMassSpringForce.h -// BulletSoftBody -// -// Created by Xuchen Gan on 7/1/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_MASS_SPRING_H #define BT_MASS_SPRING_H diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index de39778ad..ef48f97b1 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -1,9 +1,15 @@ -// -// btDeformableRigidDynamicsWorld.cpp -// BulletSoftBody -// -// Created by Xuchen Han on 7/1/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 "btDeformableRigidDynamicsWorld.h" @@ -13,7 +19,6 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { reinitialize(timeStep); -// beforeSolverCallbacks(timeStep); // add gravity to velocity of rigid and multi bodys applyRigidBodyGravity(timeStep); @@ -165,7 +170,7 @@ void btDeformableRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collision void btDeformableRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) { btMultiBodyDynamicsWorld::predictUnconstraintMotion(timeStep); - m_deformableBodySolver->predictMotion(float(timeStep)); + m_deformableBodySolver->predictMotion(timeStep); } void btDeformableRigidDynamicsWorld::reinitialize(btScalar timeStep) @@ -181,8 +186,7 @@ void btDeformableRigidDynamicsWorld::reinitialize(btScalar timeStep) void btDeformableRigidDynamicsWorld::applyRigidBodyGravity(btScalar timeStep) { - // TODO: This is an ugly hack to get the desired gravity behavior. - // gravity is applied in stepSimulation and then cleared here and then applied here and then cleared here again + // Gravity is applied in stepSimulation and then cleared here and then applied here and then cleared here again // so that 1) gravity is applied to velocity before constraint solve and 2) gravity is applied in each substep // when there are multiple substeps clearForces(); @@ -211,9 +215,6 @@ void btDeformableRigidDynamicsWorld::beforeSolverCallbacks(btScalar timeStep) { (*m_solverCallback)(m_internalTime, this); } - -// for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) -// m_beforeSolverCallbacks[i](m_internalTime, this); } void btDeformableRigidDynamicsWorld::afterSolverCallbacks(btScalar timeStep) @@ -222,8 +223,6 @@ void btDeformableRigidDynamicsWorld::afterSolverCallbacks(btScalar timeStep) { (*m_solverCallback)(m_internalTime, this); } -// for (int i = 0; i < m_beforeSolverCallbacks.size(); ++i) -// m_beforeSolverCallbacks[i](m_internalTime, this); } void btDeformableRigidDynamicsWorld::addForce(btSoftBody* psb, btDeformableLagrangianForce* force) diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 47284e7fb..7d771d455 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -43,6 +43,9 @@ class btDeformableRigidDynamicsWorld : public btMultiBodyDynamicsWorld bool m_ownsSolver; btScalar m_internalTime; + typedef void (*btSolverCallback)(btScalar time, btDeformableRigidDynamicsWorld* world); + btSolverCallback m_solverCallback; + protected: virtual void internalSingleStepSimulation(btScalar timeStep); @@ -55,7 +58,7 @@ protected: public: btDeformableRigidDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btDeformableBodySolver* deformableBodySolver = 0) : btMultiBodyDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration), - m_deformableBodySolver(deformableBodySolver) + m_deformableBodySolver(deformableBodySolver), m_solverCallback(0) { m_drawFlags = fDrawFlags::Std; m_drawNodeTree = true; @@ -76,8 +79,7 @@ public: m_internalTime = 0.0; } // btAlignedObjectArray > m_beforeSolverCallbacks; - typedef void (*btSolverCallback)(btScalar time, btDeformableRigidDynamicsWorld* world); - btSolverCallback m_solverCallback; + void setSolverCallback(btSolverCallback cb) { diff --git a/src/BulletSoftBody/btPreconditioner.h b/src/BulletSoftBody/btPreconditioner.h index 97cec43c5..8860a8cfe 100644 --- a/src/BulletSoftBody/btPreconditioner.h +++ b/src/BulletSoftBody/btPreconditioner.h @@ -1,9 +1,15 @@ -// -// btPreconditioner.h -// BulletSoftBody -// -// Created by Xuchen Han on 7/18/19. -// +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 BT_PRECONDITIONER_H #define BT_PRECONDITIONER_H From 73f5eb6a8f477c46b18a61476e81dc4dd9cb6612 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Mon, 5 Aug 2019 16:49:04 -0700 Subject: [PATCH 37/47] add profiling and code clean up --- src/BulletSoftBody/btConjugateGradient.h | 5 ++--- .../btDeformableBackwardEulerObjective.cpp | 11 ++++++----- .../btDeformableBackwardEulerObjective.h | 5 +++-- src/BulletSoftBody/btDeformableBodySolver.cpp | 3 +++ src/BulletSoftBody/btDeformableContactProjection.cpp | 8 +++++--- src/BulletSoftBody/btDeformableMassSpringForce.h | 4 ++-- src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp | 7 +++++-- src/BulletSoftBody/btDeformableRigidDynamicsWorld.h | 4 +--- 8 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index dfec3dde5..b8dac7184 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -17,15 +17,13 @@ #include #include #include - +#include "LinearMath/btQuickprof.h" template class btConjugateGradient { -// using TVStack = btAlignedObjectArray; typedef btAlignedObjectArray TVStack; TVStack r,p,z,temp; int max_iterations; - public: btConjugateGradient(const int max_it_in) : max_iterations(max_it_in) @@ -37,6 +35,7 @@ public: // return the number of iterations taken int solve(MatrixX& A, TVStack& x, const TVStack& b, btScalar tolerance) { + BT_PROFILE("CGSolve"); btAssert(x.size() == b.size()); reinitialize(b); diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 618648b47..44783fb3d 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -12,6 +12,7 @@ */ #include "btDeformableBackwardEulerObjective.h" +#include "LinearMath/btQuickprof.h" btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) : m_softBodies(softBodies) @@ -23,6 +24,7 @@ btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAligned void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated) { + BT_PROFILE("reinitialize"); if(nodeUpdated) { updateId(); @@ -43,9 +45,7 @@ void btDeformableBackwardEulerObjective::setDt(btScalar dt) void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) const { - for (int i = 0; i < b.size(); ++i) - b[i].setZero(); - + BT_PROFILE("multiply"); // add in the mass term size_t counter = 0; for (int i = 0; i < m_softBodies.size(); ++i) @@ -54,11 +54,11 @@ void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b) for (int j = 0; j < psb->m_nodes.size(); ++j) { const btSoftBody::Node& node = psb->m_nodes[j]; - b[counter] += (node.m_im == 0) ? btVector3(0,0,0) : x[counter] / node.m_im; + b[counter] = (node.m_im == 0) ? btVector3(0,0,0) : x[counter] / node.m_im; ++counter; } } - + for (int i = 0; i < m_lf.size(); ++i) { // add damping matrix @@ -97,6 +97,7 @@ void btDeformableBackwardEulerObjective::applyForce(TVStack& force, bool setZero void btDeformableBackwardEulerObjective::computeResidual(btScalar dt, TVStack &residual) const { + BT_PROFILE("computeResidual"); // add implicit force for (int i = 0; i < m_lf.size(); ++i) { diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index db448ebe9..82af57f6d 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -13,7 +13,6 @@ #ifndef BT_BACKWARD_EULER_OBJECTIVE_H #define BT_BACKWARD_EULER_OBJECTIVE_H -#include #include "btConjugateGradient.h" #include "btDeformableLagrangianForce.h" #include "btDeformableMassSpringForce.h" @@ -21,6 +20,7 @@ #include "btDeformableContactProjection.h" #include "btPreconditioner.h" #include "btDeformableRigidDynamicsWorld.h" +#include "LinearMath/btQuickprof.h" class btDeformableRigidDynamicsWorld; class btDeformableBackwardEulerObjective @@ -36,7 +36,6 @@ public: btDeformableContactProjection projection; const TVStack& m_backupVelocity; btAlignedObjectArray m_nodes; - btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v); virtual ~btDeformableBackwardEulerObjective() {} @@ -72,6 +71,7 @@ public: // enforce constraints in CG solve void enforceConstraint(TVStack& x) { + BT_PROFILE("enforceConstraint"); projection.enforceConstraint(x); updateVelocity(x); } @@ -85,6 +85,7 @@ public: // update the projections and project the residual void project(TVStack& r) { + BT_PROFILE("project"); projection.update(); projection.project(r); } diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index 27cb8e467..9382106e9 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -14,6 +14,7 @@ #include #include #include "btDeformableBodySolver.h" +#include "LinearMath/btQuickprof.h" btDeformableBodySolver::btDeformableBodySolver() : m_numNodes(0) @@ -29,6 +30,7 @@ btDeformableBodySolver::~btDeformableBodySolver() void btDeformableBodySolver::solveConstraints(float solverdt) { + BT_PROFILE("solveConstraints"); m_objective->setDt(solverdt); // add constraints to the solver @@ -70,6 +72,7 @@ void btDeformableBodySolver::reinitialize(const btAlignedObjectArraysetConstraints(); } diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index dff5398c9..7470c7a93 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -224,6 +224,7 @@ void btDeformableContactProjection::update() void btDeformableContactProjection::setConstraints() { + BT_PROFILE("setConstraints"); // set Dirichlet constraint for (int i = 0; i < m_softBodies.size(); ++i) { @@ -233,12 +234,14 @@ void btDeformableContactProjection::setConstraints() if (psb->m_nodes[j].m_im == 0) { btAlignedObjectArray c; + c.reserve(3); c.push_back(DeformableContactConstraint(btVector3(1,0,0))); c.push_back(DeformableContactConstraint(btVector3(0,1,0))); c.push_back(DeformableContactConstraint(btVector3(0,0,1))); m_constraints.insert(psb->m_nodes[j].index, c); btAlignedObjectArray f; + f.reserve(3); f.push_back(DeformableFrictionConstraint()); f.push_back(DeformableFrictionConstraint()); f.push_back(DeformableFrictionConstraint()); @@ -246,13 +249,12 @@ void btDeformableContactProjection::setConstraints() } } } - for (int i = 0; i < m_softBodies.size(); ++i) { btSoftBody* psb = m_softBodies[i]; btMultiBodyJacobianData jacobianData_normal; btMultiBodyJacobianData jacobianData_complementary; - + std::cout <m_rcontacts.size() << std::endl; for (int j = 0; j < psb->m_rcontacts.size(); ++j) { const btSoftBody::RContact& c = psb->m_rcontacts[j]; @@ -296,6 +298,7 @@ void btDeformableContactProjection::setConstraints() const btScalar dn = btDot(vr, cti.m_normal); if (dn < SIMD_EPSILON) { + if (m_constraints.find(c.m_node->index) == NULL) { btAlignedObjectArray constraints; @@ -369,7 +372,6 @@ void btDeformableContactProjection::enforceConstraint(TVStack& x) x[i] += constraints[j].m_value[k] * constraints[j].m_direction[k]; } } - } else { diff --git a/src/BulletSoftBody/btDeformableMassSpringForce.h b/src/BulletSoftBody/btDeformableMassSpringForce.h index 2d70ef0ae..ca8ddf983 100644 --- a/src/BulletSoftBody/btDeformableMassSpringForce.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -94,15 +94,15 @@ public: for (int i = 0; i < m_softBodies.size(); ++i) { const btSoftBody* psb = m_softBodies[i]; + btScalar scaled_k_damp = psb->m_dampingCoefficient * scale; for (int j = 0; j < psb->m_links.size(); ++j) { const btSoftBody::Link& link = psb->m_links[j]; btSoftBody::Node* node1 = link.m_n[0]; btSoftBody::Node* node2 = link.m_n[1]; - btScalar k_damp = psb->m_dampingCoefficient; size_t id1 = node1->index; size_t id2 = node2->index; - btVector3 local_scaled_df = scale * k_damp * (dv[id2] - dv[id1]); + btVector3 local_scaled_df = scaled_k_damp * (dv[id2] - dv[id1]); df[id1] += local_scaled_df; df[id2] -= local_scaled_df; } diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index ef48f97b1..116d4e0bc 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -14,10 +14,11 @@ #include #include "btDeformableRigidDynamicsWorld.h" #include "btDeformableBodySolver.h" - +#include "LinearMath/btQuickprof.h" void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { + BT_PROFILE("internalSingleStepSimulation"); reinitialize(timeStep); // add gravity to velocity of rigid and multi bodys applyRigidBodyGravity(timeStep); @@ -50,7 +51,7 @@ void btDeformableRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeS void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) { // perform position correction for all constraints -// for (auto& it : m_deformableBodySolver->m_objective->projection.m_constraints) + BT_PROFILE("positionCorrection"); for (int index = 0; index < m_deformableBodySolver->m_objective->projection.m_constraints.size(); ++index) { btAlignedObjectArray& frictions = *m_deformableBodySolver->m_objective->projection.m_frictions[m_deformableBodySolver->m_objective->projection.m_constraints.getKeyAtIndex(index)]; @@ -134,6 +135,7 @@ void btDeformableRigidDynamicsWorld::positionCorrection(btScalar dt) void btDeformableRigidDynamicsWorld::integrateTransforms(btScalar dt) { + BT_PROFILE("integrateTransforms"); m_deformableBodySolver->backupVelocity(); positionCorrection(dt); btMultiBodyDynamicsWorld::integrateTransforms(dt); @@ -169,6 +171,7 @@ void btDeformableRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collision void btDeformableRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) { + BT_PROFILE("predictUnconstraintMotion"); btMultiBodyDynamicsWorld::predictUnconstraintMotion(timeStep); m_deformableBodySolver->predictMotion(timeStep); } diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 7d771d455..cc4fdae05 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -78,9 +78,7 @@ public: m_sbi.m_sparsesdf.Initialize(); m_internalTime = 0.0; } -// btAlignedObjectArray > m_beforeSolverCallbacks; - - + void setSolverCallback(btSolverCallback cb) { m_solverCallback = cb; From 6a599bde87e53c22fb71cb6d35c718e9ea8083dc Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Tue, 6 Aug 2019 10:16:56 -0700 Subject: [PATCH 38/47] setDt in reinitialize and remove unused variables --- src/BulletSoftBody/btCGProjection.h | 6 +++--- .../btDeformableBackwardEulerObjective.cpp | 2 +- src/BulletSoftBody/btDeformableBodySolver.cpp | 20 ++++++------------- src/BulletSoftBody/btDeformableBodySolver.h | 2 +- .../btDeformableContactProjection.cpp | 1 - .../btDeformableContactProjection.h | 4 ++-- .../btDeformableRigidDynamicsWorld.cpp | 2 +- 7 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 667c715c0..430327ea0 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -113,13 +113,13 @@ public: typedef btAlignedObjectArray > TArrayStack; btAlignedObjectArray m_softBodies; btDeformableRigidDynamicsWorld* m_world; - const btAlignedObjectArray* m_nodes; +// const btAlignedObjectArray* m_nodes; const btScalar& m_dt; - btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt, const btAlignedObjectArray* nodes) + btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : m_softBodies(softBodies) , m_dt(dt) - , m_nodes(nodes) +// , m_nodes(nodes) { } diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 44783fb3d..3e6656c0d 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -16,7 +16,7 @@ btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAlignedObjectArray& softBodies, const TVStack& backup_v) : m_softBodies(softBodies) -, projection(m_softBodies, m_dt, &m_nodes) +, projection(m_softBodies, m_dt) , m_backupVelocity(backup_v) { m_preconditioner = new DefaultPreconditioner(); diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index 9382106e9..242b0a882 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -31,8 +31,6 @@ btDeformableBodySolver::~btDeformableBodySolver() void btDeformableBodySolver::solveConstraints(float solverdt) { BT_PROFILE("solveConstraints"); - m_objective->setDt(solverdt); - // add constraints to the solver setConstraints(); @@ -51,22 +49,16 @@ void btDeformableBodySolver::computeStep(TVStack& dv, const TVStack& residual) m_cg.solve(*m_objective, dv, residual, tolerance); } -void btDeformableBodySolver::reinitialize(const btAlignedObjectArray& softBodies) +void btDeformableBodySolver::reinitialize(const btAlignedObjectArray& softBodies, btScalar dt) { + m_objective->setDt(dt); m_softBodySet.copyFromArray(softBodies); bool nodeUpdated = updateNodes(); - if (nodeUpdated) - { - m_dv.resize(m_numNodes); - m_residual.resize(m_numNodes); - m_backupVelocity.resize(m_numNodes); - } - for (int i = 0; i < m_dv.size(); ++i) - { - m_dv[i].setZero(); - m_residual[i].setZero(); - } + m_dv.resize(m_numNodes, btVector3(0,0,0)); + m_residual.resize(m_numNodes, btVector3(0,0,0)); + m_backupVelocity.resize(m_numNodes, btVector3(0,0,0)); + m_objective->reinitialize(nodeUpdated); } diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index 7186f8fb2..cdcc6ed80 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -60,7 +60,7 @@ public: virtual void solveConstraints(float solverdt); - void reinitialize(const btAlignedObjectArray& softBodies); + void reinitialize(const btAlignedObjectArray& softBodies, btScalar dt); void setConstraints(); diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index 7470c7a93..27fee5cf8 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -254,7 +254,6 @@ void btDeformableContactProjection::setConstraints() btSoftBody* psb = m_softBodies[i]; btMultiBodyJacobianData jacobianData_normal; btMultiBodyJacobianData jacobianData_complementary; - std::cout <m_rcontacts.size() << std::endl; for (int j = 0; j < psb->m_rcontacts.size(); ++j) { const btSoftBody::RContact& c = psb->m_rcontacts[j]; diff --git a/src/BulletSoftBody/btDeformableContactProjection.h b/src/BulletSoftBody/btDeformableContactProjection.h index 51ea92689..9589b165e 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.h +++ b/src/BulletSoftBody/btDeformableContactProjection.h @@ -25,8 +25,8 @@ public: btHashMap > m_constraints; btHashMap >m_frictions; - btDeformableContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt, const btAlignedObjectArray* nodes) - : btCGProjection(softBodies, dt, nodes) + btDeformableContactProjection(btAlignedObjectArray& softBodies, const btScalar& dt) + : btCGProjection(softBodies, dt) { } diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 116d4e0bc..5afc88323 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -179,7 +179,7 @@ void btDeformableRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep void btDeformableRigidDynamicsWorld::reinitialize(btScalar timeStep) { m_internalTime += timeStep; - m_deformableBodySolver->reinitialize(m_softBodies); + m_deformableBodySolver->reinitialize(m_softBodies, timeStep); btDispatcherInfo& dispatchInfo = btMultiBodyDynamicsWorld::getDispatchInfo(); dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_stepCount = 0; From e5231b5cc57d617a38bb0144e5a34661b54a8811 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Tue, 6 Aug 2019 10:52:19 -0700 Subject: [PATCH 39/47] restore behaviors of btSoftBody --- .../DeformableContact/DeformableContact.cpp | 1 + examples/DeformableDemo/DeformableDemo.cpp | 1 + examples/Pinch/Pinch.cpp | 1 + .../VolumetricDeformable.cpp | 1 + .../btDeformableBackwardEulerObjective.h | 1 - src/BulletSoftBody/btDeformableBodySolver.cpp | 3 - src/BulletSoftBody/btSoftBody.cpp | 262 +++++++++++------- src/BulletSoftBody/btSoftBody.h | 4 +- src/BulletSoftBody/btSoftBodyInternals.h | 60 +++- 9 files changed, 221 insertions(+), 113 deletions(-) diff --git a/examples/DeformableContact/DeformableContact.cpp b/examples/DeformableContact/DeformableContact.cpp index c40564867..102ad40a9 100644 --- a/examples/DeformableContact/DeformableContact.cpp +++ b/examples/DeformableContact/DeformableContact.cpp @@ -228,6 +228,7 @@ void DeformableContact::initPhysics() psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = .1; + psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD; getDeformableDynamicsWorld()->addSoftBody(psb); getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); diff --git a/examples/DeformableDemo/DeformableDemo.cpp b/examples/DeformableDemo/DeformableDemo.cpp index 2411670cf..a3cdbf847 100644 --- a/examples/DeformableDemo/DeformableDemo.cpp +++ b/examples/DeformableDemo/DeformableDemo.cpp @@ -235,6 +235,7 @@ void DeformableDemo::initPhysics() psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = 1; + psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD; getDeformableDynamicsWorld()->addSoftBody(psb); getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); diff --git a/examples/Pinch/Pinch.cpp b/examples/Pinch/Pinch.cpp index 1e4afb748..c6e26ddb1 100644 --- a/examples/Pinch/Pinch.cpp +++ b/examples/Pinch/Pinch.cpp @@ -342,6 +342,7 @@ void Pinch::initPhysics() psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = 2; + psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD; getDeformableDynamicsWorld()->addSoftBody(psb); getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); diff --git a/examples/VolumetricDeformable/VolumetricDeformable.cpp b/examples/VolumetricDeformable/VolumetricDeformable.cpp index 15fb712f6..b30e4ac4d 100644 --- a/examples/VolumetricDeformable/VolumetricDeformable.cpp +++ b/examples/VolumetricDeformable/VolumetricDeformable.cpp @@ -241,6 +241,7 @@ void VolumetricDeformable::initPhysics() psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects psb->m_cfg.kCHR = 1; // collision hardness with rigid body psb->m_cfg.kDF = 0.5; + psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD; getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce()); getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity)); } diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index 82af57f6d..30c2d995e 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -26,7 +26,6 @@ class btDeformableRigidDynamicsWorld; class btDeformableBackwardEulerObjective { public: -// using TVStack = btAlignedObjectArray; typedef btAlignedObjectArray TVStack; btScalar m_dt; btDeformableRigidDynamicsWorld* m_world; diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index 242b0a882..fc792bd7f 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -75,7 +75,6 @@ void btDeformableBodySolver::setWorld(btDeformableRigidDynamicsWorld* world) void btDeformableBodySolver::updateVelocity() { - // serial implementation int counter = 0; for (int i = 0; i < m_softBodySet.size(); ++i) { @@ -90,7 +89,6 @@ void btDeformableBodySolver::updateVelocity() void btDeformableBodySolver::backupVelocity() { - // serial implementation int counter = 0; for (int i = 0; i < m_softBodySet.size(); ++i) { @@ -104,7 +102,6 @@ void btDeformableBodySolver::backupVelocity() void btDeformableBodySolver::revertVelocity() { - // serial implementation int counter = 0; for (int i = 0; i < m_softBodySet.size(); ++i) { diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 8a62d31bb..86a48bf62 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -1758,115 +1758,115 @@ void btSoftBody::setSolver(eSolverPresets::_ preset) } } -// void btSoftBody::predictMotion(btScalar dt) { - int i, ni; - - /* Update */ - if (m_bUpdateRtCst) - { - m_bUpdateRtCst = false; - updateConstants(); - m_fdbvt.clear(); - if (m_cfg.collisions & fCollision::VF_SS) - { - initializeFaceTree(); - } - } - - /* Prepare */ - m_sst.sdt = dt * m_cfg.timescale; - m_sst.isdt = 1 / m_sst.sdt; - m_sst.velmrg = m_sst.sdt * 3; - m_sst.radmrg = getCollisionShape()->getMargin(); - m_sst.updmrg = m_sst.radmrg * (btScalar)0.25; - /* Forces */ -// addVelocity(m_worldInfo->m_gravity * m_sst.sdt); - applyForces(); - /* Integrate */ - for (i = 0, ni = m_nodes.size(); i < ni; ++i) - { - Node& n = m_nodes[i]; - n.m_q = n.m_x; - btVector3 deltaV = n.m_f * n.m_im * m_sst.sdt; - { - btScalar maxDisplacement = m_worldInfo->m_maxDisplacement; - btScalar clampDeltaV = maxDisplacement / m_sst.sdt; - for (int c = 0; c < 3; c++) - { - if (deltaV[c] > clampDeltaV) - { - deltaV[c] = clampDeltaV; - } - if (deltaV[c] < -clampDeltaV) - { - deltaV[c] = -clampDeltaV; - } - } - } + int i, ni; + + /* Update */ + if (m_bUpdateRtCst) + { + m_bUpdateRtCst = false; + updateConstants(); + m_fdbvt.clear(); + if (m_cfg.collisions & fCollision::VF_SS) + { + initializeFaceTree(); + } + } + + /* Prepare */ + m_sst.sdt = dt * m_cfg.timescale; + m_sst.isdt = 1 / m_sst.sdt; + m_sst.velmrg = m_sst.sdt * 3; + m_sst.radmrg = getCollisionShape()->getMargin(); + m_sst.updmrg = m_sst.radmrg * (btScalar)0.25; + /* Forces */ + addVelocity(m_worldInfo->m_gravity * m_sst.sdt); + applyForces(); + /* Integrate */ + for (i = 0, ni = m_nodes.size(); i < ni; ++i) + { + Node& n = m_nodes[i]; + n.m_q = n.m_x; + btVector3 deltaV = n.m_f * n.m_im * m_sst.sdt; + { + btScalar maxDisplacement = m_worldInfo->m_maxDisplacement; + btScalar clampDeltaV = maxDisplacement / m_sst.sdt; + for (int c = 0; c < 3; c++) + { + if (deltaV[c] > clampDeltaV) + { + deltaV[c] = clampDeltaV; + } + if (deltaV[c] < -clampDeltaV) + { + deltaV[c] = -clampDeltaV; + } + } + } n.m_v += deltaV; n.m_x += n.m_v * m_sst.sdt; - n.m_f = btVector3(0, 0, 0); - } - /* Clusters */ - updateClusters(); - /* Bounds */ - updateBounds(); - /* Nodes */ - ATTRIBUTE_ALIGNED16(btDbvtVolume) - vol; - for (i = 0, ni = m_nodes.size(); i < ni; ++i) - { - Node& n = m_nodes[i]; - vol = btDbvtVolume::FromCR(n.m_x, m_sst.radmrg); - m_ndbvt.update(n.m_leaf, - vol, - n.m_v * m_sst.velmrg, - m_sst.updmrg); - } - /* Faces */ - if (!m_fdbvt.empty()) - { - for (int i = 0; i < m_faces.size(); ++i) - { - Face& f = m_faces[i]; - const btVector3 v = (f.m_n[0]->m_v + - f.m_n[1]->m_v + - f.m_n[2]->m_v) / - 3; - vol = VolumeOf(f, m_sst.radmrg); - m_fdbvt.update(f.m_leaf, - vol, - v * m_sst.velmrg, - m_sst.updmrg); - } - } - /* Pose */ - updatePose(); - /* Match */ - if (m_pose.m_bframe && (m_cfg.kMT > 0)) - { - const btMatrix3x3 posetrs = m_pose.m_rot; - for (int i = 0, ni = m_nodes.size(); i < ni; ++i) - { - Node& n = m_nodes[i]; - if (n.m_im > 0) - { - const btVector3 x = posetrs * m_pose.m_pos[i] + m_pose.m_com; - n.m_x = Lerp(n.m_x, x, m_cfg.kMT); - } - } - } - /* Clear contacts */ - m_rcontacts.resize(0); - m_scontacts.resize(0); - /* Optimize dbvt's */ - m_ndbvt.optimizeIncremental(1); - m_fdbvt.optimizeIncremental(1); - m_cdbvt.optimizeIncremental(1); + n.m_f = btVector3(0, 0, 0); + } + /* Clusters */ + updateClusters(); + /* Bounds */ + updateBounds(); + /* Nodes */ + ATTRIBUTE_ALIGNED16(btDbvtVolume) + vol; + for (i = 0, ni = m_nodes.size(); i < ni; ++i) + { + Node& n = m_nodes[i]; + vol = btDbvtVolume::FromCR(n.m_x, m_sst.radmrg); + m_ndbvt.update(n.m_leaf, + vol, + n.m_v * m_sst.velmrg, + m_sst.updmrg); + } + /* Faces */ + if (!m_fdbvt.empty()) + { + for (int i = 0; i < m_faces.size(); ++i) + { + Face& f = m_faces[i]; + const btVector3 v = (f.m_n[0]->m_v + + f.m_n[1]->m_v + + f.m_n[2]->m_v) / + 3; + vol = VolumeOf(f, m_sst.radmrg); + m_fdbvt.update(f.m_leaf, + vol, + v * m_sst.velmrg, + m_sst.updmrg); + } + } + /* Pose */ + updatePose(); + /* Match */ + if (m_pose.m_bframe && (m_cfg.kMT > 0)) + { + const btMatrix3x3 posetrs = m_pose.m_rot; + for (int i = 0, ni = m_nodes.size(); i < ni; ++i) + { + Node& n = m_nodes[i]; + if (n.m_im > 0) + { + const btVector3 x = posetrs * m_pose.m_pos[i] + m_pose.m_com; + n.m_x = Lerp(n.m_x, x, m_cfg.kMT); + } + } + } + /* Clear contacts */ + m_rcontacts.resize(0); + m_scontacts.resize(0); + /* Optimize dbvt's */ + m_ndbvt.optimizeIncremental(1); + m_fdbvt.optimizeIncremental(1); + m_cdbvt.optimizeIncremental(1); } + // void btSoftBody::solveConstraints() { @@ -2262,8 +2262,35 @@ btVector3 btSoftBody::evaluateCom() const return (com); } -// bool btSoftBody::checkContact(const btCollisionObjectWrapper* colObjWrap, + const btVector3& x, + btScalar margin, + btSoftBody::sCti& cti) const +{ + btVector3 nrm; + const btCollisionShape* shp = colObjWrap->getCollisionShape(); + // const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); + //const btTransform &wtr = tmpRigid ? tmpRigid->getWorldTransform() : colObjWrap->getWorldTransform(); + const btTransform& wtr = colObjWrap->getWorldTransform(); + //todo: check which transform is needed here + + btScalar dst = + m_worldInfo->m_sparsesdf.Evaluate( + wtr.invXform(x), + shp, + nrm, + margin); + if (dst < 0) + { + cti.m_colObj = colObjWrap->getCollisionObject(); + cti.m_normal = wtr.getBasis() * nrm; + cti.m_offset = -btDot(cti.m_normal, x - cti.m_normal * dst); + return (true); + } + return (false); +} +// +bool btSoftBody::checkDeformableContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict) const @@ -3262,6 +3289,33 @@ void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap collider.ProcessColObj(this, pcoWrap); } break; + case fCollision::SDF_RD: + { + btSoftColliders::CollideSDF_RD docollide; + btRigidBody* prb1 = (btRigidBody*)btRigidBody::upcast(pcoWrap->getCollisionObject()); + btTransform wtr = pcoWrap->getWorldTransform(); + + const btTransform ctr = pcoWrap->getWorldTransform(); + const btScalar timemargin = (wtr.getOrigin() - ctr.getOrigin()).length(); + const btScalar basemargin = getCollisionShape()->getMargin(); + btVector3 mins; + btVector3 maxs; + ATTRIBUTE_ALIGNED16(btDbvtVolume) + volume; + pcoWrap->getCollisionShape()->getAabb(pcoWrap->getWorldTransform(), + mins, + maxs); + volume = btDbvtVolume::FromMM(mins, maxs); + volume.Expand(btVector3(basemargin, basemargin, basemargin)); + docollide.psb = this; + docollide.m_colObj1Wrap = pcoWrap; + docollide.m_rigidBody = prb1; + + docollide.dynmargin = basemargin + timemargin; + docollide.stamargin = basemargin; + m_ndbvt.collideTV(m_ndbvt.m_root, volume, docollide); + } + break; } } diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index 87633a83c..f2934c94a 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -160,6 +160,7 @@ public: RVSmask = 0x000f, ///Rigid versus soft mask SDF_RS = 0x0001, ///SDF based rigid vs soft CL_RS = 0x0002, ///Cluster vs convex rigid vs soft + SDF_RD = 0x0003, ///DF based rigid vs deformable SVSmask = 0x0030, ///Rigid versus soft mask VF_SS = 0x0010, ///Vertex vs face soft vs soft handling @@ -1006,7 +1007,8 @@ public: btScalar& mint, eFeature::_& feature, int& index, bool bcountonly) const; void initializeFaceTree(); btVector3 evaluateCom() const; - bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const; + bool checkDeformableContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const; + bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti) const; void updateNormals(); void updateBounds(); void updatePose(); diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index eb487a56f..80545ebad 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -928,10 +928,62 @@ struct btSoftColliders psa->m_cdbvt.collideTT(psa->m_cdbvt.m_root, psb->m_cdbvt.m_root, *this); } }; + // + // CollideSDF_RS + // + struct CollideSDF_RS : btDbvt::ICollide + { + void Process(const btDbvtNode* leaf) + { + btSoftBody::Node* node = (btSoftBody::Node*)leaf->data; + DoNode(*node); + } + void DoNode(btSoftBody::Node& n) const + { + const btScalar m = n.m_im > 0 ? dynmargin : stamargin; + btSoftBody::RContact c; + + if ((!n.m_battach) && + psb->checkContact(m_colObj1Wrap, n.m_x, m, c.m_cti)) + { + const btScalar ima = n.m_im; + const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f; + const btScalar ms = ima + imb; + if (ms > 0) + { + const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); + static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0); + const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; + const btVector3 ra = n.m_x - wtr.getOrigin(); + const btVector3 va = m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra) * psb->m_sst.sdt : btVector3(0, 0, 0); + const btVector3 vb = n.m_x - n.m_q; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, c.m_cti.m_normal); + const btVector3 fv = vr - c.m_cti.m_normal * dn; + const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); + c.m_node = &n; + c.m_c0 = ImpulseMatrix(psb->m_sst.sdt, ima, imb, iwi, ra); + c.m_c1 = ra; + c.m_c2 = ima * psb->m_sst.sdt; + c.m_c3 = fv.length2() < (dn * fc * dn * fc) ? 0 : 1 - fc; + c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR; + psb->m_rcontacts.push_back(c); + if (m_rigidBody) + m_rigidBody->activate(); + } + } + } + btSoftBody* psb; + const btCollisionObjectWrapper* m_colObj1Wrap; + btRigidBody* m_rigidBody; + btScalar dynmargin; + btScalar stamargin; + }; + // - // CollideSDF_RS + // CollideSDF_RD // - struct CollideSDF_RS : btDbvt::ICollide + struct CollideSDF_RD : btDbvt::ICollide { void Process(const btDbvtNode* leaf) { @@ -946,7 +998,7 @@ struct btSoftColliders if (!n.m_battach) { // check for collision at x_{n+1}^* - if (psb->checkContact(m_colObj1Wrap, n.m_x, m, c.m_cti, /*predicted = */ true)) + if (psb->checkDeformableContact(m_colObj1Wrap, n.m_x, m, c.m_cti, /*predicted = */ true)) { const btScalar ima = n.m_im; const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f; @@ -954,7 +1006,7 @@ struct btSoftColliders if (ms > 0) { // resolve contact at x_n - psb->checkContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predicted = */ false); + psb->checkDeformableContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predicted = */ false); btSoftBody::sCti& cti = c.m_cti; c.m_node = &n; const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); From 02c5b99b2f894252205b39bc46405c7a3b9a2084 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Tue, 6 Aug 2019 11:42:48 -0700 Subject: [PATCH 40/47] add algorithm overview --- .../btDeformableRigidDynamicsWorld.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 5afc88323..2fce9e7a5 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -11,6 +11,22 @@ 3. This notice may not be removed or altered from any source distribution. */ +/* ====== Overview of the Deformable Algorithm ====== */ + +/* +A single step of the deformable body simulation contains the following main components: +1. Update velocity to a temporary state v_{n+1}^* = v_n + explicit_force * dt / mass, where explicit forces include gravity and elastic forces. +2. Detect collisions between rigid and deformable bodies at position x_{n+1}^* = x_n + dt * v_{n+1}^*. +3. Then velocities of deformable bodies v_{n+1} are solved in + M(v_{n+1} - v_{n+1}^*) = damping_force * dt / mass, + by a conjugate gradient solver, where the damping force is implicit and depends on v_{n+1}. +4. Contact constraints are solved as projections as in the paper by Baraff and Witkin https://www.cs.cmu.edu/~baraff/papers/sig98.pdf. Dynamic frictions are treated as a force and added to the rhs of the CG solve, whereas static frictions are treated as constraints similar to contact. +5. Position is updated via x_{n+1} = x_n + dt * v_{n+1}. +6. Apply position correction to prevent numerical drift. + +The algorithm also closely resembles the one in http://physbam.stanford.edu/~fedkiw/papers/stanford2008-03.pdf + */ + #include #include "btDeformableRigidDynamicsWorld.h" #include "btDeformableBodySolver.h" From 9a7e30d09ffe20a533ad76b1729e66232aa5de89 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 8 Aug 2019 15:00:55 -0700 Subject: [PATCH 41/47] move deformable examples to a single folder and rename them; change license to google 2016 --- examples/CMakeLists.txt | 2 +- .../DeformableContact/DeformableContact.h | 20 -------- examples/DeformableDemo/DeformableDemo.h | 20 -------- .../DeformableMultibody.cpp} | 48 +++++++++---------- examples/DeformableDemo/DeformableMultibody.h | 19 ++++++++ ...DeformableDemo.cpp => DeformableRigid.cpp} | 42 ++++++++-------- examples/DeformableDemo/DeformableRigid.h | 19 ++++++++ examples/{Pinch => DeformableDemo}/Pinch.cpp | 24 +++++----- examples/DeformableDemo/Pinch.h | 19 ++++++++ .../VolumetricDeformable.cpp | 24 +++++----- .../DeformableDemo/VolumetricDeformable.h | 19 ++++++++ examples/ExampleBrowser/CMakeLists.txt | 16 +++---- examples/ExampleBrowser/ExampleEntries.cpp | 13 +++-- examples/ExampleBrowser/premake4.lua | 3 -- examples/Pinch/Pinch.h | 20 -------- .../VolumetricDeformable.h | 20 -------- .../btDeformableRigidDynamicsWorld.h | 4 +- 17 files changed, 157 insertions(+), 175 deletions(-) delete mode 100644 examples/DeformableContact/DeformableContact.h delete mode 100644 examples/DeformableDemo/DeformableDemo.h rename examples/{DeformableContact/DeformableContact.cpp => DeformableDemo/DeformableMultibody.cpp} (88%) create mode 100644 examples/DeformableDemo/DeformableMultibody.h rename examples/DeformableDemo/{DeformableDemo.cpp => DeformableRigid.cpp} (88%) create mode 100644 examples/DeformableDemo/DeformableRigid.h rename examples/{Pinch => DeformableDemo}/Pinch.cpp (93%) create mode 100644 examples/DeformableDemo/Pinch.h rename examples/{VolumetricDeformable => DeformableDemo}/VolumetricDeformable.cpp (92%) create mode 100644 examples/DeformableDemo/VolumetricDeformable.h delete mode 100644 examples/Pinch/Pinch.h delete mode 100644 examples/VolumetricDeformable/VolumetricDeformable.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1918a9003..ba9efac19 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,4 +1,4 @@ -SUBDIRS( HelloWorld BasicDemo ) +SUBDIRS( HelloWorld BasicDemo) IF(BUILD_BULLET3) SUBDIRS( ExampleBrowser RobotSimulator SharedMemory ThirdPartyLibs/Gwen ThirdPartyLibs/BussIK ThirdPartyLibs/clsocket OpenGLWindow TwoJoint ) ENDIF() diff --git a/examples/DeformableContact/DeformableContact.h b/examples/DeformableContact/DeformableContact.h deleted file mode 100644 index 591c6bab1..000000000 --- a/examples/DeformableContact/DeformableContact.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -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 _DEFORMABLE_CONTACT_H -#define _DEFORMABLE_CONTACT_H - -class CommonExampleInterface* DeformableContactCreateFunc(struct CommonExampleOptions& options); - -#endif //_DEFORMABLE_CONTACT_H diff --git a/examples/DeformableDemo/DeformableDemo.h b/examples/DeformableDemo/DeformableDemo.h deleted file mode 100644 index c688cea9d..000000000 --- a/examples/DeformableDemo/DeformableDemo.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -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 _DEFORMABLE_DEMO_H -#define _DEFORMABLE_DEMO_H - -class CommonExampleInterface* DeformableCreateFunc(struct CommonExampleOptions& options); - -#endif //_DEFORMABLE_DEMO_H diff --git a/examples/DeformableContact/DeformableContact.cpp b/examples/DeformableDemo/DeformableMultibody.cpp similarity index 88% rename from examples/DeformableContact/DeformableContact.cpp rename to examples/DeformableDemo/DeformableMultibody.cpp index 102ad40a9..78adf7bf1 100644 --- a/examples/DeformableContact/DeformableContact.cpp +++ b/examples/DeformableDemo/DeformableMultibody.cpp @@ -1,17 +1,15 @@ /* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -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. -*/ + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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. + */ ///create 125 (5x5x5) dynamic object #define ARRAY_SIZE_X 5 @@ -27,7 +25,7 @@ subject to the following restrictions: #define START_POS_Y -5 #define START_POS_Z -3 -#include "DeformableContact.h" +#include "DeformableMultibody.h" ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. #include "btBulletDynamicsCommon.h" #include "BulletSoftBody/btDeformableRigidDynamicsWorld.h" @@ -46,20 +44,20 @@ subject to the following restrictions: #include "../CommonInterfaces/CommonMultiBodyBase.h" #include "../Utils/b3ResourcePath.h" -///The DeformableContact demo deformable bodies self-collision +///The DeformableMultibody demo deformable bodies self-collision static bool g_floatingBase = true; static float friction = 1.; -class DeformableContact : public CommonMultiBodyBase +class DeformableMultibody : public CommonMultiBodyBase { btMultiBody* m_multiBody; btAlignedObjectArray m_jointFeedbacks; public: - DeformableContact(struct GUIHelperInterface* helper) + DeformableMultibody(struct GUIHelperInterface* helper) : CommonMultiBodyBase(helper) { } - virtual ~DeformableContact() + virtual ~DeformableMultibody() { } @@ -109,7 +107,7 @@ public: } }; -void DeformableContact::initPhysics() +void DeformableMultibody::initPhysics() { m_guiHelper->setUpAxis(1); @@ -237,7 +235,7 @@ void DeformableContact::initPhysics() m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } -void DeformableContact::exitPhysics() +void DeformableMultibody::exitPhysics() { //cleanup in the reverse order of creation/initialization @@ -274,14 +272,14 @@ void DeformableContact::exitPhysics() delete m_collisionConfiguration; } -void DeformableContact::stepSimulation(float deltaTime) +void DeformableMultibody::stepSimulation(float deltaTime) { // getDeformableDynamicsWorld()->getMultiBodyDynamicsWorld()->stepSimulation(deltaTime); m_dynamicsWorld->stepSimulation(deltaTime, 5, 1./250.); } -btMultiBody* DeformableContact::createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating) +btMultiBody* DeformableMultibody::createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating) { //init the base btVector3 baseInertiaDiag(0.f, 0.f, 0.f); @@ -341,7 +339,7 @@ btMultiBody* DeformableContact::createFeatherstoneMultiBody_testMultiDof(btMulti return pMultiBody; } -void DeformableContact::addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents) +void DeformableMultibody::addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents) { btAlignedObjectArray world_to_local; world_to_local.resize(pMultiBody->getNumLinks() + 1); @@ -403,9 +401,9 @@ void DeformableContact::addColliders_testMultiDof(btMultiBody* pMultiBody, btMul pMultiBody->getLink(i).m_collider = col; } } -class CommonExampleInterface* DeformableContactCreateFunc(struct CommonExampleOptions& options) +class CommonExampleInterface* DeformableMultibodyCreateFunc(struct CommonExampleOptions& options) { - return new DeformableContact(options.m_guiHelper); + return new DeformableMultibody(options.m_guiHelper); } diff --git a/examples/DeformableDemo/DeformableMultibody.h b/examples/DeformableDemo/DeformableMultibody.h new file mode 100644 index 000000000..8bc9020f3 --- /dev/null +++ b/examples/DeformableDemo/DeformableMultibody.h @@ -0,0 +1,19 @@ +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 _DEFORMABLE_MULTIBODY_H +#define _DEFORMABLE_MULTIBODY_H + +class CommonExampleInterface* DeformableMultibodyCreateFunc(struct CommonExampleOptions& options); + +#endif //_DEFORMABLE_MULTIBODY_H diff --git a/examples/DeformableDemo/DeformableDemo.cpp b/examples/DeformableDemo/DeformableRigid.cpp similarity index 88% rename from examples/DeformableDemo/DeformableDemo.cpp rename to examples/DeformableDemo/DeformableRigid.cpp index a3cdbf847..c26bcc7d5 100644 --- a/examples/DeformableDemo/DeformableDemo.cpp +++ b/examples/DeformableDemo/DeformableRigid.cpp @@ -1,17 +1,15 @@ /* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -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. -*/ + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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. + */ ///create 125 (5x5x5) dynamic object #define ARRAY_SIZE_X 5 @@ -27,7 +25,7 @@ subject to the following restrictions: #define START_POS_Y -5 #define START_POS_Z -3 -#include "DeformableDemo.h" +#include "DeformableRigid.h" ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. #include "btBulletDynamicsCommon.h" #include "BulletSoftBody/btDeformableRigidDynamicsWorld.h" @@ -41,17 +39,17 @@ subject to the following restrictions: #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "../Utils/b3ResourcePath.h" -///The DeformableDemo shows the use of rolling friction. +///The DeformableRigid shows the use of rolling friction. ///Spheres will come to a rest on a sloped plane using a constraint. Damping cannot achieve the same. ///Generally it is best to leave the rolling friction coefficient zero (or close to zero). -class DeformableDemo : public CommonRigidBodyBase +class DeformableRigid : public CommonRigidBodyBase { public: - DeformableDemo(struct GUIHelperInterface* helper) + DeformableRigid(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper) { } - virtual ~DeformableDemo() + virtual ~DeformableRigid() { } void initPhysics(); @@ -148,7 +146,7 @@ public: } }; -void DeformableDemo::initPhysics() +void DeformableRigid::initPhysics() { m_guiHelper->setUpAxis(1); @@ -246,7 +244,7 @@ void DeformableDemo::initPhysics() m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } -void DeformableDemo::exitPhysics() +void DeformableRigid::exitPhysics() { //cleanup in the reverse order of creation/initialization @@ -285,9 +283,9 @@ void DeformableDemo::exitPhysics() -class CommonExampleInterface* DeformableCreateFunc(struct CommonExampleOptions& options) +class CommonExampleInterface* DeformableRigidCreateFunc(struct CommonExampleOptions& options) { - return new DeformableDemo(options.m_guiHelper); + return new DeformableRigid(options.m_guiHelper); } diff --git a/examples/DeformableDemo/DeformableRigid.h b/examples/DeformableDemo/DeformableRigid.h new file mode 100644 index 000000000..1f2bb0911 --- /dev/null +++ b/examples/DeformableDemo/DeformableRigid.h @@ -0,0 +1,19 @@ +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 _DEFORMABLE_RIGID_H +#define _DEFORMABLE_RIGID_H + +class CommonExampleInterface* DeformableRigidCreateFunc(struct CommonExampleOptions& options); + +#endif //_DEFORMABLE_RIGID_H diff --git a/examples/Pinch/Pinch.cpp b/examples/DeformableDemo/Pinch.cpp similarity index 93% rename from examples/Pinch/Pinch.cpp rename to examples/DeformableDemo/Pinch.cpp index c6e26ddb1..aaae1df3f 100644 --- a/examples/Pinch/Pinch.cpp +++ b/examples/DeformableDemo/Pinch.cpp @@ -1,17 +1,15 @@ /* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -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. -*/ + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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. + */ ///create 125 (5x5x5) dynamic object #define ARRAY_SIZE_X 5 diff --git a/examples/DeformableDemo/Pinch.h b/examples/DeformableDemo/Pinch.h new file mode 100644 index 000000000..3d01b262f --- /dev/null +++ b/examples/DeformableDemo/Pinch.h @@ -0,0 +1,19 @@ +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 _PINCH_H +#define _PINCH_H + +class CommonExampleInterface* PinchCreateFunc(struct CommonExampleOptions& options); + +#endif //_PINCH_H diff --git a/examples/VolumetricDeformable/VolumetricDeformable.cpp b/examples/DeformableDemo/VolumetricDeformable.cpp similarity index 92% rename from examples/VolumetricDeformable/VolumetricDeformable.cpp rename to examples/DeformableDemo/VolumetricDeformable.cpp index b30e4ac4d..6f2b88f8d 100644 --- a/examples/VolumetricDeformable/VolumetricDeformable.cpp +++ b/examples/DeformableDemo/VolumetricDeformable.cpp @@ -1,17 +1,15 @@ /* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -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. -*/ + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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. + */ ///create 125 (5x5x5) dynamic object #define ARRAY_SIZE_X 5 diff --git a/examples/DeformableDemo/VolumetricDeformable.h b/examples/DeformableDemo/VolumetricDeformable.h new file mode 100644 index 000000000..04e30d9c6 --- /dev/null +++ b/examples/DeformableDemo/VolumetricDeformable.h @@ -0,0 +1,19 @@ +/* + Bullet Continuous Collision Detection and Physics Library + Copyright (c) 2016 Google Inc. http://bulletphysics.org + 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 _VOLUMETRIC_DEFORMABLE_H +#define _VOLUMETRIC_DEFORMABLE_H + +class CommonExampleInterface* VolumetricDeformableCreateFunc(struct CommonExampleOptions& options); + +#endif //_VOLUMETRIC_DEFORMABLE__H diff --git a/examples/ExampleBrowser/CMakeLists.txt b/examples/ExampleBrowser/CMakeLists.txt index cfae5fcc5..19334b2db 100644 --- a/examples/ExampleBrowser/CMakeLists.txt +++ b/examples/ExampleBrowser/CMakeLists.txt @@ -359,14 +359,14 @@ SET(BulletExampleBrowser_SRCS ../MultiBody/MultiBodyConstraintFeedback.cpp ../SoftDemo/SoftDemo.cpp ../SoftDemo/SoftDemo.h - ../Pinch/Pinch.cpp - ../Pinch/Pinch.h - ../DeformableContact/DeformableContact.cpp - ../DeformableContact/DeformableContact.h - ../DeformableDemo/DeformableDemo.cpp - ../DeformableDemo/DeformableDemo.h - ../VolumetricDeformable/VolumetricDeformable.cpp - ../VolumetricDeformable/VolumetricDeformable.h + ../DeformableDemo/Pinch.cpp + ../DeformableDemo/Pinch.h + ../DeformableDemo/DeformableMultibody.cpp + ../DeformableDemo/DeformableMultibody.h + ../DeformableDemo/DeformableRigid.cpp + ../DeformableDemo/DeformableRigid.h + ../DeformableDemo/VolumetricDeformable.cpp + ../DeformableDemo/VolumetricDeformable.h ../MultiBody/MultiDofDemo.cpp ../MultiBody/MultiDofDemo.h ../RigidBody/RigidBodySoftContact.cpp diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp index f186f642a..481d36c5d 100644 --- a/examples/ExampleBrowser/ExampleEntries.cpp +++ b/examples/ExampleBrowser/ExampleEntries.cpp @@ -47,11 +47,10 @@ #include "../FractureDemo/FractureDemo.h" #include "../DynamicControlDemo/MotorDemo.h" #include "../RollingFrictionDemo/RollingFrictionDemo.h" -#include "../DeformableDemo/DeformableDemo.h" -#include "../Pinch/Pinch.h" -#include "../DeformableContact/DeformableContact.h" -#include "../MultiBodyBaseline/MultiBodyBaseline.h" -#include "../VolumetricDeformable/VolumetricDeformable.h" +#include "../DeformableDemo/DeformableRigid.h" +#include "../DeformableDemo/Pinch.h" +#include "../DeformableDemo/DeformableMultibody.h" +#include "../DeformableDemo/VolumetricDeformable.h" #include "../SharedMemory/PhysicsServerExampleBullet2.h" #include "../SharedMemory/PhysicsServerExample.h" #include "../SharedMemory/PhysicsClientExample.h" @@ -196,10 +195,10 @@ static ExampleEntry gDefaultExamples[] = //ExampleEntry(1, "Spheres & Plane C-API (Bullet3)", "Collision C-API using Bullet 3.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_RTB3), ExampleEntry(0, "Deformabe Body"), - ExampleEntry(1, "Deformable-RigidBody Contact", "Deformable test", DeformableCreateFunc), + ExampleEntry(1, "Deformable-RigidBody Contact", "Deformable test", DeformableRigidCreateFunc), ExampleEntry(1, "Grasp Deformable Cube", "Grasping test", PinchCreateFunc), ExampleEntry(1, "Volumetric Deformable Objects", "Volumetric Deformable test", VolumetricDeformableCreateFunc), - ExampleEntry(1, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableContactCreateFunc), + ExampleEntry(1, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableMultibodyCreateFunc), // ExampleEntry(1, "MultiBody Baseline", "MultiBody Baseline", MultiBodyBaselineCreateFunc), #ifdef INCLUDE_CLOTH_DEMOS diff --git a/examples/ExampleBrowser/premake4.lua b/examples/ExampleBrowser/premake4.lua index ff81b34b7..985a0457b 100644 --- a/examples/ExampleBrowser/premake4.lua +++ b/examples/ExampleBrowser/premake4.lua @@ -189,9 +189,6 @@ project "App_BulletExampleBrowser" "../VoronoiFracture/*", "../SoftDemo/*", "../DeformableDemo/*", - "../DeformableContact/*", - "../VolumetricDeformable/*", - "../Pinch/*", "../RollingFrictionDemo/*", "../rbdl/*", "../FractureDemo/*", diff --git a/examples/Pinch/Pinch.h b/examples/Pinch/Pinch.h deleted file mode 100644 index 6c7e2fb3c..000000000 --- a/examples/Pinch/Pinch.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -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 _PINCH_H -#define _PINCH_H - -class CommonExampleInterface* PinchCreateFunc(struct CommonExampleOptions& options); - -#endif //_PINCH_H diff --git a/examples/VolumetricDeformable/VolumetricDeformable.h b/examples/VolumetricDeformable/VolumetricDeformable.h deleted file mode 100644 index af1cc38b6..000000000 --- a/examples/VolumetricDeformable/VolumetricDeformable.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -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 _VOLUMETRIC_DEFORMABLE_H -#define _VOLUMETRIC_DEFORMABLE_H - -class CommonExampleInterface* VolumetricDeformableCreateFunc(struct CommonExampleOptions& options); - -#endif //_VOLUMETRIC_DEFORMABLE__H diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index cc4fdae05..6489d6ebc 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -1,13 +1,11 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - + Copyright (c) 2016 Google Inc. http://bulletphysics.org 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. From 96e8dcef0f57c730ea1f268d6cd575dac22f5d7e Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 8 Aug 2019 16:45:19 -0700 Subject: [PATCH 42/47] fix bug caused by not reseting to zero --- src/BulletSoftBody/btDeformableBodySolver.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index fc792bd7f..4dd45edc8 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -55,9 +55,19 @@ void btDeformableBodySolver::reinitialize(const btAlignedObjectArrayreinitialize(nodeUpdated); } From 436b6c6963d4639599908d4643d4b5f341f86f6c Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 8 Aug 2019 17:14:13 -0700 Subject: [PATCH 43/47] separate multibody position prediction into standalone function --- .../Featherstone/btMultiBody.cpp | 204 +++++++++++++----- src/BulletDynamics/Featherstone/btMultiBody.h | 2 +- .../Featherstone/btMultiBodyDynamicsWorld.cpp | 67 ++++-- .../Featherstone/btMultiBodyDynamicsWorld.h | 3 +- .../Featherstone/btMultiBodyLink.h | 64 +++++- 5 files changed, 259 insertions(+), 81 deletions(-) diff --git a/src/BulletDynamics/Featherstone/btMultiBody.cpp b/src/BulletDynamics/Featherstone/btMultiBody.cpp index 1857bd55f..4d634b699 100644 --- a/src/BulletDynamics/Featherstone/btMultiBody.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBody.cpp @@ -1595,35 +1595,167 @@ void btMultiBody::calcAccelerationDeltasMultiDof(const btScalar *force, btScalar } void btMultiBody::predictPositionsMultiDof(btScalar dt) { - stepPositionsMultiDof(dt, 0, 0, true); + int num_links = getNumLinks(); + // step position by adding dt * velocity + //btVector3 v = getBaseVel(); + //m_basePos += dt * v; + // + btScalar *pBasePos; + btScalar *pBaseVel = &m_realBuf[3]; //note: the !pqd case assumes m_realBuf holds with base velocity at 3,4,5 (should be wrapped for safety) + + // reset to current position + for (int i = 0; i < 3; ++i) + { + m_basePos_interpolate[i] = m_basePos[i]; + } + pBasePos = m_basePos_interpolate; + + pBasePos[0] += dt * pBaseVel[0]; + pBasePos[1] += dt * pBaseVel[1]; + pBasePos[2] += dt * pBaseVel[2]; + + /////////////////////////////// + //local functor for quaternion integration (to avoid error prone redundancy) + struct + { + //"exponential map" based on btTransformUtil::integrateTransform(..) + void operator()(const btVector3 &omega, btQuaternion &quat, bool baseBody, btScalar dt) + { + //baseBody => quat is alias and omega is global coor + //!baseBody => quat is alibi and omega is local coor + + btVector3 axis; + btVector3 angvel; + + if (!baseBody) + angvel = quatRotate(quat, omega); //if quat is not m_baseQuat, it is alibi => ok + else + angvel = omega; + + btScalar fAngle = angvel.length(); + //limit the angular motion + if (fAngle * dt > ANGULAR_MOTION_THRESHOLD) + { + fAngle = btScalar(0.5) * SIMD_HALF_PI / dt; + } + + if (fAngle < btScalar(0.001)) + { + // use Taylor's expansions of sync function + axis = angvel * (btScalar(0.5) * dt - (dt * dt * dt) * (btScalar(0.020833333333)) * fAngle * fAngle); + } + else + { + // sync(fAngle) = sin(c*fAngle)/t + axis = angvel * (btSin(btScalar(0.5) * fAngle * dt) / fAngle); + } + + if (!baseBody) + quat = btQuaternion(axis.x(), axis.y(), axis.z(), btCos(fAngle * dt * btScalar(0.5))) * quat; + else + quat = quat * btQuaternion(-axis.x(), -axis.y(), -axis.z(), btCos(fAngle * dt * btScalar(0.5))); + //equivalent to: quat = (btQuaternion(axis.x(),axis.y(),axis.z(),btCos( fAngle*dt*btScalar(0.5) )) * quat.inverse()).inverse(); + + quat.normalize(); + } + } pQuatUpdateFun; + /////////////////////////////// + + //pQuatUpdateFun(getBaseOmega(), m_baseQuat, true, dt); + // + btScalar *pBaseQuat; + + // reset to current orientation + for (int i = 0; i < 4; ++i) + { + m_baseQuat_interpolate[i] = m_baseQuat[i]; + } + pBaseQuat = m_baseQuat_interpolate; + + btScalar *pBaseOmega = &m_realBuf[0]; //note: the !pqd case assumes m_realBuf starts with base omega (should be wrapped for safety) + // + btQuaternion baseQuat; + baseQuat.setValue(pBaseQuat[0], pBaseQuat[1], pBaseQuat[2], pBaseQuat[3]); + btVector3 baseOmega; + baseOmega.setValue(pBaseOmega[0], pBaseOmega[1], pBaseOmega[2]); + pQuatUpdateFun(baseOmega, baseQuat, true, dt); + pBaseQuat[0] = baseQuat.x(); + pBaseQuat[1] = baseQuat.y(); + pBaseQuat[2] = baseQuat.z(); + pBaseQuat[3] = baseQuat.w(); + + // Finally we can update m_jointPos for each of the m_links + for (int i = 0; i < num_links; ++i) + { + btScalar *pJointPos; + pJointPos = &m_links[i].m_jointPos_interpolate[0]; + + btScalar *pJointVel = getJointVelMultiDof(i); + + switch (m_links[i].m_jointType) + { + case btMultibodyLink::ePrismatic: + case btMultibodyLink::eRevolute: + { + //reset to current pos + pJointPos[0] = m_links[i].m_jointPos[0]; + btScalar jointVel = pJointVel[0]; + pJointPos[0] += dt * jointVel; + break; + } + case btMultibodyLink::eSpherical: + { + //reset to current pos + + for (int i = 0; i < 4; ++i) + { + pJointPos[i] = m_links[i].m_jointPos[i]; + } + + btVector3 jointVel; + jointVel.setValue(pJointVel[0], pJointVel[1], pJointVel[2]); + btQuaternion jointOri; + jointOri.setValue(pJointPos[0], pJointPos[1], pJointPos[2], pJointPos[3]); + pQuatUpdateFun(jointVel, jointOri, false, dt); + pJointPos[0] = jointOri.x(); + pJointPos[1] = jointOri.y(); + pJointPos[2] = jointOri.z(); + pJointPos[3] = jointOri.w(); + break; + } + case btMultibodyLink::ePlanar: + { + for (int i = 0; i < 3; ++i) + { + pJointPos[i] = m_links[i].m_jointPos[i]; + } + pJointPos[0] += dt * getJointVelMultiDof(i)[0]; + + btVector3 q0_coors_qd1qd2 = getJointVelMultiDof(i)[1] * m_links[i].getAxisBottom(1) + getJointVelMultiDof(i)[2] * m_links[i].getAxisBottom(2); + btVector3 no_q0_coors_qd1qd2 = quatRotate(btQuaternion(m_links[i].getAxisTop(0), pJointPos[0]), q0_coors_qd1qd2); + pJointPos[1] += m_links[i].getAxisBottom(1).dot(no_q0_coors_qd1qd2) * dt; + pJointPos[2] += m_links[i].getAxisBottom(2).dot(no_q0_coors_qd1qd2) * dt; + break; + } + default: + { + } + } + + m_links[i].updateInterpolationCacheMultiDof(); + } } -void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd, bool predict) +void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd) { int num_links = getNumLinks(); // step position by adding dt * velocity //btVector3 v = getBaseVel(); //m_basePos += dt * v; // - btScalar *pBasePos; + btScalar *pBasePos = (pq ? &pq[4] : m_basePos); btScalar *pBaseVel = (pqd ? &pqd[3] : &m_realBuf[3]); //note: the !pqd case assumes m_realBuf holds with base velocity at 3,4,5 (should be wrapped for safety) - if (!predict) - { - pBasePos = (pq ? &pq[4] : m_basePos); - } // - else - { - // reset to current position - for (int i = 0; i < 3; ++i) - { - m_basePos_interpolate[i] = m_basePos[i]; - } - pBasePos = m_basePos_interpolate; - } - - - pBasePos[0] += dt * pBaseVel[0]; pBasePos[1] += dt * pBaseVel[1]; pBasePos[2] += dt * pBaseVel[2]; @@ -1677,18 +1809,7 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd //pQuatUpdateFun(getBaseOmega(), m_baseQuat, true, dt); // - btScalar *pBaseQuat; - if (!predict) - pBaseQuat = pq ? pq : m_baseQuat; - else - { - // reset to current orientation - for (int i = 0; i < 4; ++i) - { - m_baseQuat_interpolate[i] = m_baseQuat[i]; - } - pBaseQuat = m_baseQuat_interpolate; - } + btScalar *pBaseQuat = pq ? pq : m_baseQuat; btScalar *pBaseOmega = pqd ? pqd : &m_realBuf[0]; //note: the !pqd case assumes m_realBuf starts with base omega (should be wrapped for safety) // btQuaternion baseQuat; @@ -1714,10 +1835,7 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd for (int i = 0; i < num_links; ++i) { btScalar *pJointPos; - if (!predict) - pJointPos= (pq ? pq : &m_links[i].m_jointPos[0]); - else - pJointPos = &m_links[i].m_jointPos_interpolate[0]; + pJointPos= (pq ? pq : &m_links[i].m_jointPos[0]); btScalar *pJointVel = (pqd ? pqd : getJointVelMultiDof(i)); @@ -1727,10 +1845,6 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd case btMultibodyLink::eRevolute: { //reset to current pos - if (predict) - { - pJointPos[0] = m_links[i].m_jointPos[0]; - } btScalar jointVel = pJointVel[0]; pJointPos[0] += dt * jointVel; break; @@ -1738,11 +1852,6 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd case btMultibodyLink::eSpherical: { //reset to current pos - if (predict) - { - for (int i = 0; i < 4; ++i) - pJointPos[i] = m_links[i].m_jointPos[i]; - } btVector3 jointVel; jointVel.setValue(pJointVel[0], pJointVel[1], pJointVel[2]); btQuaternion jointOri; @@ -1756,11 +1865,6 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd } case btMultibodyLink::ePlanar: { - if (predict) - { - for (int i = 0; i < 3; ++i) - pJointPos[i] = m_links[i].m_jointPos[i]; - } pJointPos[0] += dt * getJointVelMultiDof(i)[0]; btVector3 q0_coors_qd1qd2 = getJointVelMultiDof(i)[1] * m_links[i].getAxisBottom(1) + getJointVelMultiDof(i)[2] * m_links[i].getAxisBottom(2); @@ -1775,7 +1879,7 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd } } - m_links[i].updateCacheMultiDof(pq, predict); + m_links[i].updateCacheMultiDof(pq); if (pq) pq += m_links[i].m_posVarCount; diff --git a/src/BulletDynamics/Featherstone/btMultiBody.h b/src/BulletDynamics/Featherstone/btMultiBody.h index fe60af991..91b5c3edb 100644 --- a/src/BulletDynamics/Featherstone/btMultiBody.h +++ b/src/BulletDynamics/Featherstone/btMultiBody.h @@ -435,7 +435,7 @@ public: } // timestep the positions (given current velocities). - void stepPositionsMultiDof(btScalar dt, btScalar *pq = 0, btScalar *pqd = 0, bool predict = false); + void stepPositionsMultiDof(btScalar dt, btScalar *pq = 0, btScalar *pqd = 0); // predict the positions void predictPositionsMultiDof(btScalar dt); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index 2e6dbc440..1be76ad86 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -36,7 +36,7 @@ void btMultiBodyDynamicsWorld::removeMultiBody(btMultiBody* body) void btMultiBodyDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) { btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); - integrateMultiBodyTransforms(timeStep, /*predict = */ true); + predictMultiBodyTransforms(timeStep); } void btMultiBodyDynamicsWorld::calculateSimulationIslands() @@ -791,7 +791,7 @@ void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) integrateMultiBodyTransforms(timeStep); } -void btMultiBodyDynamicsWorld::integrateMultiBodyTransforms(btScalar timeStep, bool predict) +void btMultiBodyDynamicsWorld::integrateMultiBodyTransforms(btScalar timeStep) { BT_PROFILE("btMultiBody stepPositions"); //integrate and update the Featherstone hierarchies @@ -815,28 +815,21 @@ void btMultiBodyDynamicsWorld::integrateMultiBodyTransforms(btScalar timeStep, b int nLinks = bod->getNumLinks(); ///base + num m_links - if (!predict) - { - if (!bod->isPosUpdated()) - bod->stepPositionsMultiDof(timeStep); - else - { - btScalar* pRealBuf = const_cast(bod->getVelocityVector()); - pRealBuf += 6 + bod->getNumDofs() + bod->getNumDofs() * bod->getNumDofs(); - - bod->stepPositionsMultiDof(1, 0, pRealBuf); - bod->setPosUpdated(false); - } - } + if (!bod->isPosUpdated()) + bod->stepPositionsMultiDof(timeStep); else - bod->predictPositionsMultiDof(timeStep); + { + btScalar* pRealBuf = const_cast(bod->getVelocityVector()); + pRealBuf += 6 + bod->getNumDofs() + bod->getNumDofs() * bod->getNumDofs(); + + bod->stepPositionsMultiDof(1, 0, pRealBuf); + bod->setPosUpdated(false); + } + m_scratch_world_to_local.resize(nLinks + 1); m_scratch_local_origin.resize(nLinks + 1); - if (predict) - bod->updateCollisionObjectInterpolationWorldTransforms(m_scratch_world_to_local, m_scratch_local_origin); - else - bod->updateCollisionObjectWorldTransforms(m_scratch_world_to_local, m_scratch_local_origin); + bod->updateCollisionObjectWorldTransforms(m_scratch_world_to_local, m_scratch_local_origin); } else { @@ -845,6 +838,40 @@ void btMultiBodyDynamicsWorld::integrateMultiBodyTransforms(btScalar timeStep, b } } +void btMultiBodyDynamicsWorld::predictMultiBodyTransforms(btScalar timeStep) +{ + BT_PROFILE("btMultiBody stepPositions"); + //integrate and update the Featherstone hierarchies + + for (int b = 0; b < m_multiBodies.size(); b++) + { + btMultiBody* bod = m_multiBodies[b]; + bool isSleeping = false; + if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) + { + isSleeping = true; + } + for (int b = 0; b < bod->getNumLinks(); b++) + { + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) + isSleeping = true; + } + + if (!isSleeping) + { + int nLinks = bod->getNumLinks(); + bod->predictPositionsMultiDof(timeStep); + m_scratch_world_to_local.resize(nLinks + 1); + m_scratch_local_origin.resize(nLinks + 1); + bod->updateCollisionObjectInterpolationWorldTransforms(m_scratch_world_to_local, m_scratch_local_origin); + } + else + { + bod->clearVelocities(); + } + } +} + void btMultiBodyDynamicsWorld::addMultiBodyConstraint(btMultiBodyConstraint* constraint) { m_multiBodyConstraints.push_back(constraint); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h index 04707bf2d..653ec36ca 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h @@ -96,7 +96,8 @@ public: virtual void removeMultiBodyConstraint(btMultiBodyConstraint* constraint); virtual void integrateTransforms(btScalar timeStep); - void integrateMultiBodyTransforms(btScalar timeStep,bool predict = false); + void integrateMultiBodyTransforms(btScalar timeStep); + void predictMultiBodyTransforms(btScalar timeStep); virtual void predictUnconstraintMotion(btScalar timeStep); virtual void debugDrawWorld(); diff --git a/src/BulletDynamics/Featherstone/btMultiBodyLink.h b/src/BulletDynamics/Featherstone/btMultiBodyLink.h index e7966b852..1cd6b8c07 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyLink.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyLink.h @@ -191,16 +191,11 @@ struct btMultibodyLink } // routine to update m_cachedRotParentToThis and m_cachedRVector - void updateCacheMultiDof(btScalar *pq = 0, bool predict = false) + void updateCacheMultiDof(btScalar *pq = 0) { - btScalar *pJointPos; - - if (!predict) - pJointPos = (pq ? pq : &m_jointPos[0]); - else - pJointPos = &m_jointPos_interpolate[0]; - btQuaternion& cachedRot = predict ? m_cachedRotParentToThis_interpolate : m_cachedRotParentToThis; - btVector3& cachedVector = predict ? m_cachedRVector_interpolate : m_cachedRVector; + btScalar *pJointPos = (pq ? pq : &m_jointPos[0]); + btQuaternion& cachedRot = m_cachedRotParentToThis; + btVector3& cachedVector =m_cachedRVector; switch (m_jointType) { case eRevolute: @@ -245,6 +240,57 @@ struct btMultibodyLink } } } + + void updateInterpolationCacheMultiDof() + { + btScalar *pJointPos = &m_jointPos_interpolate[0]; + + btQuaternion& cachedRot = m_cachedRotParentToThis_interpolate; + btVector3& cachedVector = m_cachedRVector_interpolate; + switch (m_jointType) + { + case eRevolute: + { + cachedRot = btQuaternion(getAxisTop(0), -pJointPos[0]) * m_zeroRotParentToThis; + cachedVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector); + + break; + } + case ePrismatic: + { + // m_cachedRotParentToThis never changes, so no need to update + cachedVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector) + pJointPos[0] * getAxisBottom(0); + + break; + } + case eSpherical: + { + cachedRot = btQuaternion(pJointPos[0], pJointPos[1], pJointPos[2], -pJointPos[3]) * m_zeroRotParentToThis; + cachedVector = m_dVector + quatRotate(cachedRot, m_eVector); + + break; + } + case ePlanar: + { + cachedRot = btQuaternion(getAxisTop(0), -pJointPos[0]) * m_zeroRotParentToThis; + cachedVector = quatRotate(btQuaternion(getAxisTop(0), -pJointPos[0]), pJointPos[1] * getAxisBottom(1) + pJointPos[2] * getAxisBottom(2)) + quatRotate(cachedRot, m_eVector); + + break; + } + case eFixed: + { + cachedRot = m_zeroRotParentToThis; + cachedVector = m_dVector + quatRotate(cachedRot, m_eVector); + + break; + } + default: + { + //invalid type + btAssert(0); + } + } + } }; #endif //BT_MULTIBODY_LINK_H From 817e64a769219621de0debc4979630953dbee60b Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 8 Aug 2019 17:26:19 -0700 Subject: [PATCH 44/47] remove one softbody array copy --- .../openvr/bin/osx64/libopenvr_api.a | Bin 1641184 -> 0 bytes src/BulletSoftBody/btCGProjection.h | 8 +------- .../btDeformableBackwardEulerObjective.cpp | 4 ++-- .../btDeformableBackwardEulerObjective.h | 4 ++-- src/BulletSoftBody/btDeformableBodySolver.cpp | 3 +-- 5 files changed, 6 insertions(+), 13 deletions(-) delete mode 100644 examples/ThirdPartyLibs/openvr/bin/osx64/libopenvr_api.a diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/libopenvr_api.a b/examples/ThirdPartyLibs/openvr/bin/osx64/libopenvr_api.a deleted file mode 100644 index 377e345f2bc51f12be61beab1a98befb2db1aa9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1641184 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%0Akp&Czyf;XQ~4cc^ekb&upZT$y!XxSr}Cr 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%0AYFgI)rXt$=arF%P?y~O71M-_X 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%0DonDWGRsa!32VtOh{b4Q@n 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 (+H^s_RpxX6> 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à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%0Dsma zv^lw8U{3}N0Y@N!Az(_7(Gi!*Ii_jUo&+#~O$p*|U~dYxj+i!I07WWFpUAnpNU^o) z?W2b&eRC`*>>WGU_L{UdHQ=rdEpwZ+w z^s63=W60yTRj*-TS&)?1nlh}SBP`n|O5@Pj`yb-%E8zLz&_ z!{&L6%5UO?A+sUwDfWhlu=fL-6P4HOe)ZO23^+#$zG`G>s`Wim1jpV3EpR#>!5AuS zdrzkQZ+j0L|F-ume4Povhu>pSF1(2T-K4eJv1}H(VQWmamLrtZ>o52QunLyPZ1kNT zjAVHd6<@|l@F^U9MIETm;qa3o)H-bCM!Hz+xF@cgkNJTo!DQy0x%_ekYSr=)!SI|Ex5A^uG<_xc8vf&i z)LuAM`JK8OE)N#=Oo-EulX&^9KZorbgT_|SuPs}M7TcL}XX`6)TAqp+v|pOgaR6dCHP=)yTj5>5j(lw)hNC{-Ro3nAfkEdhJCL`}@9Kg7h&m(ZALp}4k%{y(0*EK+3lbAR7I15!&N zv_2&Wd#XW_HSvu-{-QkNjSc>d<~1u;U3&&EEug?F5U{jwihVsOfiZu!EnobVOwe#U0({`315aIO%&;sK=g?v_ z@g{{Y75eYS?E_;uL@@X)UuEFL^-r$B9%IC~@LKRPZy_A<(yl_37(=3vx&^8@;aodv zmK@zg;j=?twxPp4)(1bmBugZ*DOg`F#(~um53TYD{ITIJ$r5e=K=&(yHxx4zGA0`p zQlD@Q&OWfF3m#Ki$(6o=g#Dy8%yEMuoDk>#LAFmJo!}55jU|vqPU+yj*g1?OIf>}y7cfam2 zRwfk@r>btb1A1pLWdQi7u#(~qxEzqpS4^Ywr68xvWIluo>ehf zYPx5Wz6tIVr))(%+Q)tYde9{#c_@ZsH6MYZV*|@0*um1af$Ru& zKqJ@zkICb=p)13B3>#0rK{UG%uolUwR74UFQ4#CVB4!>e~xuA^G4;f`U~p*ka`lnb}Y!>n(zOY zHR_Bt7g|v>br!QIF)JSdR|^luNw`}SzN4B60;VlM5GT0e$BbFip{E3%4x6)!pmz2x zCtl^#Z>~tP!@}v3xMAqd!Wvxd9cop12{W)T@(>T7th?EM(T8+NV!0rY|5(nPP7eJ7 zTM@2x66A|Kg|X0pKk5@&z)RALYQiu4UlN}Y2ve7SZoI1wE!hXN7*w&Hyx!Y)ikdr{ zvnKh=U7GSQ2ddYUASw5m5};L^65s-7QDcH+?1U*nGB#|AkiYfml{&DN&dEf*Knsh@ zH9~HW^m55?WIBgHl^S6IS`#R(bQrUGXQpe!Bm?0>cZK!m$0}bTqi{4ALAvohxEcO7 zEPv&sJ?6!mAgGvWhzwjyMT({`VR1%#9bXNGA9{=N?z?7Fg0Nq$$jrNH@L#XAy6! zi$!-rl5{P=a?!n+4T)4Gd z>)hu}5Gq9%FKbt=E2(LTw{V8OL!%pRo9=-+vIn(xdB7HrHr3R!I{A{JW>(wh7@^CU zMraHr)exsoHH(^QzxC@C>=_nkwf8=-``~R5 z7)FKo0B`2@dWJ!L5wPtQ|BOm8jmNj^m9hVm26niW6={;`-$ezS78|W5Mp&QIC%xjA z;aKT&<%lCvY-Z?V@r^<>gSmF~HkeTtV=m zVioh)q+Vj}K8#r0xD!-a35&+XMN&A%BS=Ms_4c@+JWTsg4&B2aKat!yGta9zLy=E^NL6^4H?M+a7 zpGh5fI5msE&_YFQHEICV)~(x6F7!G-^qr2d&{d+vx;blNw+~XK?;QHsLxj zancEYbz~OoKgBlEa zE4u=osrj~rl8Ii1^tiRs0J`NCZh-X?e9hW>)m>EX^1Bcys)8Wkkt$%Tf?4N5fHQoi z1ktwAY?!*(`Ud;c}nY-X+p~dye-XHS9Wfji0Aqc?0JKhH2O&v%z zWHtTxHr`c8qq}t+E6n4#z4FPN2~<*eaUm9;u}qCmeoW$d7W2dy|F+KJc@A!Kpyz?} zz(wGqX7smVI+<6mwn2z%ZK-l`VPV;Af_zk1I#nj}KaJF6rod0T>X+EaLwa>&t=gh;R*^>+z%i~w(!o<2Za;^v@+|$Wf&#!fg&T_2oQp5x9s;nQ=id3!3jW zCLKW#%=gsBq?3<&$chl_;d0VZ`IcWn&C2#l`nw+SFCmh!VL|){ zi0h>tnyL1_m3aMoxClS&i<@vy8!r%37n}I-67F2LXt%Sr9bz_eGrl>eFwmu9ktY&vt zTRrkJNlD7Brx2{c!EpQa1a|)yko1S@vnk1?8~TWN)~i7^$1~-XoowtlAdfu;!U>YL z%02XpOi>z-QZBj<%)1VV!f`@7<|HRrJ}Yj)Ls`aomU_kJ*^Za5$=`Hm-wz)A@ts)k z(#6SdWVxsQumgsWOhVWSiHs@kM!$mKCk$}I$hMTd1;0|Du6w`1c+;`Z(%F)+HycFQ z$A~Y4Kvz}o=ZUr|&cPf%mFq2or@r}fx!i*vJnM-sW(DDu2>S5>S2yKKbl8nQziW5; zy|u3|_e7fDxq;}N53KYFV$6+z_zV31IEmL|8|+0u{jy=78pHAdQ)0O#PAC2i{(Kvf zo>m9qW-Q_}Zv7to;O7wSCO*Fxrn!E6pvUXbwdU@{3=b!ROC-)l|3uz3e<;{&YB+(A0L9{qu=es1{hyUa(k@yq*e}q9T&X zdi+%q9|1As6oEQ?W$rrs%bneGpgY&q)6@O3bIuVS;low?_IDC@@85rD&+eW>hcDXk zikH1CP@U_J?E9V0_MV1=XEnU|;ENkNd-rs9?mg0QV0Z7n14j=u968$Eedusc=iUbT zLtHETj`SSfckt@V_w{t`+;MU9c2O_OU3v82-u<0)ZQI?`^|IXI&i$Rck96kt96EZi zCwJ(|w{-65+0?V;;NH&Om*tiNLjLe)9LcQ#?+*B-fL{&x&4BdX;vo9_BEPaq@kCam z-E-eJXH#_FKklc7piF*d@}%$$)Z+NP*8Wc7ck|8Q$4Z6YN&LRRAGMs5_>Hu4_(QeB z?_~b-PzgU7!@o)H>S*v(;n#i2 z?kz$4-fGfP{OrFShR;wD<(_(kwW{a}>owlu#@Z=9NCG}CxOF>Z9 z+;2(DgFz4G>V65|qvo$h9{sY)3~w^~XL#0c1%ICbqxY5e7xd#v>7%@F;s5Z(_GdK$ zhZW>K4f!4n{(`<-(I3C=UeEov_yxVWqQ5KPZ+@r!1^v0AKbo&I9Npj-^yo?cSdRPQ zua4WO@eBGiSNHuN*`X#s^nWw__g-yw(670=pRMlyi|}6YWMb9GO~N4@#0ka`<4|+OR_u%UO zKS}@Zw|@>0_^W&F>iIkqei}bu|3Qzhn9rxd-*oUteJ;7*t4T+pUoo=$Zot#75z7tw zeMPx@;cxik_80VguI{rnavfcc@BJpm@Co}5dOuh9>6QI69jBavVZ~?d|BN7~wtZ0U z{Y-E07y5%--8Wa4dj;gK{i5ZD{^6wjG5!JgtN)Vyg??g1f1iNA=`Y(~=r30E_f^XK zd;1Ih#)|&_6aJdNYJZ{sILROL{Vn+G_(%H-{Yb9vnw9fS|IdOg(l~4X>{s}!ySm1I zs0Z}F8U7dl$^Jt>ldIcP<6ly&OFs$!x$oG2=yy&^_nGi=ANxs^zQ;+20Q?SNxc4wfR_Y3E#S}p3`Ge3 zM?P-(?*UT&e~nn)HGi7RJs0$AfENSL1~R^90U6&9|Jd}sK+@wMGyO+E(y#ld({Ub< z={O_cH$UQd?*jf7+~4+L$9rVh`ML&n7Sn$Tkl}v*N4Z=(uElhaWWmX+X-``+;2UHNX}i%k?ZE%X9XG={tcehY=v%*8?fP z4u}!%`VYd+WITgF3<=g>3}ieP0_pGK_nCh>@bz%NyPV5i4*Udg7w`jtz6!{2ZvZk} z`%Mm405W|`f8g+U0xtpmVIbwa8%Q}v1Kk3ooO6Mc^TzkO{4NDDzpo7V>j9r1@V9^8 z{8t40;qT>g8{z+-fvvzEU=#2z%%~CXOQEZPe-5PF_W|?3VsLK@^ya|-a>?>O1*E(- zAmt1nH;$u&e?I7|2QBCMK)#PtfE$2E-|hT#zAKk|Cg?UG`7Z;Ke@oH)Hvo6j9r!Zf z*+8c6*8-jz@TUWI|6c*W1f;xiAmyC}WcfXzKbLz6=HjrA=Klk~WBec2JOACi_FuTp@qW9D&QiIzNBJ=^Q)kav27ae;i2uzrEG`PXSpT9{@5vy#dz)J3znwki+MJzYY4yz*CX` zSdT$553D^m|47dSEdCvh--gl80;-`U>bI}#nM=tmMta)*JG`~HA$3Aj7pb|B?k81T%1{|M#qGPr*c$nc{9 zKLVuxG+=XZzj=rAbpw$3ItR$`PX{vm69WEtyXn6O_>q9`3;1pnBK7))*BZZuPOt^^ z8-T9{-hxi>VqianGM)>8jAuQN@jN5olLF4d^Q+)K4tyfs`_DG}{e2tA_xE}r-CuQ) z{k;@Ode6C*_p3m7S$_pO52oX0G_Gd?ZvZm>vw@8NnLx(>gWs_H`+$^x9gy-mfaJFX zY&%P{%j-7->3%M-9{4;U%XeX&<@^JXa&80S)vkX9kn(;V_{*T54P<%z2Raqf-vlyU zXPoKqrvVxMhi5o^FOcDzeoYhb>woq_yT9Ohmh+Y8+WlrA<9k8g^mm?a`Xx`bzb67; z4*qAJ;`rVKL{Y7O5s=~j_DS~lQ6T+Y0c5&4DGl z>Expfa~A?n2U2bwu-TLExeI_O<{YwcYD2)a0qX|XB}At9@JI0h8Q)~U zaUlMkI*LE!4+nQHLePCExc3G3j)1#>_;+d>{xDoiaBm2>7KneR*5eQPBpB}!{?L69 zsPq8oJ{#O;g8O7}=V@a49}Vuq!M!hFZ{TzMM0p*-eOGXA3+^q!y*aoy2KR>Go(njK z_ln0;Cj$-#>DJZdE<9I)BHG3 zd_kb&yzu?Of1KyNJJ4}n_m2Y|=W*W~=s0itjzGtG*dsxHoL4odVu^j;J^5PMG6%xhKK#l-!A+oKmMRgMaTJevdC{l z9pdk=LwU_Xsqy#WP#)Ab{Cx|GivHt#@~cDo;{5T`L;fe&%Isg?aRga;cN6h z`f_nTc=KtFKhAI8fcM1o^!>HvU4XRUU**R+g)IH%8v6M)^vyN&M(fXtypP~1D~}7h zS^9%D^k0LS<^QZk{(O!9!^nTu{~0y(B{lv(Sd+eClutJNLJj@Rn)D|%^apC_z8d+T zsL9W3YVz|MwEt}U|5g+JA8Pz_E;;LePYr!jjsII}_|)Io@IR{Y|6oo0->IQ{YW&lV z$;#urYnJAGW|nTO@&BC~`V%$uIP_OGJm<)>^v7!Gp&B~Z-u}i7=W!Ld{ned4mmfNO z4VH^H?>meI;6sP6zgFxr9UxqbicBbK(k=fa-O!w2>q+}+bD@q2f-2`{~5d(XM;?M)k++S{+( zePrLBb}wtU?>Thfz@dX%wqDuP+Pa~!y}hUF@S*G4_jew=8u{rweE87eRts?WrVZK9 zTlQSKy}hYvPuK3l?LCKg@9R0TWlw7>+%BxF#?zs7a}$Le=sa+wvnSVnRrk@JBf0iV zw{P#Z+ucx)` zl063=yR?m+hmrKw$3fBshdaCX@7_aMOxoj`&&MuocQ;n@xP4Mvb7h`YAWtTjrs@B@p^%e?mx=_L|>)gHf|0A;ZA=#I1 zhvKW&U8^+Wqer?}xO;kcw_n+L^}d7cdv^EifzxYW`I=X?ziR8I?c3YWq{`6t8x;C= zEMBYYy!@_*m=A_6yo8 z|Ngr~|F_6}{Dn$l(*TCMiaQ?D(b1U3&Xh&yn&*P%w9L2e|g`_}h zquA7Q=)gV{W-RYVRgN()L76g+?r3*h|5# z+tH02-hw&~GgX!=k_s!kecx4Eb{#oPb9vv9_NxvZz7Cy${Bn!wmL2V_tsAf1z5i%u z>$R=t^<3ZG*}DBz?fA!*a&CNK2luw^Mu*e0T*Y9-A3n10+Rputxwb+7C@z=t#pvT4 z*Y=}V{x?P!UMt@y-|vn?I}h)FtgkiXB)r(}{f~4|!M9aoJML)T(b&GD2`}feOSWIw z-ge3M^HoZZsnWcviPAPceu54hfV}f0?}8&xK^23QFSN;OcFU3FxA+)!o|L!8r`t~+ zpFY;Nr!+UIvA6c_JJR!*wUY$8zn1OT(|Pd7zC(}MB$8NLSW-%@y^p70w?Z_A9fxAu zcw7qBnq+k5~UKv9aQA>h88V{g_MO)vtP0J9q4N_q1#3}v(5lRTZStW z_x84TcOE`+=-}@C`+BZ#zqawDu;-rawBcl@CN6vAo{HZYP3N3@e#7#wX=CFB7o5Lw zn}bMO9rSN33{QM`U%{^`H{98<korXTWRe_Jw|Nbx;e{_o;!jg z*V8CxSCpsarN9KVw|917T*%?2e(mkm>6^22ZYbbrkQYdvtLTc)#53_9OC2~ng#`ut z;62AR&u+xeMNY0qG62Hqs1~5|V>;viisK`E*jY%vUBLIGZf7Jb92$;%u^#F7rsDUh z`j7F}9?ZbzxXgpIh2cDM()y!!0dVy3y5^gcT=Dnfc&k)|7;<$J!a__*3eew+tu>7?z<8*DEklX-pgs^ zz56|xx_AGP>oFs?cYmB@dEWf zdE`iiVtO}k+OcWbA?7Pv8JNEKt1Y63)0e&2e8OLg{$jr^%8@##4*PjR+NzTHaQbpQ z$csvG9m2f`-DepEX4qvC_O z=^;PxHdL4ehQ?v|{`tL0>;3tG>#E#3aY;#j;7FC*RY~i&@&kve+^)u@Ci#JDs@%Gg z*8B1US68|1!|fCKfjw1jZ%JCenjdJda=Qj+`||^Ds&d<(w0rGm3&JVn}%I$hw zSeG9-qsr}flGdB@1E*KHy$$!11HWA5_V%Q80N=Q% za(hS8+Ls^rrHtG9KGd6}cmukQ{J;~kj2p$^T_yNL9eU_k!`8o3j2xcs z7*7-9)GVV(j5;y?3o5yij}2m+A_lh$R2b)qK?^EB@VzX92jl#4g8ab0W*I|b&^F5t z+?!?mz8F6eVfWt7GEmKfY-P|3$U zIxb&^kssiG%nD;0dYz7vnB5xE-UC+#O;}ig8Vru~UrCh;e0>@p>`F#dt%O zak&_u6r(N6*d@lO7_ZJU-XO*&#P}mTS5h?t1&Nzw#CQ=ya0^HweG+%>;U1f%g)OH0 zBYmOip-7))`h$^vp6S1g^ixcKGSUwqcF6yHq!&zoInwu<{(7YEG5x(r-)8#zk^Z>p z|A_P-n&t%&N`GSdtVmyP`ZpuJ&-Cje{RY!}BfZ7+zDQqa`f#MrGJQPK&og~Xq@QB? z&m#Q*sx$KcsYoxFzBkhMnm!9dEv5e+)0ap3Hq)Jv{9b7#JkrlIUH|Nm{->B;8|epNGa~;liu8i%rbypw z`c;v>$MofqzRmQTBFzhAAn(dZ|DoxtBAu8%80qUxzcbSNOn)TOZ!rB=k=|nZ^O3&L z^n9exGJPtBo_b%;GyVKXKgIOrk$wPr4(Z(!=>^kABYm&w!ARd@dN|Uznf~iYf86w^ zBmIY_zZU7l^v@!Fz3DTsLtg3KXZpfOzrpn7k=|nZZIQmv^j}2!EYshL^z%%gis=@~ ze~RfBM*0DCugL$)BTY>N`i+sk*YsN>eb4{P-nYQlSylO-h(N$cf+JddaZtRbXe3E# zNsCI-HgEz7gg&sMn54;R6WS&rkCLLrl=MKp9zTuB8KZ~>$45YCCSHjX7|%=!wF!*Z z3F-`0nK3#unmF8<;2;K^8SekT*4pQM=j0?U5AV#qKhCes|66OX{oZ@+wZHxNl>Vfn z?^XJ%j=oFjzi{+tls@KYPwC${dY{s-I?Lr>>GK`^KBa3MU9EJhqt_~Zi=$Txjl(g_ z#_A!k<6EB?wd*h=oCx!un=^Qr6Jh>yQwFa^=07)P@GvLB{AX_l4|5{Se>yXGm=j_C z)0V-*oCx!u>oRzl6Jh?dBZG%I5#~SJGkBO2VgB>M3?Al0nEzap!NZ&g^Pj6Tc$gDm z{A!<-27pGz`$m=j_Cvp$1|IT7YR@5$g{PK5c- zx(puXM411q$>3p5g!xZd1`l&0%zxgQ!NZ&g^PlrFc$gDm{_|u84|5{Se}0|8`-q$U z{4Qug_95$f-6Z6L4hO_RXFqd6hnvMgXFoGRhkkL;+0P?EhlApvv!Cw;9b)33v!Cw- z9c~c^o&9_}=y0nz=Fno&K?j`{>Fj4~(BTJ?L7n~71RZ`T4m$hU5OmOKkoq^D)rhb#%4T z(~h=j(k~pnQr&;&XqzS#x@pU4>i#B2Kc&-#^Bp~>^m<4CNa-z(eo*NSN8hXTen;P> zwD0K8DE&u{_LTmHqxUKOZAZ5%{Wp$&pVG6Au2woVEnBPfNp4!RQt1_rK1=C$IQlfD z*E#wroi<$N=sBfR)3P5a-RImNRQh&D->dYO9etP5Qe-?^F5|H?3(^ z`pu4hpVIGfbhXl(9lciRJ&s%~(LYl9?;ZW1 z(oZ@1UZqcR)0DfEex;*7qx2gb?J2#|(fgEsx1(E?u6FeMl)lE%)k=3bdacs8IC`bh zUv>0ZN*{LgX-Yrh=%;krkeX)ADgC5#|B=!!chi~&l|IMO_bOfL=)06Icl2kJu5+}f z^!1M3r}S-(ZdLk=j((rgf9dFIrT@;+Yn6V|(JPhygRE)N`HntK-QVZvr!d??zkJxy z)J&ki=I9?O{XIuNsPxm0zE|njyJ^o|O25a^pHaHW(Vo&Dcl17`la6jx`d5yApVF^6 z%k*Kj(ib~=t?Nj2!`aiME84?VJWCTUDp?t-Zo|%#-MbsPLK?oJ zy*qpf?u={>7hwZNmg9!@&d#2WZaS5&4DIb~+TDungkfDv4P$XO(|g&<5O*JCGI6Z^ z5^P1qQKYb2mdzBnfRSPo9u3RIo+4a| z60%sA6+>y&wC@ZrD}&P7DtkS{-R)sHPN4FgIDUYI*nLP_DGCqUnZm7YJKAw)Xj|h> zJn|=?r75Yj``vcXmpnWFjGs^4!uA4R=Pb z?};M5W)y;JF|A!7WG78`D>lxCZ@`tPVPp_hxTmANs}(IT+=%9##e%oap0+m4ZW-!= z$KNu8W$icaML}~zE-R_08@rUd_p#)#4N3ZsWCpdAO1~tGbs_r$n08bUTjIt}?7Qu( zM$#FLYo}$Xsmyj-$1^{uweTgbipx-GDCydE)FCp%a&tYl4D}RnlH%;?NVkqMR8md* z4dJ@>8&Ko#<&lyVxh5~!Z>rM?Fcd`XC!wcjtg#Y$A;#NysSboW;ia&%_-rg?lthy~+*V(=kWh`k%@m_+a?LD2$^>zk`iYqI%ay(8V_B8IJ{@&Bdu}@kflt&|yyaP8e zWB;udbg8z=%{*z>shZODy;ZD7DEu~Ll^Ou8%*4_XNQw=J)pZ-fo3W{rjR@*CErJLF zB0QX7iYZGDH6DThtAo&I=B$b+oskJr%8D zt!H@BBC$X#aX7IvT-&p|yR`$Vva%aPLPs|$Y89(KkeD5+(@>He#dHu37hRyGoGO*H z6wg?OH*PB}4P!f4vvgBPqr?MYa!|l&XBnr^Eof-$aDBQ*`!xKZ3Icvov8xf()zid# zxueb6hS{Qbqv=p8rAsehe>~wJx|%wp*f`#TUXT?EDliaAPs##-2ezD@I1|#++SG;q zCEXNBN7becg{E|4yt1ihcTZP%lPL$7GAu``1L=60m!`%x>F3-zmkP5~?71w-bW&`X z#Rw|)6-ILwUzT`VJ9Mq|s(=`ZC`-)hQe}FeXsA${TB1$6FlLB>ljXre!-n7Rb{Kbz z+>~4}SDG>kb?t#ID`F_8tgzBql1jLS7Apfp56F`2=xoP$wWlj>KAwc}lMsxMmr%1WFJ+UF#X?ta+930ijWsn(hs24=GOjv9 zSy~`9P%S4S22@INaYAX5Z;+OonzES6T`Y?caOtSv!a}r3%wo?x4ztOo5zB?5iJ|o3 zFs^9F3?{czR`5J8No#L$7_cR)F?C^Db);AatkK&0>~I!)BYjY=n`vI0Q^%Y8%`3T`8Yb=vwT4MZ1~=xI60{ zLwX#@DO>609ysQvGY^ECBLULlFy&Yr$km(799y~(q(or2bawZ2ELBgKMaU$=nfM4X zm6yd4TeC)bo$<-3#9}#w63C?sJ9jpn>qeVfRJXahT^#P!n^JR(<+7dqD)uGmQb#rysB8|+BP#@4PZoZkL;x&}| zrCoAqck_f8mT^T<>O3c-9L%d3G*|X?U%6u=Y@%E;2)?=vY9W^!0(Y~QXy%w=5ja77%uQ+T^;lZ!Z<`l{)QMq7VbYZca@u za8*&xp*0|^rrnnI4KlybcAAlbt1%C5@7&xGZED?tdzn)5+H$tE>omhU<#ImJUd4>7 z$H3ivCFUE)k1XZI#mbVx8$Q$?-t3A(J)sye2FqMT{hg2(71d_Bxe>*TNvn8gRaG z`sxModg8|FX$qEM0>A&j zIt+eTd&>IZo<07~Rb1qbRYv(Obq=uTyV#zCpM}5Z+}^qHy^$gONaZY^MRKR%{1+mB z<4b^8ATD0OauOB_&wLz6{?Ckl*zmC7Hw^DI{Dk2F!|M$j4X-k+G%Phd$M6ipJj2Ja z490Z)%NPiC*|30JdHvFvNAw%9@O8M&yuQ9yLaGl|KhOaX`-SFv` zssCRY{@Cy#!}|>HHvFvNA;TLDuQR;H@G`@7hUXc+&hT`@r%$)|4S#I-kl}rXcN>1z z@Q~q+hSwQhV|bb2I>Yk}UuSr_;nSyC{Dwa^e8})V!@CVXYk0`;M#Jk2uQ9yLaGl|K zhOaX`-SFvri{J3ah7TFuXLz^aXAKV--e`E8;WdVr8Ll%t&+v7IryD+veW7eWzcT!> z;X{V^8QyL9S;H_?GxRI=%_*(|z7jiB+__f{2&9KEpaj0I23hy#q0om| z(TmP!?`&!c+((jqKKr8<&dV)bkN%OgTMazNU!132_PqBH{PTC8HM-faD((KFPh|Y+ z>-ow&&B{LSz3t2DhT&I!BX{X}>Y~ZabJgaI)}vP*M!Q?|&cv+q=p7c`fO(iec){P| z^htPKQS5iv(Y5$I`hta5Vu3{N)^t@MeeA^8Tv!+kALX|rSb*92E&7T|hs{&3h1Y@b zveQNp%Wo4d)9qpkv%`y6cu-678?x~F5S~?0R{A8rt$VO*gd0e*!>h{*Zy4ca{j$Pq zTK2w@Z7#p3YA7R?z5%3fv$8U>eZ2Gcy??Bp1~3lrH}wszkMKj9U-YvUb>(mRsmm&Wz1YU;!yj%U*{&@bR^6Jfz1CQ}$XncX38>aE~ zbM8=%_z7<0$H&9DbH2u}ny&F{$7}q=5FBg#JNhW&B_pz5OTkOl33Z2ncgHrR1iU*M zlp<7ne_!K`wU99>>MAn1LE1*7|AE4YcSo%n)nzwa326507*jJs5=J9 zj0@DpUk|Bak-9_D8#n4F;ExDDF)H!`weeTgdVf&uJzd>@|B4!K>p)E$|Glk)z(L>; zaH!V%L5+9qaJ78SI#fNmUQ!Gng^(DHOjeCBt&kk8iC;Sc-UP(QK?7^2YT~t1wei!y zJ_d3c;h)e7kfT>4_!ikTO1NV7>u~|agD1SjHgVP|DFRAoHl6qgMhrlls zevF3~B5?y8Tg!_aIKmF`{>l$t`@oJJJKkAv_CdxT%DBJB-M^!k?-ZQ9(cBL_CTD29 z1$3n0-!YZR3W2|lc(HOk%`zx-Hg$}R(=o2##U_*z@M2R!`2wClt(1W0A5)4@@U1iY zf1cO>G}0a`A$_otQJ{fP#)~besDS5({+$sjcz(W83f1`$&o6@XTxI|>8i0W3&nhM0 z`SVH|@j!{51o1`n0nAbw-zOoV^(J3h~B#!4iC z%8dI$p@Wj?`4#G>RIE-YU%>OXDJ9_f4N3`kehaC|O3P*?VnE;%K1SB!Y)1TKFCF}`VSxm5RQjO!m2yBPRlr)g-^Y|dB}npOLdAWdyx5?) z`2*^vRBTu%U%>N6RAf|`qL$G^$CVPuP$LE3D(nA6UjKixSVNKlf8lAi{M(puf9wn5 zF-9IFW`)vm4XsTn0WVWq>?=GPqgOk?8FvAcP(@6N`n8f3PJFCLREX$b6gSl{>rxbo zf_HuX+^DAM^BHL}Z6tuku3k)2iDHWT0{w^c5TxoT1+-a_P7;pB7;JWWry12`Y>G~d zJnjo8K1NRD@GtTz27ZlDkCBQic>au1gn={AcePw~1c@gjh^+KM?|a$;*xuOmCq4fO zl(99b*Z_m@Vs(-}1s!4#+%{qQR$C21B?LS*HR1*(5w9!~?|?4q%#Xw?Fb=FQgntdY zwvTO0JXiHW=gT8bRYovuN8&&X-FO}b4g*JkBfwGMC~z95lE)!84x9i^0H;!cSIvSo z3)Vbv9=HHp0M1NSJ<5XY-~Z@I1^s7Bkyg#bYajIEj|ABM)ghCX_FLcB7O4MhB%7*q`V%)jlnN zFjf3yYz08_9`}Ug7haX*I2nmM#$Np9u4%T zUIyXCD#VKdMhvACe5m{J0``$Z`MsB)zQyx26T$=G-C zm(|jr_Jly+8jJ=Z~p*+Jv63W66~Aytqpl*&vB1+xd~7$-1&;P`_XiGW`61B&Ah+-Aj1#%#<_I9OxS zBA{b7s0A=(7L^FG7QN(^iwQ-44d)V0StnDcpkz) zh=Gz=JG{g|IliRr46kB1w@4g`27ncDQdpQbipyfdc?5hhoS$Zk@RJjurPYn{!RHBG z3281LZw1mh-meG(k6b^^5nvt;W8o{x#yf)@sOo&j$LH0%`o_qM`L!GCY-!qT;c(&99y zL{cZSB3E0&f(a`w%hXnlq|z1aFWH{7Hl!xPE?ZWicyBaUPUB)*RM!Y(xVR<=%U|Q6_fW7jF+nW!wIPHB$j8^Mp>;w4A{PZXJl-3M%jr-&U zH3MnU416#(>^g)MomGs^mJS@D-h_sYCr4dr;bp|4_Yp6?Z+I5(8@~84cCY{M-!~lb znavm9Hw>WTpnne%+yL?7`v#Q7i|-p`{7{Wwl6!t6jfaNQi|-p=eBS_Da_q(T4N#^p zzHfN(eS>?y^567*Lxs#PW#yEMZ!ov9#wareZ&FQc-yD~DQSFJ5?-oH*OP@M980%o5 zSdRu2eCw6{Kg;WXiU!v#3=LeNE^{1Rbl{umc=kDyhfj}Yy@O^4O=5aM`KsQTWC^lsg{ZMdv&56Vrc$Y7$61UrdYzq zRfu@YJ%ZN-qrg!hUXa(0Bi0Gv1aJyC6?6wKKsS(hqVdAUQlQXAWDzm3IgWkjG*KV>%!unv^Q{$Cybs8=ayv zT&<|`0!0<3CqGH)tnjqR-jQ~LTUs^yV58)a8fu$+oxc(q~yl$7|DcAz7d%bg_E3?7g(tSiB4c#Va7i>!X}p!_zm5 zk@#99Zb(A2mx%UWO+jzVLm(p*!CQQdSHSbfl@jp$38e^u(nxO80^sZIRH5j*?%2Hg z5XfAZ#S#ux7=xM%@LlZl#ofdnF%Z z9LQ$A#H#y9{M94)PFCrI6$5{ba$s&M29lSG+~lDcAFOFs;Bkqjc{6%^cGLWbXn|x4 z+GOdI!B&|Zaba3B6$YBGwqjYUkr&J23GW$Qym-%u$C12(*q>qhnrq{tLV~qjD4B~1 zV7Wsn0o{azTvCyt7>dNr7l2MsNwH<~hSKAgqg$fCv#*`A!{Y*$s9hq9&+tghEn<$hLfIec1kWEP#mzD9F+)oaY z^v78I*ov?M5UdtmZsj}nIR48x&sFHEA<#oWjPV%fy;=;e`0v$XaIGB;6iuuU0j7)v z67Vzwp&1Bg4yJJ_fqaO}t<&~y;^PosG*D}PF}P+7u(r`B#!wIuMrMr8{_2xIjJEv! zih)Ov{Sr8#EuSh9lX$(#EFX%Iwk93IqickNj=fm(^0vI}=6zER-UmhhNI7STYeBz9 z+|S(iA*!h{_6!VV11?@o2=)bl5y750yzPH)K+*=yEU6WcDql*$unmk@!vdk@%X( z%HLuc6RKbv1wRw{?Ndk$tAXPH0UP#|QpgA6nDG5+P#0C^7aX+ZAYr(5 zZ-0iu{f9Z?&5A#T)JyDnVbepqE$>mV%jHSk2V&O)RjuQrM+OrrSBER9yGb z*^V?XQ7-t_`y2x1OdA*l$sJsHk9f{+yn>vnz(|OIHnYVdwk=k)vm;zTTD9=5hh!z zaM#3&>bwb5p|I4zK@20}2OD<%Q3*t0SAtnvQJW{b{=`8xL?iSXYkQyrV|Ogp7}k z2zM->!zgy($!Kb35|-AyNu;b$myu^f5hv-(2xIIL&qL*(1VZ~hVd{2K1_ig4Egxa`7?HdgC38> z_fJ5ELpFxz9-YMKSmC=Ii-Cf{m<1eZL*6I1I%4Dcb-PD7QF)jX8gT~!_ct%4L@RGAi5rXqs8s#Z#lLVShzH}bj zRBYRb6*4EM`of|Pp4^1X0+^S$bm7ZcUb0oaP? z9@9xFOFPT*F9Pc?D3h*gjBkD?>M7Iah%mj71AmO3P~c>VH)Osd?VO~u^8MA9Ye)-D z)Ph+3?!_^br-K-yJYpcr#ZZ!VPNss3_-7`smozbN@WI*-WW~)z#dfAaSR!0}%^gqSOP@n8W=X#fJx@5KWHN0AC-zj*lL zw)Be!<_42B&Pkw8b#fx5uE#y3)Q`rpRn1$lu}XA*1KP9ae*k~y{2aUpH(>dqE3(A3 z`xdD?dwNcHZs5vtn43k-XY*uc09CeBI3u)5d|Q5e?o(|}!%|ai633Zp&qBmawM`sj z_X$t6=^b?_AXDugOtobuWBuZn3}5>NAK5Q@q2^8J#Hef{!G58p)bHsP%`v7Hqb?xT zFGzsbB9_mIzM`3eC)Y150I|LFtQp_fX>e+n>ART|enrE;QKkZ(dquN)YFD~PFdyg< zlah4w2tHVkn84!_J>m>hgZ2~5sojvw(G^WneB-$<@SGYyD1&;^{;(3EoRDBx1zE%5 z6UoG*n^n_tl38`ior9*69klO-^`WUa``R-TTzA06llfA_fi(|5QBD@Lg6dXjN|~?u z;w5k{5h*>-qUQ`@0BcR@{y0522pd@KX*()t8|&pt}YQ53ANGdo|; z;rLr&n2%|yXdv@HX4_uRG_1@i&@`TBLBnR}wnrehJ9<6ypcg>T%kB+?LK|ClOeSWT zRj+msy&NVw-pXO|49_srxe7}AX z{RWyyhX}Sm{>M8f-KDErk7eE?^FD1kaoLcJ>2BkIIvs0!Ygwm3Urbw=bOY<;(*SYC353H0O`XF+TNsVRL@-znT5@n7-p zJEX`}Mh+e!_ohnNB)PX%GV61)gz0h}skl&(Y)}ya)nV|^qLM5mPy{_W+bev`S7o`t z>TOH|ObU2%Xv$oY(@eOXqjF~h53&Gs8#|g7+6Cu|ICzRyCoK;xanTy^;?qfiBRKMY zBQ;=6NLelWZg?CbZoo2e^rI6Vu;?8bAf$HbBPZxy{BM<|x+P<>kCF_b{7|hcq!@LC zvZJ)m;RrMKO(U#SV|0oEM-?TOu@NNDRRpCVK$bhbh%89gcb`}cd|y#s+-0`U$1$~r z=F2<)_-vZ#*5?1Wn(08Gneu(PG*vcNj3&?BwqkR8v8g`arW$;IvV=ZmdtLE-+Uu7a z|6gve$hsSLUu>^>Eri-t82^f>eV4x-;ssW%!S-5GfOh327ygZ!cx+xEF)QHD0Fc0A z0{%3azTY8kIHu(n{W`7CQ_lmjw}CA-(jj>~H*X-;4nLEzZTJggAr$GC=t2bt-;B4G zkvR8I(EzW2y9^L!Va3S6kdprdAg+M3@Jb0_=n~2oz*4YM0!W`ygy3tL6-Zxdu0#S+ zL{wA&>(5FF;2n!n3bLc4kU6YmqA^-(03|9Ufc12x1YrCqMF_rNWGDzgKr_$0f@y=K zJj=nbgFoPmJylLc+2uqAEGVr*zk|`ibdp$OLg5XNGW!JlUUgF{HYk)YfTPDMGAzu5 z0FE9jC4i&HN)ZBfPb?%w;V(SS^0lM<9~aRWc}UYSp?m>s;ZRBd>tjkO$kAgkQb&0$ zfbee+4vroJq|x9MCOJ5IOhA5w|gKSc^hj|s44l_Ka-er;mq8W|zy(c>pj z#;)n~N=UH^@uGl6u9SjrwN)p~ga8&tl~RC_k?SbGhV6Gy6wOQn6$(d>mDwkd=v6nN zu>7LTL188YaP(Ly0j$9(C4fa-@emskrUL9sr37%wQYp*sF{K2s1gn$)rY=ee;C%@w zYz4+&Rtt_E<0*XxjIKC(jK9G%V5HFqaP$}tas~`KE7cdVii}<;>ot6sThA46tk>XK z-<$El{{a4~iW`2NxEF#E@y95Zq56c6cbkX`Izj+%0hAJeDgPwhd;y#ZQAz*}Qz=4F z_03AxG|fc<6xJqFhlE)_xyV?Ag?8PPfLyj_AAU~xBw=rtWE+qvqq42&+nJof- zgSsgd>lMluz^i!`84zYdz)K7&C4jc86d|Yvr=?u|DL_gM-XNke@{pzpp?m?)pHfNy zonI*hszG{9sX+@M|F;NdG8O`uS`iKw80moOC*YvFQY(}a2&lom5|c~QF^yLMs#z%k zsAi=ER1MB6M*vDws3hTNjKOB7cZ33yv0*ylholK7K1NPj4UUqE`vTaIs1!lepq6Va zEV)S%a;m{2uJxdSH82QRSmH$i4PGe)-)gH|m%?x{SD!ZJ>K(<+^P!@HJ4%UIh8WRd@naXSs z@VBX(Qn3!9d;#qCRFOVmCIrxel@fs3REiK(ltWA}c1#0Oin3iqW8|?}2;~c4`;bxs zP@76AP*KurO7U0#p{EeeWNd*>(lCAD#K*`%-1&5mD?n{3B@j@QZ4#49)3i{&05&Eo zB>=Ullz=MAS>*^|*OyR9!qFIm%}(zy1tw!dbkg(+2V3mukg^v?NI{7bu*XR$f+$KY z*VqclO_GpPQGOInW&3->fF+D0_Pjb4mCxlO-Gl=uV{spgV=~1u)DjB>>&Y z+oYg7dC^qh3d3IM&8F-~AjM%76@X2slmK+6QVOCiJD7{i0PjZJ|;G(VSYYdflR4 zv6xeHZb5#W=B#57cn>ATp@0Ujl!9-yRV2)WfR`vyN?{4jsbTvOilUimph96GSDD)c z5_Re(6wFU$wg@vJ06nUd0Q9I*0+`8&hghF56`)6z5`Z36%CbAElmLclr3A8XK^=kH zWb8}$%WCOQ@+qx3=^FRR3u;c%qB;5CG$*^B6#ASgM>St$>qEppId++tm{afpBinzI54Oud&R!DfZc3uvwa?xc&mc&td>6hw2DGmEA(<10s*fklnP-}2q=Moo%ul#a%q}SF9NW3l@fsNR7ya# zBHd(X`r}o0Bc$$vXD-9CoJgVYW(enH$6HgpJ)2si$R@IVls=mif|~P1%t^ ziVI~|L9UJA=>6)ZAlfp-Tx15YAZgV7;V^O3ivXsIN)dwElA%Cb3iw(E0Xy@Vd29QJ zd_Jb_%p3GoX896jCj3-|lr!qohGe1KaqiqVP;b+;3fP^~cG)yu(Mw>74iQm+9#x7E z)SUB3Gdlh(Af-9qE21&-kfvdwGOlI9yp&8mdxKV`dp)Q*={2Q^EPz?cPRd;frip|T zADhuY<_UUtB=x9L0s+l=wXj{9##Kll<0LZzm{K zq#Oaa^a>}gA2dj5&Or@T0BdSW5kzxpx!TDaxwRmt=KM#LvD2It48rXx*26kz@Z4F0 zB}4(=YHNj1x$em1Ucp=|IvVzKzNK%QMkoM1s+2(H-O#+`dD*M^xJAGY?pF;Yj2}Iti5gS5vIjYvNuUN&aD;s zm?}ElAMKx9TY(Vd)(oER=^1xA?ik8GpyS|Aclf4xFc+s)i{i*4Uq5zGi}p`M&|K+& zEo9ROc?#*9j$8zU4n&{@2N5F^4F{hL$jw4-2CP}^ft7Z^h@~S> zKlLZM-gHtyOfL~R6)S((40{2xoX0ftoa7-{fagLyUDJ-XJ|$VkQDL~by{z07AbSfN z5VpAM{?%pn6V_SDz4Y9G{DH@KeY!hv=&fGiq}`YL)v%w~nVbe{RL6Hmato z`}y$;e6s`v2RsHmhQo#UL`C&VFeda2-dgN7laE{!+%kbU&~miN*;YF_beVM&TP{pR z{O$yG9M}3{C|LP$`j$y#6sL_L3Z%EM`NKX8OaC529R@ww=}$o|K|a(;_DXk}+DPs8oU zHb2=>i{?{1qsi(&5|+2S7`dBY>BSN)fUSfOasU z!2_VU9R*To0}ANTnKouJBw>lkT^qj&=Q(+r6jCh+iHAyEU^qNVR(0NCBz~UJVD(ji zVJ;{`z)Mbn!f{mrFEOo@01mGTbqApu-^Ho%?w~P_PuvK2cg!k9z}Zq}Z{-gVK?B)= zQ>JKYWJM%76MVueEdmTj5si%sxT(vqxIHc^C63mwy#T7D7VU*M`tbjIYT}pVBcr_# zuI@jak6|%{7KaQkV35IvpLqfM;=bQ2=v&9odeL&J>}>P8T})wjI@?vT%EX~&NuF+okGnnb+8ce{=I-u~ z6(*K1=)vuF&m5BM8d%$qZC@?W{nze33+@2MfB7&$?Ev)fAm{P64NZ92LeVtL{N}$1rwJdKepz*WMEx#_o|} z>>eG)YF9Y-f*)deaVRXe3sJ3+vK458$jCQ#F$ zv=5J~vq<61hEfDNW1kA2Jlw(}b`sx3gAs{ej4+A9Z7noa*C8k*b*M5PW7G=Y$e zLGhqF>^-}j*x+JFNiOs-8mLhfR$wFygpqi?I)qfO8 z80(eb6x?^H>~mDfUgJ2BU<&ZksZbal?g`B9D*MKLPcL|t?JUK7NO)w45|@%=}?A%&Z|)Dg-DUMj}>?VgMhGRA&gcbpf?+UnkN$m zyST}12Bzaf;#a=mgVXW(N)b{z9zoWz;Re*Q9`Yv_j>j}Uf_#-r=8cGQ1`IflYLo)_ z2#rz#dM^Z&@C2BqmZ!x14gv3uX{87$wH(yP92e|Nuuj&YpobwWCkFfxc@n7EB^OPs zsL{&?=zyUVfW|){;P(mB?-dxUBj93w4A0j-P;hp|iGHuD4pv^omlHd^>QR^D1mosB{bIsI>gl>b#PsncJID7W|0-DuBDDf z=D3>`;VQ6Ui?f+f&4ZWhM4nQ^DnzLxCK48-vx=Ga{oz+*^q1W7s*LxEEtwSz>#52ER#yBuJ$YCuXR zbwL2^!?i~XZuvTk%RhN5HnBpjPuwft)=_JnCyL}u6E*%;jsVd9K-&5;4ANBXIfjNY zCGqq4!~~wyXw=y7wgv&axL13RIjKPy-)~c! zT~&i92F|PYkEj!D34}Grl$TC;Fnr{`4mD%-TuG`V^CI!Q$S(Pg+lojYvQ-IHLY<0RPcc#Y{ogh*LL8s3RWpD3t(>J3NXxsvXj5KX2Isg zX2-w^l;F*(u}+~MWOBz_>{yI^y#np4P(4U*xTvzQ;NYE7?CR_qwOS*(kH17c2xQ!! zB{PaRZl>28T~It`n%L1hEgI~!)BqX;lyZl}tgP%-Ev0xIi48QqzfYUTrQ*@^Kqb`N=RD^!gGu zaWo(SPd;7&O8bzRA^LeO>rVXK3r50~PedWYxoB5S7#ZssRRkupiNo;RJFAj?;6>#LFP%jG<7+`!u|q)DsYta5j; zT)DPu>mLzGy>*04<6MtO+MRB$TiErjNRTi64X{YwaHf4g*JF zV~Em3pOcU{pt7)VQBUS4S2)dQhx0NF8_r{ljtrUQapK>L3sNSo!$D%DElWGvgndDy?WBEF3t(+|iugnEJl!G+H^D-vkJS5E?JLLor9Y2Do)FYT!zb#grFM2*BeuOw`wvgZmNjgoL^P7 zX*5i+Bt+A1s25uv;Wc!(-H!$PfyAwlI27aG)Rlbyz;gBV?pM8$4SCQ$XMm9G`dR%z z6>C!xLp{S6N4iYJu{_n|dQhRPJDm9E4PCev3pDBrV>;B7l!WM-@p42D+tN>rNRV66 zg807^M*Puo{aEBW8FBwJ;=#WzQ^~N^zffHedp%Q+gW&WmuRxGiWE}r+R2vs;!8tUi zC2d~}Vf(__ZEb=>cpgH^(2l8u?K7;g1_n1tzYKg(Gdlno{J*MDUk*PMIsEiVNDy@= zgarB*UQ%$&6Y6VR_~$3^1JUbSVuW3xpdyOS;BhBkct zZticj5VWLh{mQQO%`PtvlPE8N{#h6ba)lDk{Gr&Sy3&p>fny283l5$|$F~HkW3nQA zE_r4+NyOkuNgX)C&J3-Y?%&7LcW@u4U(Rx<$hZi>bsye7fjWy{8ZLbj%4W#>b>z2? zM-I=NB<+T8U)gl3&~$jM1-}ShSy+SqhASr+(jfHDz{Y{vTMt#;n(AE0IdgY%l}L8t%#vw(QHb=1|FTfV@2}c0E#_1z zQ#P%`5~DhwbVC>kK|*C|4Mog3N7X=8>BL6wepkSGn7H=zf!_x?B$$fk`ohRX*IVI= zfw*zN--$9j6yx7qCCm;Xm+_|(!)}NYt{PyCCfM1uQnhrY^GWGySBeSvq9jm~Zd95^ zj#1%Djz;rZvMk^kE8rnK52Jufa;?9dK>O5EKuO@mqmCp}S?>Or|DyRY*IdzIkFirf z%lWX(h0!X3FX&u&ZVT!ZX_{f0`Z)#umL^gdv{h99uRupZr3CbU94V2BC+e(cmID?Zq7T7CNm{vgZ>$JbKVhjNw~mfrNv~o;$Y5; zoT}`df-x>r=;GoAd5_$pt*Ng^6$(x*WHU2 zb@%_S=AO3n7tKA@+Rn5KK@Vn|ds0%)+9Jg8w< zbpgvx41e5qRZ(yo3=_V3s2Z#o==u1es*k7aj#nVX`lh_LZ|)pPJ_CW;;y`m%IC9|U z+^hMIP+u-xC-LmXmGZnFwNrF{z95#MQV;^jj#V@>kBX1Q~zc5lzm)4_9M7gcc=30UH?S6*npYu z?$9$b-sR}m5hKJQ+3~;<}2I zP`xp_r6VX3%Qi_!M}QnmTMj(gbclGcTFFR$%i>T+_u;d0HIDiE4O?S`(l?UWloL@m z0^I6I?ZSsNPRgtHkR&^gqsNot3CVLDA79s(ukJX3u6WuT+06IFcrVEyv%ZC9OQd5% z61jrCM7N93-PSC9vwo56u`f8dL9~)?Y{Ppc_|}$=vq}s}*0#-6_jDOwQdU z3Q6x?$L>b3o|Kx+D>#U|^3!#1wP4L&wv?h=SpaBM!w3+iMM&=;)$fsvvkv54^-8P- zCr8Bt_I}77P26vZ2^x8l?zx*WzfHF`CMI3)T395uJ{=c4^=pVKA5b zB8^460%9ndLI$C`W02dBP>BVU*W7Q#a7eOoTYqv}sL4Xh7@-pzVnNOO6_kLlpwPAHz?P>)HF6O;oB#g6mVIu#wMVv!qdtTzm4I9_6&4ynUwLP0qyGsGa=r*?zAd5O&~zVi(w&nWn)I+*V1L7cgeWI7-Tnp*T|bp(Urd8ncaU&wR8kzQNgJt6 zkNNqF1VpDHggUw$I6@NuAC1Ym-zLml03ce+ct{J);OmzmRi=Z-8XKd44X5S`SOt;_G-k&z6I^Uu9q@f_0s8! zq(2rMJggc{T{DTG*+0 z#$GERR3vwVb47eBY|H)QkQoIJ>au6bx}qjlcW_8%YzL&Qe6HZ;@3%90S1r2f^1u<+ z6<53akh|3P+w%E76$dd`N^u39Koo*gaPW%(^Ur-*OgEEb6Q@+V?mvcY2P$){v0X)B z5t~Q(m-7in#|5N9#7V!CVq0@?>Af&x(yVQP5Qm}3l+njNq$UhoL^UHtPBZx1Byw?pe7Ll{_j`n%hM4x&dP&c9McplF6s@ssd31x>EaS4|&WxtsY&|Xct%}I-+CPngxa2&IqU#phv#YkPB6^g|XPCA{{U~lp|ovl)4;=!lb9# zcs{0t*oL@ux(2&&fyaQDDqcIITf(o!bP@l(YcW;4c7E|TaJ*B*{Bc;id7RTkE)C0z zLhIHz<;JO_bm{%6F0Bc+SAp{K0R~v`>!YcC2qHOIk%Agu6VLR%t<<-Qv|H#=R_%zx5=*YL zzwv}d%{4bp(rGsW`Kbmf!O5y&$s4x_sm(YZS$ltKFZF52IZE%?;=Rg0D2zu0`wDF^Z;@S9 zBP)=E3Dp0DIO+5b-xjv5GV7rPv48y~kzGM;DEt_f?M9TKJ*I} z_+ThfsJT$Jf};#l`l@TN&r?5i0MmI&@*+kmT0HxQ>JxSdFtlH&YA`EQ_n>4O#j<2> z`h-dd`b0oa_=0MXpff(q*uc1R-Fb>ugiL^j=XSH!)d^O1?Iiwlu(G<`bDf1EuStI1M}A5&%^L1KMnPn+gG0SHqxiNSom-jhVVC1 z@GS`NozCU|UYfquhso^v1MpL1G~-WH1o7vY+dp{#Y5O=+5xPkJ+5@*8e}(c_fXh!1-AAGsL>cgV zB>n^h^Diz(&E;R{Qi%NXMXR{{PY}2VIP^;9fpyK6@MaRHBX>UjuOabiOn z6v4`m4~&doXA9jA;!fo=4}WFmLwNp-`7|*@9PHblDEfTZL?<{Cw<< z>hd{Y-fMA&p9LbJ-2>u7AmoRD@Jr?Q7ee9>ADG_)3Ot4X%%1#GvJa}?P>2sa7=ISa z=BFTjqmqGe*?r{42R7rKWYpqMrSb!^XS#6tz;L5vyd8f&$Oz>3&i0OI+uqKQLPukF zOV>O1b`nEd+Zwm;j)uG2!_Cp|Xy=~RwrKe3P2oDYg*Qcawsv)Q?hEf|-5qUf+!H-L zAl?~mY|bIs*}f)rMJ-)S7kS4*4@zB-BR7gMi6ao zMd>>C)@awd#%=_=y{8+G(az5H&UK-!TP`WzEOCW8EIoS-V}@Tgyvy)^8)|N#K&Tq= z`_`8fsaUdq6#>S%=m6)0Ug8>j%7rHs`QwgU{1&;_nfuFLChnE;7k@tb1$}Cu`o!<5 zlLb=lPni1zyEcB={=>t<4o$yF@ypubQvL_bz3&`#{}GfJeku1O!$OA|&Qp94@#lr| zQtlVrsr-@>#U=A+?)B7df$$s5|0wSm!LKPReGBFuewVs06@G=e53Bz?l}`Vid5=DS zZ3*|m%H`cFHmdviVL_9|sQE?ZcQh+5mA+wf->4}|`JXla^HKG`Nul(`*n6}fD{|fWpw^!YtQCO6| zz8lnG%M$K0=DuY5d)4Do?&0IOSD5=hFA;wUZ==EQ$C|%I=`Y-`?n}jAV(za}pNst0 z-K73EFX2A=k>$gmHutktY*G00=KhN%!k;;?eE6Z8mv;{z$GyVbmn`3Y4gbL<$~ScD zapE`kAFJ4+{D%hAp=^o#S9t2aRQZ&|)xBwn@Q2NPsrsKdj{A(ce{+fS4f`7LrX}JJ zeM}veia%`bw2SduR6Z5v{wf-&p}a-z4S%Q}?_DB&;URT@1ofB8f9P}S?rHs2DisRt z{v&;Yi7UUn8#jgWdJFRkUw&%-AmTa~Tu$*?Heo7>AIDGmRlc(DmX~aJ#VMEdzmz(M zavSl#W2?$pIbb9)IrSxB@iFhlx*Cb;)Z1SQve3o%4iF40V&T|$8Ora%jdc8Fg-3bn ztRl|a@w4$al>fD*l>f}q z>G&MvOAcwcHqM9gcV?vnLGs6RT!68tu;K0gfi2*O=3IkOi+`R6ZPP9H$H zE5mcMxOwR0xoN`}>-1xVTpU&No8#OtzD?<6-Tqgf74TT#1Qo}VnV^RE) ze}o%3ta4^=gz|4)I@}K++>s+H{|qaEKi966lJ;~Ea(&-XIkQ7@%6%Pj<0iLM`#%@q z{t$AbCm{FlkQ+GxxpUDshfVIEE#0~DQ3JV_qnZ!1S90c~8*<@?RBpL^d=7FeOwR0= zoZ%gTT;X47cxK1slzR+vk?$Tq-dAHXRbg^w*W?WEU63m`IUB!o$~ALx_PyiB`%%a( z{IBE7-2=J#6OiMJwONx}uHN{XZPe0dc2LfIyaRIEzJL7mZGl{!$(dc0GrSK&F8>D_ zp4mq^<-P>D@DEjPxpMw4|V?P7ejf*Oy}seC(%^yl2eb z${F4Tkn8xF%F*u16(05F6NszmpH$B5uTXyfW6E&xoA*!Pr6HzT#UBCI0QUkv1Z)I; z7+4AH35DLh4!8@r3fKjF8}K@~{|a^1|mskZUeT0UJLvmz`Je_g)kK?zVS0i zJMeEm9SXGr*TBB41fB`J1o)-f)ZdLj`nw!h0es+->hGJMQ2E~thC0{?CYz7zN+U^y@kNcs2QEU(myOMxYz&j7v~`1pZP=v}}Eft33v z%-0z2VIXv0@j3fLp$mbp{jj=!`NmKPuWX9PP}nPhw*&DCrua?3HNZTe#D{t9+d-EC z(H4r&0A37y9F=?#@F5^xeH0%Ct^$aGx}L|-nRZ<2XM@iri$D!vqW65=fZBFV+GjiFFA@CU#)U@P!#zd2*kn(qYQ0Z@IzI`d+#72( z{Cr>==+C1vn9hH>T=5j(TS5QyGL`>63ZL|Sz}EreK!)=gbY|8|9+2UD`cn1(%S#lW zsnYcP8}MaF=TCt2_sB-&{}qt@PXS*I{;j|jz_$T+1J3{!0e`yzHY4z}>y>{HNd9#| z^8d9`^LGP~{u+UFzZ6LKU!gOS|3e`8_W{Yj7|3$@E;=XOzXhcG=YVwI0Hr~GF_8Q} z0FpoSF7;Omd?V-rU=8p$=?CEz^jd4W&E|qFE;);hW}6=3Vj6f_XC-qFI*T3-Gu(!1w<1nzGIEXvlYnjR~tTz zPECKKK>E8CotggL4@6TdE<TL=!E3stkLxfV04S;E#axcfZl!H2QN!`$q3I zy25@ci+G_0io)O|Fbw0Y6LzCMAI$) zuF<9MQ2+mm!GPuW_du50BS5C-0pL#XM}bk`Ag~#@707f{1DTGMhARwDHGFcV=J!{? zFyww@^#3yYE5MV%|1^;C?F4QIeI=0PvcdRo0y5rL8GQ%e;8?LgMYHX!|72xPpkJXhsUehU_& z!B4(f-Tx<$?jt~!=hskquYvpZK$cq+$n;bht~D$&{AU!_^>F{q*&6N>Z&Lr0K>Gi4 zApL*A@MDI3Z&d!v(CMn-{^aXbpM4Zaz4$1U9`T8@u(%5RDUjj(!0^wZwCL|EK&F`my}1=t3B1CZss`*g*Fr)mAP0~t<};pNB_{jCAgALmZ= z_XfiYkT}*4_cBPiovit21+v`U1|nU#JjB1@uwkEJgJFeX*f3-`gUpJ5!(qcd!v@0&!?0n< zZ~=wFa+${;mdgxK!ZREP;@>Hw_(S($sIBeKw*kHH~NPl%e`l~R0x$#SkA2xo-Z~^r%@c|`1Ae>G)X8dX6PZ)pP_@l-j zHvW+D2aVrn{9faC7{9^z+l*gl{0ifT4FQsl4*`*`S~k>IB4KWwycT-%l}NZ-KflOm zw_g4lqr=1Sh~MMrM3f&G7BX}{^pS*zagjgjUAi9`7BY07(Qf^FgUP#f?1Z_y_3Z(R z&#h|FZU%^j>?hEzpRrxm-Qob+b*4^HS`X?Rwn7Usr>F*1< zb>B{eO?S6WJOeSI_o@7L=u?)DTc`e_`FHD@6XrjBtIEIAh1ak2KRW+6EBy}WSBB@- z9Us78PTK7=c%RW6l=$PgCGr^5`Mb`_Z-yNczfz2Iba(6EgBHG9cfQHoL$|8@-eH-5}+O2c`jg{AMT>Vd zgwb8FGw6S?S=}E+`cY-6UorZ3kd8w>NdE+ORFHlQ=?&7Q$WM^oiS`(ztFq`wR(RZv z7?giSR`@q(rS~skHwNX)v*f>%75)b3m!SO0toVL|`U|>0nic*nS?NENmEX^2rO)hv zRQYZ|dkBVK36~)K0Qz%~{$^HupUa|Oot1vf1vC6#pG6O6(O=6dpO0qcKM(CSn4X8T z;(saHU(kJTR(YL=_84?8&T=oxO3!Pv+TX9Uc-tY(Fk!tHAb7OxTCQ)+SS##Guq|EH+Qe9uP-etsjuHF zn@a1qH+Dtqo7(s6X>Y5p*~5)-oss5Wy_c5N*EdJ6?}>`<>MJD8 zmWH(wZFSp@_Nps3*RM_ODy`nUs=lhKYIW1@Xk+Jcq19<{S_IEAjAxai?bvAB_B>M* z4CC^$vJF>nVqLqP#`SeQ+jqA%m6o76)U?aiRaYNN%C3U!2H8!_kW73@>9vs79lwkG zES;PS;AxX?Tn@w$Y=PyCUAh_8C0FZzjkcX?RB&k-8c=Ifz3$JgZX&C+sim>AzPq!r zwY#gjsVb`u!655``s&SV*dofYm$;t0hg}?j9&kZ`|9gnKw4^!eHaZ`tgv(Z=urh1) z65BrR(!FHml&;_0xHr0`ogR)8P3fxjHSLYfmtennK>B(2x>eXSZ87Hz>-c>x5Q5ZC zY1!uPeY>O0@8u@+&W&Xjx@v-)OjS`?lFCf$jFj_Ig_#ntd|Xgp-_^0ZwYz?M&yF3@ z&gao2HwD^cRxB@Qd(R5H6#6)zil0XYmQH_Zb}3nXA6I2xzz&+7;6;Hg+j?>Zv04U? zXEknQC*rw}Kv^MKT9(a&j9gj%vc|w??SFMwcVpA8>P7x6Js2%>4WEJ9SgMC?aD8!e zcWGI02;W#5?4(&8IK$1_MW%;EjV04r$Lkbtsnn$eoE~~E!$)=?*)8(9k4qU!z?F$6 z^@UXenPETA4tl)67B#YQZsCH-F*Mm~z2KIt>ywY;yvAqom?`i6;Z|tszWmH`!mMHZt z&I97yV14V3>TO+}Wu-_^SN)Fm&Knv#o9k)l@O)hL7L1Ck_i~0-wYTbm?tLB6s?8hf z@h_O_=VlmR*ct7LcJ7T<1%rA)3*h%3L%C}|mWkkmqP4f`I%y{XBOe{Db%{3F)79dd zp3Jc7aX_&NtQ{RV4cNUy+;%s%?F4`K?)ub}8vLzoH?+1j*Kdk;_25`0n(u~7&|{!n z+PZZ{vtf5*SJ$Q}Y{qC?6C|Wh?CILM84UvR*Q{kvufMFlwQbYo&#P5eZN9L+i6OdB zvZhCCkdD@!ZB?6^HeD`qWvkb3kaM6;$?V${ZR)|<(Y;ah42D!zhRH}(+uqjB_O?AZ z{s`63%64nc!3i`9+;Ow&As4&6wW~I|XM40W<>`6#XUmz3$->IczuG7+#+uSKT0u29 z{ko-{Z$nZQ@Pc-Ps!hRiN=09`s*Wdn(`n#bjH#%z`g?&Bae1y(l&z80C-W#x$(Hsl zI8e+{B2^mCO~bg1A~&U_IH!!cyS(6m+34yivu_%=bhRYulGfhM=s7LXuIHN$Y00JK z5-Ri9!OZbE_6rhl#v7p3a#*`+nSe`ky|pL}zP^&z7BCO%?ZwpgK$m_&n*>Ll4k$jn zTWi`?-?h8_hWZYuqUueT%P6(?$}RQ3uc%EGGYD zd38pTpHn~>ebWI2dj6V5IcZPF5{)I`h}ez09ATZEs&n*I#OCx zdlnKzOHAH?Z=r1!sQ(wXqru+nx}mY7zP+crzNxjdsb@D{Tk3lx3=U|p+4D-Y<4qXN zt0YOK7mDiQ8>|;fHRmXb=dZIQ(4{6hrDZzA>L9~h%lg3Lp`|33f-G62AeW7dt0642 zt|~W{KIeE)3;2hjY4h581Xfb-T85~a)Vt-X(4`wT*o39NnpO62RxMub0wHJoN7pz%RzUu$9clE(>RoDG32v`jC3F-_kO(vUwiyK(j zHL@+o5LU4tBZ{}x0A?H}RCa}pJ@tpMt)g_YiQK0R`@CMG)K*8C=@iY7N!?EVP&<*T zFe9@9M-t4`2x>sZo_0yxqD>Scrp5?EaewFI?!NtyY-4xYKm10kv-jR}&;2_0+;i`J zdroLcBoYaQqLIkby1GzkaRlEOecimByLRltCUGZLCc4SEqouX=j_tUAqvzGrzy1_g z?*Uw&^8FiLL$I1~S89du!GqU6tO@_c9LE;_b*+%^t&|6k34GK=&CMG&HE-Mj4U3X0`!BXk;+weB@Vhfy;1a!_1{qgemu?aa`F{%l zuAK2B1H7n#hYG_LzSRqS8qy{QVcanzAHDz24_@)0*Z9~LQwR{Rte*G7{x}Qv_{fkL zY_c6BknY#epoAEBYPn57ne{gDshbu%W3YP5`2=|4xjN0j9=OWQ1>6~!%VQtNb|)HX z!P;3b7jN8JlOZ)2Hzf;dusF*=T?3@WLqPieTBP?NQ+{m;fk`e|eE${I-}3~a*#p|5RX_FQbR7uwb;ZJPw{B=W#QB0g|?0Eo~1LG;@uYMXY2qK_ka z9B31OFt!-a0p?KD@aaHf3rzcR9@Lbw!fIX@11NpzDHeR=sXIfZHH$ORhgfh^1m z_d-%V_LBOm4Y9uh_Wuo^gz)3VW*gIMCOJ3!=7mcAwNhqSb?oEjT$)ekF`tO9@nHk* zaE3=#iOCulXB?UG+Gk2&tspTdwdQPu z4a*#VpAi*|7Xy!N`XaP|=#)EU?qcHVAx``(r)4Gb#B6Q4iuGC_pCrfpO{M^f7?T<^ zP_K|_b!H^?LE-s>QMk!jUz3$UpAcZ+Wdn?TD4!f%~3t)?vCxZZRjZ6&&;2H_}m&jH2z|{@zJAnrGBXD=J4}}#Z z5d~01mRb-agAgM{5hIf5AW-rui4+~eFb-i@w#bVl>P4DQAZ92#dYge-aV~OLPCB1~ zn5ahDBt@#t*tD9CRsW2lAkCp1`S?w|Er@G{!c6Po_NqRl26IK&iT&O(nI}EaMLnRp zoD!&&Ze}o-GAMe>BEe=*?)r&{qtOgtp`9`N1#k+J> z^FXSb*p-p`6rqAD>}s~p47h%}j131#_Mie9D|R4Sq8Ck;Q3-Qu}PLy`|2 z1^e8jKapW>UHr+PFr1BfWsb(qA`>m19O5Zm%v@vQ1St|Lm!!#rH160IaGGw*)PI}0 zXlGDWGU}2lqE6+oY=q`eL$C{|h3p_HXC#FZh;YTkErz%kKrhrw#bT1iKqN(@#4spP zxRf{=Ol6?Kt&BM&;M`YiS-3sf)K*)uQIKyIv|ZMcq@7r!$P%FF+RR^#7$;_4yNlySQl*)ZR?=<>%>81=FE- z#CaBwoW-|cH_?W586U505YG1o$=Nkv7H|x3Eba}%cLFqwM8|3mHv0Q%(f5uhZ-{6% zuA11wKa>!%?oVFq$?+&Yu>L>l97oxfn>c>C?c!(3(B7R~I({6^XGUwrDG32|yB9y6 zCo49iP7g&!v#H@mH_>aQGTRYrchWHtvi6em@a|!W-IJuWf~(hmAXN$|yX&n9Se)J) z)-1d0&m2SenJ;KK9o(HKjNy0Y?H;CsDI6o@$tJXBMuqLYw-z)1J7vZ%PdJ@31LK-_ z4`svQltv@uCVIYWKYcf%>_cmM1_SuwjbPv0A)O_97O%4TNhH$Z>2!JVy#N;ZN+1gG5(9j>A zMD6FU&Y}`@^z7W|As_nLa2FU{X#(nO@i%2@{!T0g=cP3m`QH4EkR>C|vw>6i*vYGb zU*H6Y7#6*|4^!JocS>|I7y13cXDP>p&+nmjR9vPwmB~|l6TX-!&K2Q(22O!4-V`5o z4xs-2nf?R{wL9^fE1pvJp&)h?cK3^^Zb~TgRm^8i=*&IARD8cZux7t|`n&csl-C|` z_TvCW$>*QbsC!>nzBp*|3`oHt+3O1f{%qr&8r1 z&u^oGeFBUb#K^G1^yf0G@HWniz}pM4G8TE8cD()~z~01RIB?7&h1omB1#B$xw>uRo zJ%6M{1#V;9_W~m|i)pG*7`tCAIPNb4T0b}<<8w*cV3h9{=$gYnU;0xt0h3STKjMdE zX%}~LUO(@|(gJW|4;<{I8Hm34H2hzgp;;7k^L*2Hxg;httTEjF5k znQ^V79-hd}W|b2Me^VEMV&PPS0$}nnWE#UZq;wA?I%o(e=2Sz`drMC){hoPBbBW$;}?=TG(f?Hzm3&Aa6=^Ul2qFlH?eKO_Dvu^^_wusI1g^)irZ* zndTX1rhSZQe4-6I;XOPLPqef=BdGIspyLZT<$N&kUAh(mfCm|1q(&`;jHnd)UEw@3pw-WLqKzNnttvgdj(cCPm(-20dcu-3=7L|W4#5-vS!Ir(Qyeeu{#M`yif*E&&orFMLK~th z`+Sx}TSnL!JuGAdK*g@-`RygAs4szOrTHrs=$6ss6#i32>O<-$ z_-q8D(l-pXlqLYa3h5q%rkEzL1y-IMxbhKLJ3?M&7t>(rBLzo5Th^DrDPCsKFkK3p zfXhfA8KZn~35n&2PsxZHrXPw7&g6U*E9hru%bNWcn8Xc-`|^NUSp1o%+s!=uc;$P3EIUc(3~-!FxXIh`KTke5(n(6i)ieIvt}WUQ8;Y7iESPT)9~-?3JcDj`l6IXQ}!w$|O+CUP;l*_Cwfa(N>Ff zu(Iuzxem~4U3M)y16S>63iiR`J(LwDf5)V`dr0L%2R-&um%a}eLnxXBhe<>FsWM*o z6ty7DXZ&dnxGx60*FE?hEmf(-;ku~Q=5$7~0h329ttvIME=bZSAdR~{ZCH2_MW*F- zJ8vi=AqL)1y@Uw(U-rnMhK2121uzJk7`58FZl#y_vK5;^CbJb&0x==LV2(F+WKjHX z@$iTnxCT7blPhaprRnun!O~L(Rj> z2lDR0IH(mkj{+!fF3uYRis3v(KOfGc?3gwTXgiLrxM|TyO|1p~B91EZR~OATZ|0|T zl<2*(I&($))vyDaiNm2a45PuGVEP8Qx5l*z-CL4B=0w+O@6|@{&DGwEXi2Ki;*N@* zY9Irw)++DqMr5X=VZPHLN7r~u40ku^q&VH@po8Rn3;(^2c+_^r<$ebawMRXt6NA={ zLDPYtiy?T%_WE0kaeN4faigfl0)Nvs&1y{J53efXWq~9KB$gk$4^wj=dx=T%b$`Wq zob(5A13q2?at9wYT3dupAXnXqUeH5}O7FMrfuI?7u32H&sTpS(c4~qdc11s*Vdox@ zBc$ld-jV3*C=P?4n33Ky4KF``%v`Y#*E+I=bKkWaTVAyf)dcAcN{i%AEH#sIKDG}f zKK2qP(}|PrZzArQdA17^TsQ?j=}tyG=aW3`C@C}+@|=?#z22R<(so(&6V`e+JC6`i zlr`#Le~MY=d;(wO73ZPuRAf~ui~gPQ+D>9NO?vSYw**qoFZ9Z8)WM-Ml{T@$IbmnM zjHB$dbKK2dzQQ?a?~`q;GefHgnGeMnO*Xc~C+tJ>gYN0|_Fm%X(#Suz_x(NQLuq6~ zHOxoteH|5;k!qOB?R}3_V1^+KD>MC2*w7XiDI`nI%kAv;O81c;pB zD@&66YmPUzygyPCxh+rKQ#EO!P-&Zp?YTP=OC{dI1;bl(mywLlmL*b^P$a({83t?d zk4SjVxHt9#yoveYN8Ve^Z0vSD<-Cb2h_`<5;YYF5NG#Qc;u4aaa^BeEyn)Hj)qm9; z4S0#;t6N@PnW_oyao((+z$Yd7kkpjNbkF=CSFi23_o2{eY&nveA7o7Mhno$+1$_Q> z99uAl1S&X$Bwp1PS~#tb2zQpx7k4Tq{5kElO@TjixFRP0JeH16t%x7DGc0OGof*)! z@?#jrQRgUqA9cnFq@D2<4$$`T03Rz3a1MMrE_`}hVSuO8@uS`=Jitd~fJ1p@A|L)j zJ9!nzfi&G(=P!fA%g{ieZMf7PCk3VDwb-7zS_}g`%WLFi#mFNg&OhVmD)A~0AI^~7 z#2A*W2e`gt!?_wnA^C_VA9fRmk$fvBAHLifLo%-BaW{@zkF;~t8*xVhUK?sWle+e+ zpdH{bIfXBF@(-k9l`UHs+moQ$m8HZ|;MP3}+%Q#3(ZL>fvzLJn4S#Uo2!Bkc+m0%K zpgsluDCPr`jORCE%|yjlI8$~;WymzfkA>HW_|$baY#>eA5{Nvfh2lPFu?g(p43P2@0Ee*%<4 z-}K=Xa8@`u+r=-5tV4Isn*2qiU_q%kO1OVp6*q|q!Vi6U51$`V#7-P; zZqkHe9X>F)^raKY_hTuszJ-75D{y~paOunSDEgc9GoVkQfjs|Na2Iab(q=`Xi|?vi zvUFMf@`kUkT;<$n2q~lkRXnC(jkPR|Cm%TURHPgG#k1varJCcpfz_v?-(&N8v94<* z{bm6b^s}1&J7xJ7-6a`vv|`{nCiQQS5PVu_dX`?%#Pc@wHoH7xXmx0MFTL%8XQhCO z@~1U@P})(T|6|SH2R{S!(C_x}ROC1IpUd-4X#TE+l5w{DeVR`8qN~xbT_pKuOK+vO z0PqB)W)=18(1HCAMH5i`-+H@zr#Fi5ROIi{^p;uD$(a*9-=C%ay(A#;Ts=#AAL$Wz z@N+_XD$1WeOL|0qm)J8){+yzOoPeomTg&+B-%P^2`}CPpbJ7Tm`~C>eo-Z zyQ)93Ex_wlyxHh|o@$BbZ2ni<)eoM|J1h8Kr=_B0{>p9vtrPfcQvY>24=d_N!~AW0 zS`|;{qZJ&jPM7e1jL*6WDOTqv{CCcdk9Rq&+T((+^VJHzP#vG@P5w@^|0ei4f2-EJ z4tSG_r}NMX?w_6RN#M7uzc-ziRq5^pUaR62=sqz!-POe7>NajRy40>+z?=D%v`go8 zMfu!*;6>g$J0AHv-83zDDhI04n*v^wx&c*rP!(_f<@l|tx=U5LP!;cP;MFQ#3);m` z75;l1cxx3;15X81X5 z;jlD@X)8zY1oSoRpTj>>_!Nkud7oPgh@YH z015vafP}wX;kAJ1f-w1}B>abW)aYdZNsq4bc(TMB0^$v+K9={Z0o zT{)rg;~JmU_(6^D)A(ME?@-td$n^o_`e=MiVMrkWm-8GT@ZxWyKgkb?(ND)TZ1l|m z4IBOPhZ;8evo=!a7pHu~O^7!UG;Vf2=7XxQjE=^9BldTGy95;l6|uQY7*(swk! z(Zjxm@`%3C>%e{-HhSP!6yNA|?Px3E8$I)dD-q4z1i z(d!l(dgxqwz70O5^31;BMhzQ1Kg#ss*8%)Z&%InKM^71qsRFDFnZsQl-~GaNk4=zvJ{?wM8F^3P!^7%Jb(HJW%;j1|M=4<%JAPo z`%BVMvOj!lS$Kb0_%F)B_C(*!*a;ZVfCRF0FfbyO`=hV$q^t zso|%m$aGPOk-ewNZLlN4F$SKtvaf>rH4onxUAk*~ebWORuJBM$-7?TQmQ`-Bx3t3N zXf$4k7=x^^2D2Tu(b!xnzP74#>5t~tSGH(>Q$VNp$8=bXf3)v20Q@hPAoBp(UujE#xYtm=pzbGIg+jTm<^FB3 z6WO?-ebweCHt&KZ(dI{&DQlPjGY1Ev(MOusJh5$nI^|l7>*?$3R^D%DYg72q@q!< z41`eg&h;D7V_VT<)BrPjC32?4Sz2n$lcY-huI TVStack; typedef btAlignedObjectArray > TVArrayStack; typedef btAlignedObjectArray > TArrayStack; - btAlignedObjectArray m_softBodies; + btAlignedObjectArray& m_softBodies; btDeformableRigidDynamicsWorld* m_world; // const btAlignedObjectArray* m_nodes; const btScalar& m_dt; @@ -119,7 +119,6 @@ public: btCGProjection(btAlignedObjectArray& softBodies, const btScalar& dt) : m_softBodies(softBodies) , m_dt(dt) -// , m_nodes(nodes) { } @@ -139,11 +138,6 @@ public: { } - void setSoftBodies(btAlignedObjectArray softBodies) - { - m_softBodies.copyFromArray(softBodies); - } - virtual void setWorld(btDeformableRigidDynamicsWorld* world) { m_world = world; diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index 3e6656c0d..fbc663f35 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -22,13 +22,13 @@ btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAligned m_preconditioner = new DefaultPreconditioner(); } -void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated) +void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated, btScalar dt) { BT_PROFILE("reinitialize"); + setDt(dt); if(nodeUpdated) { updateId(); - projection.setSoftBodies(m_softBodies); } for (int i = 0; i < m_lf.size(); ++i) { diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index 30c2d995e..c681300a7 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -62,8 +62,8 @@ public: // set initial guess for CG solve void initialGuess(TVStack& dv, const TVStack& residual); - // reset data structure - void reinitialize(bool nodeUpdated); + // reset data structure and reset dt + void reinitialize(bool nodeUpdated, btScalar dt); void setDt(btScalar dt); diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index 4dd45edc8..b77ba9da3 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -51,7 +51,6 @@ void btDeformableBodySolver::computeStep(TVStack& dv, const TVStack& residual) void btDeformableBodySolver::reinitialize(const btAlignedObjectArray& softBodies, btScalar dt) { - m_objective->setDt(dt); m_softBodySet.copyFromArray(softBodies); bool nodeUpdated = updateNodes(); @@ -69,7 +68,7 @@ void btDeformableBodySolver::reinitialize(const btAlignedObjectArrayreinitialize(nodeUpdated); + m_objective->reinitialize(nodeUpdated, dt); } void btDeformableBodySolver::setConstraints() From 7adb6fdff3bd182f27668836a5b9d0ecc109856a Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Thu, 8 Aug 2019 17:43:49 -0700 Subject: [PATCH 45/47] 2016 -> 2019 --- examples/DeformableDemo/DeformableMultibody.cpp | 2 +- examples/DeformableDemo/DeformableMultibody.h | 2 +- examples/DeformableDemo/DeformableRigid.cpp | 2 +- examples/DeformableDemo/DeformableRigid.h | 2 +- examples/DeformableDemo/Pinch.cpp | 2 +- examples/DeformableDemo/Pinch.h | 2 +- examples/DeformableDemo/VolumetricDeformable.cpp | 2 +- examples/DeformableDemo/VolumetricDeformable.h | 2 +- src/BulletSoftBody/btCGProjection.h | 2 +- src/BulletSoftBody/btConjugateGradient.h | 2 +- src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp | 2 +- src/BulletSoftBody/btDeformableBackwardEulerObjective.h | 2 +- src/BulletSoftBody/btDeformableBodySolver.cpp | 2 +- src/BulletSoftBody/btDeformableBodySolver.h | 2 +- src/BulletSoftBody/btDeformableContactProjection.cpp | 2 +- src/BulletSoftBody/btDeformableContactProjection.h | 2 +- src/BulletSoftBody/btDeformableGravityForce.h | 2 +- src/BulletSoftBody/btDeformableLagrangianForce.h | 2 +- src/BulletSoftBody/btDeformableMassSpringForce.h | 2 +- src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp | 2 +- src/BulletSoftBody/btDeformableRigidDynamicsWorld.h | 2 +- src/BulletSoftBody/btPreconditioner.h | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/DeformableDemo/DeformableMultibody.cpp b/examples/DeformableDemo/DeformableMultibody.cpp index 78adf7bf1..e947a5585 100644 --- a/examples/DeformableDemo/DeformableMultibody.cpp +++ b/examples/DeformableDemo/DeformableMultibody.cpp @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/examples/DeformableDemo/DeformableMultibody.h b/examples/DeformableDemo/DeformableMultibody.h index 8bc9020f3..acd9d421d 100644 --- a/examples/DeformableDemo/DeformableMultibody.h +++ b/examples/DeformableDemo/DeformableMultibody.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/examples/DeformableDemo/DeformableRigid.cpp b/examples/DeformableDemo/DeformableRigid.cpp index c26bcc7d5..403ce4907 100644 --- a/examples/DeformableDemo/DeformableRigid.cpp +++ b/examples/DeformableDemo/DeformableRigid.cpp @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/examples/DeformableDemo/DeformableRigid.h b/examples/DeformableDemo/DeformableRigid.h index 1f2bb0911..0d0e0dc5e 100644 --- a/examples/DeformableDemo/DeformableRigid.h +++ b/examples/DeformableDemo/DeformableRigid.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/examples/DeformableDemo/Pinch.cpp b/examples/DeformableDemo/Pinch.cpp index aaae1df3f..df0964447 100644 --- a/examples/DeformableDemo/Pinch.cpp +++ b/examples/DeformableDemo/Pinch.cpp @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/examples/DeformableDemo/Pinch.h b/examples/DeformableDemo/Pinch.h index 3d01b262f..1616ec39a 100644 --- a/examples/DeformableDemo/Pinch.h +++ b/examples/DeformableDemo/Pinch.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/examples/DeformableDemo/VolumetricDeformable.cpp b/examples/DeformableDemo/VolumetricDeformable.cpp index 6f2b88f8d..74d9678a8 100644 --- a/examples/DeformableDemo/VolumetricDeformable.cpp +++ b/examples/DeformableDemo/VolumetricDeformable.cpp @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/examples/DeformableDemo/VolumetricDeformable.h b/examples/DeformableDemo/VolumetricDeformable.h index 04e30d9c6..fe5d326a5 100644 --- a/examples/DeformableDemo/VolumetricDeformable.h +++ b/examples/DeformableDemo/VolumetricDeformable.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btCGProjection.h b/src/BulletSoftBody/btCGProjection.h index 6b5caf581..f38fa545c 100644 --- a/src/BulletSoftBody/btCGProjection.h +++ b/src/BulletSoftBody/btCGProjection.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btConjugateGradient.h b/src/BulletSoftBody/btConjugateGradient.h index b8dac7184..22a9f3ada 100644 --- a/src/BulletSoftBody/btConjugateGradient.h +++ b/src/BulletSoftBody/btConjugateGradient.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp index fbc663f35..746048562 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.cpp @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h index c681300a7..f87f7f509 100644 --- a/src/BulletSoftBody/btDeformableBackwardEulerObjective.h +++ b/src/BulletSoftBody/btDeformableBackwardEulerObjective.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableBodySolver.cpp b/src/BulletSoftBody/btDeformableBodySolver.cpp index b77ba9da3..eb8e62237 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.cpp +++ b/src/BulletSoftBody/btDeformableBodySolver.cpp @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableBodySolver.h b/src/BulletSoftBody/btDeformableBodySolver.h index cdcc6ed80..94102afa9 100644 --- a/src/BulletSoftBody/btDeformableBodySolver.h +++ b/src/BulletSoftBody/btDeformableBodySolver.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableContactProjection.cpp b/src/BulletSoftBody/btDeformableContactProjection.cpp index 27fee5cf8..84d35c062 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.cpp +++ b/src/BulletSoftBody/btDeformableContactProjection.cpp @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableContactProjection.h b/src/BulletSoftBody/btDeformableContactProjection.h index 9589b165e..64d448b5e 100644 --- a/src/BulletSoftBody/btDeformableContactProjection.h +++ b/src/BulletSoftBody/btDeformableContactProjection.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableGravityForce.h b/src/BulletSoftBody/btDeformableGravityForce.h index d18eac57d..270222b7e 100644 --- a/src/BulletSoftBody/btDeformableGravityForce.h +++ b/src/BulletSoftBody/btDeformableGravityForce.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableLagrangianForce.h b/src/BulletSoftBody/btDeformableLagrangianForce.h index d2bbcef40..eb4d032bf 100644 --- a/src/BulletSoftBody/btDeformableLagrangianForce.h +++ b/src/BulletSoftBody/btDeformableLagrangianForce.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableMassSpringForce.h b/src/BulletSoftBody/btDeformableMassSpringForce.h index ca8ddf983..f97ef0a03 100644 --- a/src/BulletSoftBody/btDeformableMassSpringForce.h +++ b/src/BulletSoftBody/btDeformableMassSpringForce.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp index 2fce9e7a5..3b3b62edc 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.cpp @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h index 6489d6ebc..de5eb7ef4 100644 --- a/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btDeformableRigidDynamicsWorld.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, diff --git a/src/BulletSoftBody/btPreconditioner.h b/src/BulletSoftBody/btPreconditioner.h index 8860a8cfe..663731a58 100644 --- a/src/BulletSoftBody/btPreconditioner.h +++ b/src/BulletSoftBody/btPreconditioner.h @@ -1,6 +1,6 @@ /* Bullet Continuous Collision Detection and Physics Library - Copyright (c) 2016 Google Inc. http://bulletphysics.org + Copyright (c) 2019 Google Inc. http://bulletphysics.org 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, From 12653f9f191c1706d8cffd2dec93b1febc3edab3 Mon Sep 17 00:00:00 2001 From: Xuchen Han Date: Fri, 9 Aug 2019 10:14:35 -0700 Subject: [PATCH 46/47] add back files accidentally removed --- .../openvr/bin/osx64/libopenvr_api.a | Bin 0 -> 1641184 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/ThirdPartyLibs/openvr/bin/osx64/libopenvr_api.a diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/libopenvr_api.a b/examples/ThirdPartyLibs/openvr/bin/osx64/libopenvr_api.a new file mode 100644 index 0000000000000000000000000000000000000000..377e345f2bc51f12be61beab1a98befb2db1aa9a GIT binary patch literal 1641184 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%0Akp&Czyf;XQ~4cc^ekb&upZT$y!XxSr}Cr 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%0AYFgI)rXt$=arF%P?y~O71M-_X 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%0DonDWGRsa!32VtOh{b4Q@n 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 (+H^s_RpxX6> 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à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%0Dsma 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 Date: Sat, 10 Aug 2019 12:12:59 -0700 Subject: [PATCH 47/47] fix gripper in pinch example --- examples/DeformableDemo/Pinch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/DeformableDemo/Pinch.cpp b/examples/DeformableDemo/Pinch.cpp index df0964447..44e5f4e5f 100644 --- a/examples/DeformableDemo/Pinch.cpp +++ b/examples/DeformableDemo/Pinch.cpp @@ -87,7 +87,7 @@ public: void createGrip() { int count = 2; - float mass = 2; + float mass = 1e6; btCollisionShape* shape[] = { new btBoxShape(btVector3(3, 3, 0.5)), };