From fa00ee2bbd82f063733f1c0f8c3029e02fca2cc4 Mon Sep 17 00:00:00 2001 From: jingyuc Date: Tue, 13 Jul 2021 00:45:11 -0400 Subject: [PATCH] Start the reduced deformable example. Read in mesh and modes files. --- examples/ExampleBrowser/CMakeLists.txt | 2 + examples/ExampleBrowser/ExampleEntries.cpp | 5 + examples/ReducedDeformableDemo/BasicTest.cpp | 286 +++++++++++++++++++ examples/ReducedDeformableDemo/BasicTest.h | 19 ++ examples/SoftDemo/K_r_diag_mat.bin | Bin 0 -> 100 bytes examples/SoftDemo/M_r_diag_mat.bin | Bin 0 -> 100 bytes examples/SoftDemo/eigenvalues.bin | Bin 0 -> 100 bytes examples/SoftDemo/mesh.vtk | 83 ++++++ examples/SoftDemo/modes.bin | Bin 0 -> 8068 bytes src/BulletSoftBody/btSoftBodyHelpers.cpp | 40 +++ src/BulletSoftBody/btSoftBodyHelpers.h | 5 + 11 files changed, 440 insertions(+) create mode 100644 examples/ReducedDeformableDemo/BasicTest.cpp create mode 100644 examples/ReducedDeformableDemo/BasicTest.h create mode 100644 examples/SoftDemo/K_r_diag_mat.bin create mode 100644 examples/SoftDemo/M_r_diag_mat.bin create mode 100644 examples/SoftDemo/eigenvalues.bin create mode 100644 examples/SoftDemo/mesh.vtk create mode 100644 examples/SoftDemo/modes.bin diff --git a/examples/ExampleBrowser/CMakeLists.txt b/examples/ExampleBrowser/CMakeLists.txt index 4e40d7072..eb7565490 100644 --- a/examples/ExampleBrowser/CMakeLists.txt +++ b/examples/ExampleBrowser/CMakeLists.txt @@ -388,6 +388,8 @@ SET(BulletExampleBrowser_SRCS ../MultiBody/MultiDofDemo.h ../RigidBody/RigidBodySoftContact.cpp ../RigidBody/KinematicRigidBodyExample.cpp + ../ReducedDeformableDemo/BasicTest.cpp + ../ReducedDeformableDemo/BasicTest.h ../Constraints/TestHingeTorque.cpp ../Constraints/TestHingeTorque.h ../Constraints/ConstraintDemo.cpp diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp index 9f8ab035c..6bbd7363e 100644 --- a/examples/ExampleBrowser/ExampleEntries.cpp +++ b/examples/ExampleBrowser/ExampleEntries.cpp @@ -72,6 +72,7 @@ #include "../RoboticsLearning/R2D2GraspExample.h" #include "../RoboticsLearning/KukaGraspExample.h" #include "../RoboticsLearning/GripperGraspExample.h" +#include "../ReducedDeformableDemo/BasicTest.h" #include "../InverseKinematics/InverseKinematicsExample.h" #ifdef B3_ENABLE_TINY_AUDIO @@ -214,6 +215,10 @@ static ExampleEntry gDefaultExamples[] = ExampleEntry(1, "Multibody Cloth Anchor", "Deformable Multibody Anchor test", MultibodyClothAnchorCreateFunc), ExampleEntry(1, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableMultibodyCreateFunc), // ExampleEntry(1, "MultiBody Baseline", "MultiBody Baseline", MultiBodyBaselineCreateFunc), + + ExampleEntry(0, "Reduced Deformabe Body"), + ExampleEntry(1, "BasicRD", "Simple dynamics test for the reduced deformable objects", ReducedBasicTestCreateFunc), + // ExampleEntry(1, "Simple Reduced Deformable Test", "Simple dynamics test for the reduced deformable objects", ReducedBasicTestCreateFunc), #ifdef INCLUDE_CLOTH_DEMOS ExampleEntry(0, "Soft Body"), diff --git a/examples/ReducedDeformableDemo/BasicTest.cpp b/examples/ReducedDeformableDemo/BasicTest.cpp new file mode 100644 index 000000000..6d4ffd775 --- /dev/null +++ b/examples/ReducedDeformableDemo/BasicTest.cpp @@ -0,0 +1,286 @@ +/* + Bullet Continuous Collision Detection and Physics Library + 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, + 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 "BasicTest.h" +///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. +#include "btBulletDynamicsCommon.h" +#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h" +#include "BulletSoftBody/btSoftBody.h" +#include "BulletSoftBody/btSoftBodyHelpers.h" +#include "BulletSoftBody/btDeformableBodySolver.h" +#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" +#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h" +#include "../CommonInterfaces/CommonParameterInterface.h" +#include //printf debugging + +#include "../CommonInterfaces/CommonDeformableBodyBase.h" +#include "../Utils/b3ResourcePath.h" + +///The BasicTest shows the contact between volumetric deformable objects and rigid objects. +static btScalar E = 50; +static btScalar nu = 0.3; +// static btScalar damping_alpha = 0.1; +// static btScalar damping_beta = 0.01; +static btScalar damping_alpha = 0.0; +static btScalar damping_beta = 0.0; +static btScalar COLLIDING_VELOCITY = 0; + +class BasicTest : public CommonDeformableBodyBase +{ + // btDeformableLinearElasticityForce* m_linearElasticity; + btDeformableMassSpringForce* m_massSpring; + + btAlignedObjectArray m_eigenvalues, m_Kr, m_Mr; + btAlignedObjectArray > m_modes; // each inner array is a mode, outer array size = n_modes + unsigned int m_numModes; + bool first_step; + +public: + BasicTest(struct GUIHelperInterface* helper) + : CommonDeformableBodyBase(helper), m_numModes(0) + { + // m_linearElasticity = 0; + m_massSpring = 0; + first_step = true; + } + virtual ~BasicTest() + { + } + void initPhysics(); + + void exitPhysics(); + + // TODO: disable pick force, non-interactive for now. + bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) { + return false; + } + + void resetCamera() + { + float dist = 20; + float pitch = 0; + float yaw = 90; + float targetPos[3] = {0, 3, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); + } + + void Ctor_RbUpStack() + { + float mass = 0.5; + btCollisionShape* shape = new btBoxShape(btVector3(2, 2, 2)); + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-2,0)); + btRigidBody* rb = createRigidBody(mass, startTransform, shape); + rb->setLinearVelocity(btVector3(0,+COLLIDING_VELOCITY, 0)); + } + + void stepSimulation(float deltaTime) + { + // TODO: remove this. very hacky way of adding initial deformation + btSoftBody* psb = static_cast(m_dynamicsWorld)->getSoftBodyArray()[0]; + if (first_step && !psb->m_bUpdateRtCst) { + // save rest length + btAlignedObjectArray rest_length; + + // assign initial displacement (perturb each nodes by mode 1) + for (int i = 0; i < psb->m_nodes.size(); ++i) + { + for (int k = 0; k < 3; ++k) + { + psb->m_nodes[i].m_x[k] += m_modes[0][3 * i + k]; + } + } + first_step = false; + } + float internalTimeStep = 1. / 60.f; + m_dynamicsWorld->stepSimulation(deltaTime, 1, internalTimeStep); + } + + virtual void renderScene() + { + CommonDeformableBodyBase::renderScene(); + btDeformableMultiBodyDynamicsWorld* 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 BasicTest::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(); + + btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver(); + sol->setDeformableSolver(deformableBodySolver); + m_solver = sol; + + m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver); + btVector3 gravity = btVector3(0, 0, 0); + m_dynamicsWorld->setGravity(gravity); + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); + + // create volumetric soft body + { + std::string filename("../../../examples/SoftDemo/mesh.vtk"); + btSoftBody* psb = btSoftBodyHelpers::CreateFromVtkFile(getDeformableDynamicsWorld()->getWorldInfo(), filename.c_str()); + + // read in eigenmodes, stiffness and mass matrices + unsigned int buffer_n_modes = 0; + + std::string eigenvalues_file("../../../examples/SoftDemo/eigenvalues.bin"); + btSoftBodyHelpers::readBinary(m_eigenvalues, buffer_n_modes, eigenvalues_file.c_str()); + m_numModes = buffer_n_modes; + + std::string Kr_file("../../../examples/SoftDemo/K_r_diag_mat.bin"); + btSoftBodyHelpers::readBinary(m_Kr, buffer_n_modes, Kr_file.c_str()); + + std::string Mr_file("../../../examples/SoftDemo/M_r_diag_mat.bin"); + btSoftBodyHelpers::readBinary(m_Mr, buffer_n_modes, Mr_file.c_str()); + + std::string modes_file("../../../examples/SoftDemo/modes.bin"); + btSoftBodyHelpers::readBinaryMat(m_modes, 3 * psb->m_nodes.size(), buffer_n_modes, modes_file.c_str()); // default to 3D + + getDeformableDynamicsWorld()->addSoftBody(psb); + psb->scale(btVector3(2, 2, 2)); + psb->translate(btVector3(0, 7, 0)); + psb->getCollisionShape()->setMargin(0.1); + psb->setTotalMass(0.5); + 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.collisions = btSoftBody::fCollision::SDF_RD; + psb->m_cfg.collisions |= btSoftBody::fCollision::SDF_RDN; + psb->m_sleepingThreshold = 0; + btSoftBodyHelpers::generateBoundaryFaces(psb); + + psb->setVelocity(btVector3(0, -COLLIDING_VELOCITY, 0)); + + // btDeformableLinearElasticityForce* linearElasticity = new btDeformableLinearElasticityForce(100,100,0.01); + // m_linearElasticity = linearElasticity; + + m_massSpring = new btDeformableMassSpringForce(10.0, 0.0); //TODO: this stiffness needs to match the modes + + getDeformableDynamicsWorld()->addForce(psb, m_massSpring); + m_forces.push_back(m_massSpring); + } + getDeformableDynamicsWorld()->setReducedModelFlag(true); + getDeformableDynamicsWorld()->setImplicit(false); + getDeformableDynamicsWorld()->setLineSearch(false); + getDeformableDynamicsWorld()->setUseProjection(true); + getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.3; + getDeformableDynamicsWorld()->getSolverInfo().m_deformable_maxErrorReduction = btScalar(200); + getDeformableDynamicsWorld()->getSolverInfo().m_leastSquaresResidualThreshold = 1e-3; + getDeformableDynamicsWorld()->getSolverInfo().m_splitImpulse = true; + getDeformableDynamicsWorld()->getSolverInfo().m_numIterations = 100; + // add a few rigid bodies + // Ctor_RbUpStack(); // TODO: no rigid body for now + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); + + // { + // SliderParams slider("Young's Modulus", &E); + // slider.m_minVal = 0; + // slider.m_maxVal = 2000; + // if (m_guiHelper->getParameterInterface()) + // m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + // } + // { + // SliderParams slider("Poisson Ratio", &nu); + // slider.m_minVal = 0.05; + // slider.m_maxVal = 0.49; + // if (m_guiHelper->getParameterInterface()) + // m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + // } + // { + // SliderParams slider("Mass Damping", &damping_alpha); + // slider.m_minVal = 0; + // slider.m_maxVal = 1; + // if (m_guiHelper->getParameterInterface()) + // m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + // } + // { + // SliderParams slider("Stiffness Damping", &damping_beta); + // slider.m_minVal = 0; + // slider.m_maxVal = 0.1; + // if (m_guiHelper->getParameterInterface()) + // m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + // } +} + +void BasicTest::exitPhysics() +{ + //cleanup in the reverse order of creation/initialization + removePickingConstraint(); + //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 forces + for (int j = 0; j < m_forces.size(); j++) + { + btDeformableLagrangianForce* force = m_forces[j]; + delete force; + } + m_forces.clear(); + + //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* ReducedBasicTestCreateFunc(struct CommonExampleOptions& options) +{ + return new BasicTest(options.m_guiHelper); +} + + diff --git a/examples/ReducedDeformableDemo/BasicTest.h b/examples/ReducedDeformableDemo/BasicTest.h new file mode 100644 index 000000000..aa15e5843 --- /dev/null +++ b/examples/ReducedDeformableDemo/BasicTest.h @@ -0,0 +1,19 @@ +/* + Bullet Continuous Collision Detection and Physics Library + 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, + 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 _REDUCED_BASIC_TEST_H +#define _REDUCED_BASIC_TEST_H + +class CommonExampleInterface* ReducedBasicTestCreateFunc(struct CommonExampleOptions& options); + +#endif //_REDUCED_BASIC_TEST_H diff --git a/examples/SoftDemo/K_r_diag_mat.bin b/examples/SoftDemo/K_r_diag_mat.bin new file mode 100644 index 0000000000000000000000000000000000000000..af8b7d78eafda5504669cf18a14959dce1b38983 GIT binary patch literal 100 zcmV-q0Gs~|0000@l~Y+0N{~OVxMzFC50gJXIA-)mouoer#&H~t?yWzY1!{^y?XW+G z;fb5sK)XL@ThRwTalJplLbjT!;K4r|?@!6eIKw}Z+01Dx_r*VgUwSI$+QvVO8=Z`- G8p%JG6E9W( literal 0 HcmV?d00001 diff --git a/examples/SoftDemo/M_r_diag_mat.bin b/examples/SoftDemo/M_r_diag_mat.bin new file mode 100644 index 0000000000000000000000000000000000000000..c1c2e634f2d258a130315df41cbfe89f9ce49583 GIT binary patch literal 100 ucmd;KU|{(39|Ydp1DQbZ!TvXt52k?Pj8O3}P;oF9sO~S6{|}8uHxB^FB|Y%~ literal 0 HcmV?d00001 diff --git a/examples/SoftDemo/eigenvalues.bin b/examples/SoftDemo/eigenvalues.bin new file mode 100644 index 0000000000000000000000000000000000000000..5b82cc8a5d1ed605a7e32dc886357749815301da GIT binary patch literal 100 zcmV-q0Gs~|0001rl~Y+0N{~N?xMzFC50gJnIA-)mouof2#&H~t?yWzT1!{^y?XW+t z;fb5sK)XMcThRwTalJpyLbjT!;K4s8?@!6eIKw}j+01Dx_r*VuUwSI$+QvVS8=Z`- G8p%Jz127=~ literal 0 HcmV?d00001 diff --git a/examples/SoftDemo/mesh.vtk b/examples/SoftDemo/mesh.vtk new file mode 100644 index 000000000..cbab3e1a2 --- /dev/null +++ b/examples/SoftDemo/mesh.vtk @@ -0,0 +1,83 @@ +#vtk DataFile Version 2.0 +I don't think this matters +ASCII +DATASET UNSTRUCTURED_GRID +POINTS 28 double +-0.5000000000000000 -0.2500000000000000 -2.0000000000000000 +-0.5000000000000000 0.2500000000000000 -2.0000000000000000 +0.5000000000000000 -0.2500000000000000 -2.0000000000000000 +0.5000000000000000 0.2500000000000000 -2.0000000000000000 +-0.5000000000000000 -0.2500000000000000 2.0000000000000000 +-0.5000000000000000 0.2500000000000000 2.0000000000000000 +0.5000000000000000 -0.2500000000000000 2.0000000000000000 +0.5000000000000000 0.2500000000000000 2.0000000000000000 +-0.5000000000000000 -0.2500000000000000 1.0000000000000000 +-0.5000000000000000 -0.2500000000000000 0.0000000000000000 +-0.5000000000000000 -0.2500000000000000 -1.0000000000000000 +0.5000000000000000 -0.2500000000000000 -1.0000000000000000 +0.5000000000000000 -0.2500000000000000 0.0000000000000000 +0.5000000000000000 -0.2500000000000000 1.0000000000000000 +-0.5000000000000000 0.2500000000000000 1.0000000000000000 +-0.5000000000000000 0.2500000000000000 0.0000000000000000 +-0.5000000000000000 0.2500000000000000 -1.0000000000000000 +0.5000000000000000 0.2500000000000000 1.0000000000000000 +0.5000000000000000 0.2500000000000000 0.0000000000000000 +0.5000000000000000 0.2500000000000000 -1.0000000000000000 +0.0000000000000000 -0.2500000000000000 -1.5000000000000000 +0.0000000000000000 -0.2500000000000000 -0.5000000000000000 +0.0000000000000000 -0.2500000000000000 0.5000000000000000 +0.0000000000000000 -0.2500000000000000 1.5000000000000000 +0.0000000000000000 0.2500000000000000 1.5000000000000000 +0.0000000000000000 0.2500000000000000 0.5000000000000000 +0.0000000000000000 0.2500000000000000 -0.5000000000000000 +0.0000000000000000 0.2500000000000000 -1.5000000000000000 +CELLS 48 192 +4 22 12 17 13 +4 20 26 21 11 +4 23 8 5 24 +4 11 27 26 19 +4 27 11 26 20 +4 17 22 24 25 +4 7 23 13 6 +4 22 17 24 13 +4 9 25 21 15 +4 24 22 8 14 +4 24 8 22 23 +4 25 9 21 22 +4 23 7 13 24 +4 15 10 16 26 +4 14 25 9 15 +4 25 14 9 22 +4 24 23 22 13 +4 15 10 21 9 +4 15 21 10 26 +4 24 25 22 14 +4 2 11 27 20 +4 7 5 23 6 +4 11 21 12 26 +4 20 1 0 16 +4 18 25 12 17 +4 18 12 25 26 +4 5 7 23 24 +4 26 21 25 15 +4 20 16 27 1 +4 21 25 22 12 +4 20 16 10 26 +4 20 27 16 26 +4 20 10 16 0 +4 11 12 19 26 +4 14 22 8 9 +4 8 23 5 4 +4 24 14 8 5 +4 11 2 27 3 +4 2 27 1 20 +4 12 18 19 26 +4 27 2 1 3 +4 24 13 17 7 +4 20 2 0 1 +4 5 23 6 4 +4 20 10 21 26 +4 12 22 17 25 +4 3 27 11 19 +4 21 26 25 12 +CELL_TYPES 10 diff --git a/examples/SoftDemo/modes.bin b/examples/SoftDemo/modes.bin new file mode 100644 index 0000000000000000000000000000000000000000..b2d19ef74b1668f7f8f1ca349c02c20d4f8107bb GIT binary patch literal 8068 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 vec, unsigned int& size, const char* file) +{ + std::ifstream f_in(file, std::ios::in | std::ios::binary); + // first get size + f_in.read((char*)&size, sizeof(uint32_t)); + + // read data + vec.resize(size); + double temp; + for (int i = 0; i < size; i++) { + f_in.read((char*)&temp, sizeof(double)); + vec[i] = btScalar(temp); + } + f_in.close(); +} + +void btSoftBodyHelpers::readBinaryMat(btAlignedObjectArray >& mat, const unsigned int n_row, const unsigned int n_col, const char* file) +{ + std::ifstream f_in(file, std::ios::in | std::ios::binary); + // first get size + unsigned int v_size; + f_in.read((char*)&v_size, sizeof(uint32_t)); + btAssert(v_size == n_row * n_col); + + // read data + mat.resize(n_col); + for (int i = 0; i < n_col; ++i) + { + mat[i].resize(n_row); + for (int j = 0; j < n_row; ++j) + { + double temp; + f_in.read((char*)&temp, sizeof(double)); + mat[i][j] = btScalar(temp); + } + } + f_in.close(); +} + void btSoftBodyHelpers::duplicateFaces(const char* filename, const btSoftBody* psb) { std::ifstream fs_read; diff --git a/src/BulletSoftBody/btSoftBodyHelpers.h b/src/BulletSoftBody/btSoftBodyHelpers.h index 237d29761..c3a4309cf 100644 --- a/src/BulletSoftBody/btSoftBodyHelpers.h +++ b/src/BulletSoftBody/btSoftBodyHelpers.h @@ -144,6 +144,11 @@ struct btSoftBodyHelpers bool bfacesfromtetras); static btSoftBody* CreateFromVtkFile(btSoftBodyWorldInfo& worldInfo, const char* vtk_file); + // read in a binary vector + static void readBinary(btAlignedObjectArray& vec, unsigned int& size, const char* file); + // read in a binary matrix (must provide matrix size) + static void readBinaryMat(btAlignedObjectArray >& mat, const unsigned int n_row, const unsigned int n_col, const char* file); + static void writeObj(const char* file, const btSoftBody* psb); static void getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, const btVector3& p, btVector4& bary);