123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358 |
- /*
- 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.
- */
- ///btSoftBody implementation by Nathanael Presson
- #include "btBulletDynamicsCommon.h"
- #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
- #include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
- #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
- #include "LinearMath/btQuickprof.h"
- #include "LinearMath/btIDebugDraw.h"
- #include "BunnyMesh.h"
- #include "TorusMesh.h"
- #include <stdio.h> //printf debugging
- #include "LinearMath/btConvexHull.h"
- #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
- #include "BulletSoftBody/btSoftBodyHelpers.h"
- #include "SoftDemo.h"
- #include "GL_ShapeDrawer.h"
- #include "LinearMath/btAlignedObjectArray.h"
- #include "BulletSoftBody/btSoftBody.h"
- class btBroadphaseInterface;
- class btCollisionShape;
- class btOverlappingPairCache;
- class btCollisionDispatcher;
- class btConstraintSolver;
- struct btCollisionAlgorithmCreateFunc;
- class btDefaultCollisionConfiguration;
- ///collisions between two btSoftBody's
- class btSoftSoftCollisionAlgorithm;
- ///collisions between a btSoftBody and a btRigidBody
- class btSoftRididCollisionAlgorithm;
- class btSoftRigidDynamicsWorld;
- #include "../CommonInterfaces/CommonRigidBodyBase.h"
- class SoftDemo : public CommonRigidBodyBase
- {
- public:
- btAlignedObjectArray<btSoftSoftCollisionAlgorithm*> m_SoftSoftCollisionAlgorithms;
- btAlignedObjectArray<btSoftRididCollisionAlgorithm*> m_SoftRigidCollisionAlgorithms;
- btSoftBodyWorldInfo m_softBodyWorldInfo;
-
- bool m_autocam;
- bool m_cutting;
- bool m_raycast;
- btScalar m_animtime;
- btClock m_clock;
- int m_lastmousepos[2];
- btVector3 m_impact;
- btSoftBody::sRayCast m_results;
- btSoftBody::Node* m_node;
- btVector3 m_goal;
- bool m_drag;
- //keep the collision shapes, for deletion/cleanup
- btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
- btBroadphaseInterface* m_broadphase;
- btCollisionDispatcher* m_dispatcher;
- btConstraintSolver* m_solver;
- btCollisionAlgorithmCreateFunc* m_boxBoxCF;
- btDefaultCollisionConfiguration* m_collisionConfiguration;
- public:
- void initPhysics();
- void exitPhysics();
- virtual void resetCamera()
- {
- //@todo depends on current_demo?
- float dist = 45;
- float pitch = 27;
- float yaw = 31;
- float targetPos[3]={10-1,0};
- m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
- }
- SoftDemo(struct GUIHelperInterface* helper)
- : CommonRigidBodyBase(helper),
- m_drag(false)
- {
-
- }
- virtual ~SoftDemo()
- {
- btAssert(m_dynamicsWorld==0);
- }
- //virtual void clientMoveAndDisplay();
- //virtual void displayCallback();
- void createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos );
-
- virtual void setDrawClusters(bool drawClusters);
- virtual const btSoftRigidDynamicsWorld* getSoftDynamicsWorld() const
- {
- ///just make it a btSoftRigidDynamicsWorld please
- ///or we will add type checking
- return (btSoftRigidDynamicsWorld*) m_dynamicsWorld;
- }
- virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld()
- {
- ///just make it a btSoftRigidDynamicsWorld please
- ///or we will add type checking
- return (btSoftRigidDynamicsWorld*) m_dynamicsWorld;
- }
- //
- //void clientResetScene();
- void renderme();
- void keyboardCallback(unsigned char key, int x, int y);
- void mouseFunc(int button, int state, int x, int y);
- void mouseMotionFunc(int x,int y);
- GUIHelperInterface* getGUIHelper()
- {
- return m_guiHelper;
- }
- virtual void renderScene()
- {
- CommonRigidBodyBase::renderScene();
- btSoftRigidDynamicsWorld* softWorld = getSoftDynamicsWorld();
- for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
- {
- btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
- if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
- {
- btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
- btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
- }
- }
- }
- };
- #define MACRO_SOFT_DEMO(a) class SoftDemo##a : public SoftDemo\
- {\
- public:\
- static DemoApplication* Create()\
- {\
- SoftDemo* demo = new SoftDemo##a;\
- extern int current_demo;\
- current_demo=a;\
- demo->initPhysics();\
- return demo;\
- }\
- };
- //MACRO_SOFT_DEMO(0) //Init_Cloth
- #if 0
- MACRO_SOFT_DEMO(1) //Init_Pressure
- MACRO_SOFT_DEMO(2)//Init_Volume
- MACRO_SOFT_DEMO(3)//Init_Ropes
- MACRO_SOFT_DEMO(4)//Init_Ropes_Attach
- MACRO_SOFT_DEMO(5)//Init_ClothAttach
- MACRO_SOFT_DEMO(6)//Init_Sticks
- MACRO_SOFT_DEMO(7)//Init_Collide
- MACRO_SOFT_DEMO(8)//Init_Collide2
- MACRO_SOFT_DEMO(9)//Init_Collide3
- MACRO_SOFT_DEMO(10)//Init_Impact
- MACRO_SOFT_DEMO(11)//Init_Aero
- MACRO_SOFT_DEMO(12)//Init_Friction
- MACRO_SOFT_DEMO(13)//Init_Torus
- MACRO_SOFT_DEMO(14)//Init_TorusMatch
- MACRO_SOFT_DEMO(15)//Init_Bunny
- MACRO_SOFT_DEMO(16)//Init_BunnyMatch
- MACRO_SOFT_DEMO(17)//Init_Cutting1
- MACRO_SOFT_DEMO(18)//Init_ClusterDeform
- MACRO_SOFT_DEMO(19)//Init_ClusterCollide1
- MACRO_SOFT_DEMO(20)//Init_ClusterCollide2
- MACRO_SOFT_DEMO(21)//Init_ClusterSocket
- MACRO_SOFT_DEMO(22)//Init_ClusterHinge
- MACRO_SOFT_DEMO(23)//Init_ClusterCombine
- MACRO_SOFT_DEMO(24)//Init_ClusterCar
- MACRO_SOFT_DEMO(25)//Init_ClusterRobot
- MACRO_SOFT_DEMO(26)//Init_ClusterStackSoft
- MACRO_SOFT_DEMO(27)//Init_ClusterStackMixed
- MACRO_SOFT_DEMO(28)//Init_TetraCube
- MACRO_SOFT_DEMO(29)//Init_TetraBunny
- #endif
- extern float eye[3];
- extern int glutScreenWidth;
- extern int glutScreenHeight;
- static bool sDemoMode = false;
- const int maxProxies = 32766;
- const int maxOverlap = 65535;
- static btVector3* gGroundVertices=0;
- static int* gGroundIndices=0;
- static btBvhTriangleMeshShape* trimeshShape =0;
- static btRigidBody* staticBody = 0;
- static float waveheight = 5.f;
- const float TRIANGLE_SIZE=8.f;
- int current_demo=20;
- #define DEMO_MODE_TIMEOUT 15.f //15 seconds for each demo
- #ifdef _DEBUG
- const int gNumObjects = 1;
- #else
- const int gNumObjects = 1;//try this in release mode: 3000. never go above 16384, unless you increate maxNumObjects value in DemoApplication.cp
- #endif
- const int maxNumObjects = 32760;
- #define CUBE_HALF_EXTENTS 1.5
- #define EXTRA_HEIGHT -10.f
- //
- void SoftDemo::createStack( btCollisionShape* boxShape, float halfCubeSize, int size, float zPos )
- {
- btTransform trans;
- trans.setIdentity();
- for(int i=0; i<size; i++)
- {
- // This constructs a row, from left to right
- int rowSize = size - i;
- for(int j=0; j< rowSize; j++)
- {
- btVector3 pos;
- pos.setValue(
- -rowSize * halfCubeSize + halfCubeSize + j * 2.0f * halfCubeSize,
- halfCubeSize + i * halfCubeSize * 2.0f,
- zPos);
- trans.setOrigin(pos);
- btScalar mass = 1.f;
- btRigidBody* body = 0;
- body = createRigidBody(mass,trans,boxShape);
- }
- }
- }
- ////////////////////////////////////
- extern int gNumManifold;
- extern int gOverlappingPairs;
- ///for mouse picking
- void pickingPreTickCallback (btDynamicsWorld *world, btScalar timeStep)
- {
- SoftDemo* softDemo = (SoftDemo*)world->getWorldUserInfo();
- if(softDemo->m_drag)
- {
- const int x=softDemo->m_lastmousepos[0];
- const int y=softDemo->m_lastmousepos[1];
- float rf[3];
- softDemo->getGUIHelper()->getRenderInterface()->getActiveCamera()->getCameraPosition(rf);
- float target[3];
- softDemo->getGUIHelper()->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(target);
- btVector3 cameraTargetPosition(target[0],target[1],target[2]);
-
- const btVector3 cameraPosition(rf[0],rf[1],rf[2]);
- const btVector3 rayFrom=cameraPosition;
- const btVector3 rayTo=softDemo->getRayTo(x,y);
- const btVector3 rayDir=(rayTo-rayFrom).normalized();
- const btVector3 N=(cameraTargetPosition-cameraPosition).normalized();
- const btScalar O=btDot(softDemo->m_impact,N);
- const btScalar den=btDot(N,rayDir);
- if((den*den)>0)
- {
- const btScalar num=O-btDot(N,rayFrom);
- const btScalar hit=num/den;
- if((hit>0)&&(hit<1500))
- {
- softDemo->m_goal=rayFrom+rayDir*hit;
- }
- }
- btVector3 delta=softDemo->m_goal-softDemo->m_node->m_x;
- static const btScalar maxdrag=10;
- if(delta.length2()>(maxdrag*maxdrag))
- {
- delta=delta.normalized()*maxdrag;
- }
- softDemo->m_node->m_v+=delta/timeStep;
- }
- }
- //
- // ImplicitShape
- //
- //
- struct ImplicitSphere : btSoftBody::ImplicitFn
- {
- btVector3 center;
- btScalar sqradius;
- ImplicitSphere() {}
- ImplicitSphere(const btVector3& c,btScalar r) : center(c),sqradius(r*r) {}
- btScalar Eval(const btVector3& x)
- {
- return((x-center).length2()-sqradius);
- }
- };
- //
- // Tetra meshes
- //
- struct TetraBunny
- {
- #include "bunny.inl"
- };
- struct TetraCube
- {
- #include "cube.inl"
- };
- //
- // Random
- //
- static inline btScalar UnitRand()
- {
- return(rand()/(btScalar)RAND_MAX);
- }
- static inline btScalar SignedUnitRand()
- {
- return(UnitRand()*2-1);
- }
- static inline btVector3 Vector3Rand()
- {
- const btVector3 p=btVector3(SignedUnitRand(),SignedUnitRand(),SignedUnitRand());
- return(p.normalized());
- }
- //
- // Rb rain
- //
- static void Ctor_RbUpStack(SoftDemo* pdemo,int count)
- {
- float mass=10;
- btCompoundShape* cylinderCompound = new btCompoundShape;
- btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(4,1,1));
- btCollisionShape* boxShape = new btBoxShape(btVector3(4,1,1));
- 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[]={cylinderCompound,
- new btBoxShape(btVector3(1,1,1)),
- new btSphereShape(1.5)
-
- };
- 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+6*i,0));
- pdemo->createRigidBody(mass,startTransform,shape[i%nshapes]);
- //pdemo->createRigidBody(mass,startTransform,shape[0]);
- }
- }
- //
- // Big ball
- //
- static void Ctor_BigBall(SoftDemo* pdemo,btScalar mass=10)
- {
- btTransform startTransform;
- startTransform.setIdentity();
- startTransform.setOrigin(btVector3(0,13,0));
- pdemo->createRigidBody(mass,startTransform,new btSphereShape(3));
- }
- //
- // Big plate
- //
- static btRigidBody* Ctor_BigPlate(SoftDemo* pdemo,btScalar mass=15,btScalar height=4)
- {
- btTransform startTransform;
- startTransform.setIdentity();
- startTransform.setOrigin(btVector3(0,height,0.5));
- btRigidBody* body=pdemo->createRigidBody(mass,startTransform,new btBoxShape(btVector3(5,1,5)));
- body->setFriction(1);
- return(body);
- }
- //
- // Linear stair
- //
- static void Ctor_LinearStair(SoftDemo* pdemo,const btVector3& org,const btVector3& sizes,btScalar angle,int count)
- {
- btBoxShape* shape=new btBoxShape(sizes);
- for(int i=0;i<count;++i)
- {
- btTransform startTransform;
- startTransform.setIdentity();
- startTransform.setOrigin(org+btVector3(sizes.x()*i*2,sizes.y()*i*2,0));
- btRigidBody* body=pdemo->createRigidBody(0,startTransform,shape);
- body->setFriction(1);
- }
- }
- //
- // Softbox
- //
- static btSoftBody* Ctor_SoftBox(SoftDemo* pdemo,const btVector3& p,const btVector3& s)
- {
- 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(pdemo->m_softBodyWorldInfo,c,8);
- psb->generateBendingConstraints(2);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- //
- // SoftBoulder
- //
- static btSoftBody* Ctor_SoftBoulder(SoftDemo* pdemo,const btVector3& p,const btVector3& s,int np,int id)
- {
- btAlignedObjectArray<btVector3> pts;
- if(id) srand(id);
- for(int i=0;i<np;++i)
- {
- pts.push_back(Vector3Rand()*s+p);
- }
- btSoftBody* psb=btSoftBodyHelpers::CreateFromConvexHull(pdemo->m_softBodyWorldInfo,&pts[0],pts.size());
- psb->generateBendingConstraints(2);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- //#define TRACEDEMO { pdemo->demoname=__FUNCTION__+5;printf("Launching demo: " __FUNCTION__ "\r\n"); }
- //
- // Basic ropes
- //
- static void Init_Ropes(SoftDemo* pdemo)
- {
- //TRACEDEMO
- const int n=15;
- for(int i=0;i<n;++i)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateRope(pdemo->m_softBodyWorldInfo, btVector3(-10,0,i*0.25),
- btVector3(10,0,i*0.25),
- 16,
- 1+2);
- psb->m_cfg.piterations = 4;
- psb->m_materials[0]->m_kLST = 0.1+(i/(btScalar)(n-1))*0.9;
- psb->setTotalMass(20);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- }
- }
- //
- // Rope attach
- //
- static void Init_RopeAttach(SoftDemo* pdemo)
- {
- //TRACEDEMO
- pdemo->m_softBodyWorldInfo.m_sparsesdf.RemoveReferences(0);
- struct Functors
- {
- static btSoftBody* CtorRope(SoftDemo* pdemo,const btVector3& p)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateRope(pdemo->m_softBodyWorldInfo,p,p+btVector3(10,0,0),8,1);
- psb->setTotalMass(50);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- };
- btTransform startTransform;
- startTransform.setIdentity();
- startTransform.setOrigin(btVector3(12,8,0));
- btRigidBody* body=pdemo->createRigidBody(50,startTransform,new btBoxShape(btVector3(2,6,2)));
- btSoftBody* psb0=Functors::CtorRope(pdemo,btVector3(0,8,-1));
- btSoftBody* psb1=Functors::CtorRope(pdemo,btVector3(0,8,+1));
- psb0->appendAnchor(psb0->m_nodes.size()-1,body);
- psb1->appendAnchor(psb1->m_nodes.size()-1,body);
- }
- //
- // Cloth attach
- //
- static void Init_ClothAttach(SoftDemo* pdemo)
- {
- //TRACEDEMO
- const btScalar s=4;
- const btScalar h=6;
- const int r=9;
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,btVector3(-s,h,-s),
- btVector3(+s,h,-s),
- btVector3(-s,h,+s),
- btVector3(+s,h,+s),r,r,4+8,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- btTransform startTransform;
- startTransform.setIdentity();
- startTransform.setOrigin(btVector3(0,h,-(s+3.5)));
- btRigidBody* body=pdemo->createRigidBody(20,startTransform,new btBoxShape(btVector3(s,1,3)));
- psb->appendAnchor(0,body);
- psb->appendAnchor(r-1,body);
- pdemo->m_cutting=true;
- }
- //
- // Impact
- //
- static void Init_Impact(SoftDemo* pdemo)
- {
- //TRACEDEMO
- btSoftBody* psb=btSoftBodyHelpers::CreateRope(pdemo->m_softBodyWorldInfo, btVector3(0,0,0),
- btVector3(0,-1,0),
- 0,
- 1);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- psb->m_cfg.kCHR=0.5;
- btTransform startTransform;
- startTransform.setIdentity();
- startTransform.setOrigin(btVector3(0,20,0));
- pdemo->createRigidBody(10,startTransform,new btBoxShape(btVector3(2,2,2)));
- }
- static void Init_CapsuleCollision(SoftDemo* pdemo)
- {
- #ifdef USE_AMD_OPENCL
- btAlignedObjectArray<btSoftBody*> emptyArray;
- if (g_openCLSIMDSolver)
- g_openCLSIMDSolver->optimize(emptyArray);
- #endif //USE_AMD_OPENCL
- //TRACEDEMO
- const btScalar s=4;
- const btScalar h=6;
- const int r=20;
- btTransform startTransform;
- startTransform.setIdentity();
- startTransform.setOrigin(btVector3(0,h-2,0));
- btCollisionShape* capsuleShape= new btCapsuleShapeX(1,5);
- capsuleShape->setMargin( 0.5 );
- // capsule->setLocalScaling(btVector3(5,1,1));
- // btRigidBody* body=pdemo->createRigidBody(20,startTransform,capsuleShape);
- btRigidBody* body=pdemo->createRigidBody(0,startTransform,capsuleShape);
- body->setFriction( 0.8f );
- int fixed=0;//4+8;
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,btVector3(-s,h,-s),
- btVector3(+s,h,-s),
- btVector3(-s,h,+s),
- btVector3(+s,h,+s),r,r,fixed,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- psb->setTotalMass(0.1);
- psb->m_cfg.piterations = 10;
- psb->m_cfg.citerations = 10;
- psb->m_cfg.diterations = 10;
- // psb->m_cfg.viterations = 10;
- // psb->appendAnchor(0,body);
- // psb->appendAnchor(r-1,body);
- // pdemo->m_cutting=true;
- }
- //
- // Collide
- //
- static void Init_Collide(SoftDemo* pdemo)
- {
- //TRACEDEMO
- struct Functor
- {
- static btSoftBody* Create(SoftDemo* pdemo,const btVector3& x,const btVector3& a)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices,
- &gIndices[0][0],
- NUM_TRIANGLES);
- psb->generateBendingConstraints(2);
- psb->m_cfg.piterations=2;
- psb->m_cfg.collisions|=btSoftBody::fCollision::VF_SS;
- psb->randomizeConstraints();
- btMatrix3x3 m;
- m.setEulerZYX(a.x(),a.y(),a.z());
- psb->transform(btTransform(m,x));
- psb->scale(btVector3(2,2,2));
- psb->setTotalMass(50,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- };
- for(int i=0;i<3;++i)
- {
- Functor::Create(pdemo,btVector3(3*i,2,0),btVector3(SIMD_PI/2*(1-(i&1)),SIMD_PI/2*(i&1),0));
- }
- pdemo->m_cutting=true;
- }
- //
- // Collide2
- //
- static void Init_Collide2(SoftDemo* pdemo)
- {
- //TRACEDEMO
- struct Functor
- {
- static btSoftBody* Create(SoftDemo* pdemo,const btVector3& x,const btVector3& a)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,
- &gIndicesBunny[0][0],
- BUNNY_NUM_TRIANGLES);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_kLST = 0.5;
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
- psb->m_cfg.piterations = 2;
- psb->m_cfg.kDF = 0.5;
- psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
- psb->randomizeConstraints();
- btMatrix3x3 m;
- m.setEulerZYX(a.x(),a.y(),a.z());
- psb->transform(btTransform(m,x));
- psb->scale(btVector3(6,6,6));
- psb->setTotalMass(100,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- };
- for(int i=0;i<3;++i)
- {
- Functor::Create(pdemo,btVector3(0,-1+5*i,0),btVector3(0,SIMD_PI/2*(i&1),0));
- }
- pdemo->m_cutting=true;
- }
- //
- // Collide3
- //
- static void Init_Collide3(SoftDemo* pdemo)
- {
- //TRACEDEMO
- {
- const btScalar s=8;
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,btVector3(-s,0,-s),
- btVector3(+s,0,-s),
- btVector3(-s,0,+s),
- btVector3(+s,0,+s),
- 15,15,1+2+4+8,true);
- psb->m_materials[0]->m_kLST = 0.4;
- psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
- psb->setTotalMass(150);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- }
- {
- const btScalar s=4;
- const btVector3 o=btVector3(5,10,0);
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,
- btVector3(-s,0,-s)+o,
- btVector3(+s,0,-s)+o,
- btVector3(-s,0,+s)+o,
- btVector3(+s,0,+s)+o,
- 7,7,0,true);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_kLST = 0.1;
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
- psb->m_materials[0]->m_kLST = 0.5;
- psb->m_cfg.collisions |= btSoftBody::fCollision::VF_SS;
- psb->setTotalMass(150);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- pdemo->m_cutting=true;
- }
- }
- //
- // Aerodynamic forces, 50x1g flyers
- //
- static void Init_Aero(SoftDemo* pdemo)
- {
- //TRACEDEMO
- const btScalar s=2;
- const btScalar h=10;
- const int segments=6;
- const int count=50;
- for(int i=0;i<count;++i)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,btVector3(-s,h,-s),
- btVector3(+s,h,-s),
- btVector3(-s,h,+s),
- btVector3(+s,h,+s),
- segments,segments,
- 0,true);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
- psb->m_cfg.kLF = 0.004;
- psb->m_cfg.kDG = 0.0003;
- psb->m_cfg.aeromodel = btSoftBody::eAeroModel::V_TwoSided;
- btTransform trs;
- btQuaternion rot;
- btVector3 ra=Vector3Rand()*0.1;
- btVector3 rp=Vector3Rand()*15+btVector3(0,20,80);
- rot.setEuler(SIMD_PI/8+ra.x(),-SIMD_PI/7+ra.y(),ra.z());
- trs.setIdentity();
- trs.setOrigin(rp);
- trs.setRotation(rot);
- psb->transform(trs);
- psb->setTotalMass(0.1);
- psb->addForce(btVector3(0,2,0),0);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- }
- pdemo->m_autocam=true;
- }
- static void Init_Aero2(SoftDemo* pdemo)
- {
- //TRACEDEMO
- const btScalar s=5;
- //psb->getWorldInfo()->m_gravity.setValue(0,0,0);
- const int segments=10;
- const int count=5;
- btVector3 pos(-s*segments, 0, 0);
- btScalar gap = 0.5;
-
- for(int i=0;i<count;++i)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,btVector3(-s,0,-s*3),
- btVector3(+s,0,-s*3),
- btVector3(-s,0,+s),
- btVector3(+s,0,+s),
- segments,segments*3,
- 1+2,true);
-
- psb->getCollisionShape()->setMargin(0.5);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_kLST = 0.0004;
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
-
- psb->m_cfg.kLF = 0.05;
- psb->m_cfg.kDG = 0.01;
- //psb->m_cfg.kLF = 0.004;
- //psb->m_cfg.kDG = 0.0003;
- psb->m_cfg.piterations = 2;
- psb->m_cfg.aeromodel = btSoftBody::eAeroModel::V_TwoSidedLiftDrag;
-
- psb->setWindVelocity(btVector3(4, -12.0, -25.0));
- btTransform trs;
- btQuaternion rot;
- pos += btVector3(s*2 + gap, 0, 0);
- rot.setRotation(btVector3(1, 0, 0), btScalar(SIMD_PI/2));
- trs.setIdentity();
- trs.setOrigin(pos);
- trs.setRotation(rot);
- psb->transform(trs);
- psb->setTotalMass(2.0);
-
-
- //this could help performance in some cases
- btSoftBodyHelpers::ReoptimizeLinkOrder(psb);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- }
- pdemo->m_autocam=true;
- }
- //
- // Friction
- //
- static void Init_Friction(SoftDemo* pdemo)
- {
- //TRACEDEMO
- const btScalar bs=2;
- const btScalar ts=bs+bs/4;
- for(int i=0,ni=20;i<ni;++i)
- {
- const btVector3 p(-ni*ts/2+i*ts,-10+bs,40);
- btSoftBody* psb=Ctor_SoftBox(pdemo,p,btVector3(bs,bs,bs));
- psb->m_cfg.kDF = 0.1 * ((i+1)/(btScalar)ni);
- psb->addVelocity(btVector3(0,0,-10));
- }
- }
- //
- // Pressure
- //
- static void Init_Pressure(SoftDemo* pdemo)
- {
- //TRACEDEMO
- btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0),
- btVector3(1,1,1)*3,
- 512);
- psb->m_materials[0]->m_kLST = 0.1;
- psb->m_cfg.kDF = 1;
- psb->m_cfg.kDP = 0.001; // fun factor...
- psb->m_cfg.kPR = 2500;
- psb->setTotalMass(30,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- Ctor_BigPlate(pdemo);
- Ctor_LinearStair(pdemo,btVector3(0,0,0),btVector3(2,1,5),0,10);
- pdemo->m_autocam=true;
- }
- //
- // Volume conservation
- //
- static void Init_Volume(SoftDemo* pdemo)
- {
- //TRACEDEMO
- btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,btVector3(35,25,0),
- btVector3(1,1,1)*3,
- 512);
- psb->m_materials[0]->m_kLST = 0.45;
- psb->m_cfg.kVC = 20;
- psb->setTotalMass(50,true);
- psb->setPose(true,false);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- Ctor_BigPlate(pdemo);
- Ctor_LinearStair(pdemo,btVector3(0,0,0),btVector3(2,1,5),0,10);
- pdemo->m_autocam=true;
- }
- //
- // Stick+Bending+Rb's
- //
- static void Init_Sticks(SoftDemo* pdemo)
- {
- //TRACEDEMO
- const int n=16;
- const int sg=4;
- const btScalar sz=5;
- const btScalar hg=4;
- const btScalar in=1/(btScalar)(n-1);
- for(int y=0;y<n;++y)
- {
- for(int x=0;x<n;++x)
- {
- const btVector3 org(-sz+sz*2*x*in,
- -10,
- -sz+sz*2*y*in);
- btSoftBody* psb=btSoftBodyHelpers::CreateRope( pdemo->m_softBodyWorldInfo, org,
- org+btVector3(hg*0.001,hg,0),
- sg,
- 1);
- psb->m_cfg.kDP = 0.005;
- psb->m_cfg.kCHR = 0.1;
- for(int i=0;i<3;++i)
- {
- psb->generateBendingConstraints(2+i);
- }
- psb->setMass(1,0);
- psb->setTotalMass(0.01);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- }
- }
- Ctor_BigBall(pdemo);
- }
- //
- // Bending
- //
- static void Init_Bending(SoftDemo* pdemo)
- {
- //TRACEDEMO
- const btScalar s=4;
- const btVector3 x[]={ btVector3(-s,0,-s),
- btVector3(+s,0,-s),
- btVector3(+s,0,+s),
- btVector3(-s,0,+s)};
- const btScalar m[]={ 0,0,0,1};
- btSoftBody* psb=new btSoftBody(&pdemo->m_softBodyWorldInfo,4,x,m);
- psb->appendLink(0,1);
- psb->appendLink(1,2);
- psb->appendLink(2,3);
- psb->appendLink(3,0);
- psb->appendLink(0,2);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- }
- //
- // 100kg cloth locked at corners, 10 falling 10kg rb's.
- //
- static void Init_Cloth(SoftDemo* pdemo)
- {
- //TRACEDEMO
- const btScalar s=8;
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,btVector3(-s,0,-s),
- btVector3(+s,0,-s),
- btVector3(-s,0,+s),
- btVector3(+s,0,+s),
- 31,31,
- // 31,31,
- 1+2+4+8,true);
-
- psb->getCollisionShape()->setMargin(0.5);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_kLST = 0.4;
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
- psb->setTotalMass(150);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- Ctor_RbUpStack(pdemo,10);
- pdemo->m_cutting=true;
- }
- //
- // 100kg Stanford's bunny
- //
- static void Init_Bunny(SoftDemo* pdemo)
- {
- //TRACEDEMO
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,
- &gIndicesBunny[0][0],
- BUNNY_NUM_TRIANGLES);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_kLST = 0.5;
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
- psb->m_cfg.piterations = 2;
- psb->m_cfg.kDF = 0.5;
- psb->randomizeConstraints();
- psb->scale(btVector3(6,6,6));
- psb->setTotalMass(100,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- pdemo->m_cutting=true;
- }
- //
- // 100kg Stanford's bunny with pose matching
- //
- static void Init_BunnyMatch(SoftDemo* pdemo)
- {
- //TRACEDEMO
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo, gVerticesBunny,
- &gIndicesBunny[0][0],
- BUNNY_NUM_TRIANGLES);
- psb->m_cfg.kDF = 0.5;
- psb->m_cfg.kMT = 0.05;
- psb->m_cfg.piterations = 5;
- psb->randomizeConstraints();
- psb->scale(btVector3(6,6,6));
- psb->setTotalMass(100,true);
- psb->setPose(false,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- }
- //
- // 50Kg Torus
- //
- static void Init_Torus(SoftDemo* pdemo)
- {
- //TRACEDEMO
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh( pdemo->m_softBodyWorldInfo, gVertices,
- &gIndices[0][0],
- NUM_TRIANGLES);
- psb->generateBendingConstraints(2);
- psb->m_cfg.piterations=2;
- psb->randomizeConstraints();
- btMatrix3x3 m;
- m.setEulerZYX(SIMD_PI/2,0,0);
- psb->transform(btTransform(m,btVector3(0,4,0)));
- psb->scale(btVector3(2,2,2));
- psb->setTotalMass(50,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- pdemo->m_cutting=true;
-
- }
- //
- // 50Kg Torus with pose matching
- //
- static void Init_TorusMatch(SoftDemo* pdemo)
- {
- //TRACEDEMO
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo, gVertices,
- &gIndices[0][0],
- NUM_TRIANGLES);
- psb->m_materials[0]->m_kLST = 0.1;
- psb->m_cfg.kMT = 0.05;
- psb->randomizeConstraints();
- btMatrix3x3 m;
- m.setEulerZYX(SIMD_PI/2,0,0);
- psb->transform(btTransform(m,btVector3(0,4,0)));
- psb->scale(btVector3(2,2,2));
- psb->setTotalMass(50,true);
- psb->setPose(false,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- }
- //
- // Cutting1
- //
- static void Init_Cutting1(SoftDemo* pdemo)
- {
- const btScalar s=6;
- const btScalar h=2;
- const int r=16;
- const btVector3 p[]={ btVector3(+s,h,-s),
- btVector3(-s,h,-s),
- btVector3(+s,h,+s),
- btVector3(-s,h,+s)};
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch(pdemo->m_softBodyWorldInfo,p[0],p[1],p[2],p[3],r,r,1+2+4+8,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- psb->m_cfg.piterations=1;
- pdemo->m_cutting=true;
- }
- //
- // Clusters
- //
- //
- static void Ctor_Gear(SoftDemo* pdemo,const btVector3& pos,btScalar speed)
- {
- btTransform startTransform;
- startTransform.setIdentity();
- startTransform.setOrigin(pos);
- btCompoundShape* shape=new btCompoundShape();
- #if 1
- shape->addChildShape(btTransform(btQuaternion(0,0,0)),new btBoxShape(btVector3(5,1,6)));
- shape->addChildShape(btTransform(btQuaternion(0,0,SIMD_HALF_PI)),new btBoxShape(btVector3(5,1,6)));
- #else
- shape->addChildShape(btTransform(btQuaternion(0,0,0)),new btCylinderShapeZ(btVector3(5,1,7)));
- shape->addChildShape(btTransform(btQuaternion(0,0,SIMD_HALF_PI)),new btBoxShape(btVector3(4,1,8)));
- #endif
- btRigidBody* body=pdemo->createRigidBody(10,startTransform,shape);
- body->setFriction(1);
- btDynamicsWorld* world=pdemo->getDynamicsWorld();
- btHingeConstraint* hinge=new btHingeConstraint(*body,btTransform::getIdentity());
- if(speed!=0) hinge->enableAngularMotor(true,speed,3);
- world->addConstraint(hinge);
- }
- //
- static btSoftBody* Ctor_ClusterBunny(SoftDemo* pdemo,const btVector3& x,const btVector3& a)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVerticesBunny,&gIndicesBunny[0][0],BUNNY_NUM_TRIANGLES);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_kLST = 1;
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
- psb->m_cfg.piterations = 2;
- psb->m_cfg.kDF = 1;
- psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+
- btSoftBody::fCollision::CL_RS;
- psb->randomizeConstraints();
- btMatrix3x3 m;
- m.setEulerZYX(a.x(),a.y(),a.z());
- psb->transform(btTransform(m,x));
- psb->scale(btVector3(8,8,8));
- psb->setTotalMass(150,true);
- psb->generateClusters(1);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- //
- static btSoftBody* Ctor_ClusterTorus(SoftDemo* pdemo,const btVector3& x,const btVector3& a,const btVector3& s=btVector3(2,2,2))
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices,&gIndices[0][0],NUM_TRIANGLES);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_kLST = 1;
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
- psb->m_cfg.piterations = 2;
- psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+
- btSoftBody::fCollision::CL_RS;
- psb->randomizeConstraints();
- psb->scale(s);
- psb->rotate(btQuaternion(a[0],a[1],a[2]));
- psb->translate(x);
- psb->setTotalMass(50,true);
- psb->generateClusters(64);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- //
- static struct MotorControl : btSoftBody::AJoint::IControl
- {
- MotorControl()
- {
- goal=0;
- maxtorque=0;
- }
- btScalar Speed(btSoftBody::AJoint*,btScalar current)
- {
- return(current+btMin(maxtorque,btMax(-maxtorque,goal-current)));
- }
- btScalar goal;
- btScalar maxtorque;
- } motorcontrol;
- //
- struct SteerControl : btSoftBody::AJoint::IControl
- {
- SteerControl(btScalar s)
- {
- angle=0;
- sign=s;
- }
- void Prepare(btSoftBody::AJoint* joint)
- {
- joint->m_refs[0][0]=btCos(angle*sign);
- joint->m_refs[0][2]=btSin(angle*sign);
- }
- btScalar Speed(btSoftBody::AJoint* joint,btScalar current)
- {
- return(motorcontrol.Speed(joint,current));
- }
- btScalar angle;
- btScalar sign;
- };
- static SteerControl steercontrol_f(+1);
- static SteerControl steercontrol_r(-1);
- //
- static void Init_ClusterDeform(SoftDemo* pdemo)
- {
- btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,0,0),btVector3(SIMD_PI/2,0,SIMD_HALF_PI));
- psb->generateClusters(8);
- psb->m_cfg.kDF=1;
- }
- //
- static void Init_ClusterCollide1(SoftDemo* pdemo)
- {
- const btScalar s=8;
- btSoftBody* psb=btSoftBodyHelpers::CreatePatch( pdemo->m_softBodyWorldInfo,btVector3(-s,0,-s),
- btVector3(+s,0,-s),
- btVector3(-s,0,+s),
- btVector3(+s,0,+s),
- 17,17,//9,9,//31,31,
- 1+2+4+8,
- true);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_kLST = 0.4;
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->m_cfg.kDF = 1;
- psb->m_cfg.kSRHR_CL = 1;
- psb->m_cfg.kSR_SPLT_CL = 0;
- psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+
-
- btSoftBody::fCollision::CL_RS;
- psb->generateBendingConstraints(2,pm);
-
- psb->getCollisionShape()->setMargin(0.05);
- psb->setTotalMass(50);
-
- ///pass zero in generateClusters to create cluster for each tetrahedron or triangle
- psb->generateClusters(0);
- //psb->generateClusters(64);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- Ctor_RbUpStack(pdemo,10);
- }
- //
- static void Init_ClusterCollide2(SoftDemo* pdemo)
- {
- struct Functor
- {
- static btSoftBody* Create(SoftDemo* pdemo,const btVector3& x,const btVector3& a)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTriMesh(pdemo->m_softBodyWorldInfo,gVertices,
- &gIndices[0][0],
- NUM_TRIANGLES);
- btSoftBody::Material* pm=psb->appendMaterial();
- pm->m_flags -= btSoftBody::fMaterial::DebugDraw;
- psb->generateBendingConstraints(2,pm);
- psb->m_cfg.piterations=2;
- psb->m_cfg.kDF =1;
- psb->m_cfg.kSSHR_CL =1;
- psb->m_cfg.kSS_SPLT_CL =0;
- psb->m_cfg.kSKHR_CL =0.1f;
- psb->m_cfg.kSK_SPLT_CL =1;
- psb->m_cfg.collisions= btSoftBody::fCollision::CL_SS+
- btSoftBody::fCollision::CL_RS;
- psb->randomizeConstraints();
- btMatrix3x3 m;
- m.setEulerZYX(a.x(),a.y(),a.z());
- psb->transform(btTransform(m,x));
- psb->scale(btVector3(2,2,2));
- psb->setTotalMass(50,true);
- psb->generateClusters(16);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- };
- for(int i=0;i<3;++i)
- {
- Functor::Create(pdemo,btVector3(3*i,2,0),btVector3(SIMD_PI/2*(1-(i&1)),SIMD_PI/2*(i&1),0));
- }
- }
- //
- static void Init_ClusterSocket(SoftDemo* pdemo)
- {
- btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,0,0),btVector3(SIMD_PI/2,0,SIMD_HALF_PI));
- btRigidBody* prb=Ctor_BigPlate(pdemo,50,8);
- psb->m_cfg.kDF=1;
- btSoftBody::LJoint::Specs lj;
- lj.position = btVector3(0,5,0);
- psb->appendLinearJoint(lj,prb);
- }
- //
- static void Init_ClusterHinge(SoftDemo* pdemo)
- {
- btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,0,0),btVector3(SIMD_PI/2,0,SIMD_HALF_PI));
- btRigidBody* prb=Ctor_BigPlate(pdemo,50,8);
- psb->m_cfg.kDF=1;
- btSoftBody::AJoint::Specs aj;
- aj.axis = btVector3(0,0,1);
- psb->appendAngularJoint(aj,prb);
- }
- //
- static void Init_ClusterCombine(SoftDemo* pdemo)
- {
- const btVector3 sz(2,4,2);
- btSoftBody* psb0=Ctor_ClusterTorus(pdemo,btVector3(0,8,0),btVector3(SIMD_PI/2,0,SIMD_HALF_PI),sz);
- btSoftBody* psb1=Ctor_ClusterTorus(pdemo,btVector3(0,8,10),btVector3(SIMD_PI/2,0,SIMD_HALF_PI),sz);
- btSoftBody* psbs[]={psb0,psb1};
- for(int j=0;j<2;++j)
- {
- psbs[j]->m_cfg.kDF=1;
- psbs[j]->m_cfg.kDP=0;
- psbs[j]->m_cfg.piterations=1;
- psbs[j]->m_clusters[0]->m_matching = 0.05;
- psbs[j]->m_clusters[0]->m_ndamping = 0.05;
- }
- btSoftBody::AJoint::Specs aj;
- aj.axis = btVector3(0,0,1);
- aj.icontrol = &motorcontrol;
- psb0->appendAngularJoint(aj,psb1);
- btSoftBody::LJoint::Specs lj;
- lj.position = btVector3(0,8,5);
- psb0->appendLinearJoint(lj,psb1);
- }
- //
- static void Init_ClusterCar(SoftDemo* pdemo)
- {
- // pdemo->setAzi(180);
- const btVector3 origin(100,80,0);
- const btQuaternion orientation(-SIMD_PI/2,0,0);
- const btScalar widthf=8;
- const btScalar widthr=9;
- const btScalar length=8;
- const btScalar height=4;
- const btVector3 wheels[]= {
- btVector3(+widthf,-height,+length), // Front left
- btVector3(-widthf,-height,+length), // Front right
- btVector3(+widthr,-height,-length), // Rear left
- btVector3(-widthr,-height,-length), // Rear right
- };
- btSoftBody* pa=Ctor_ClusterBunny(pdemo,btVector3(0,0,0),btVector3(0,0,0));
- btSoftBody* pfl=Ctor_ClusterTorus(pdemo,wheels[0],btVector3(0,0,SIMD_HALF_PI),btVector3(2,4,2));
- btSoftBody* pfr=Ctor_ClusterTorus(pdemo,wheels[1],btVector3(0,0,SIMD_HALF_PI),btVector3(2,4,2));
- btSoftBody* prl=Ctor_ClusterTorus(pdemo,wheels[2],btVector3(0,0,SIMD_HALF_PI),btVector3(2,5,2));
- btSoftBody* prr=Ctor_ClusterTorus(pdemo,wheels[3],btVector3(0,0,SIMD_HALF_PI),btVector3(2,5,2));
- pfl->m_cfg.kDF =
- pfr->m_cfg.kDF =
- prl->m_cfg.kDF =
- prr->m_cfg.kDF = 1;
- btSoftBody::LJoint::Specs lspecs;
- lspecs.cfm = 1;
- lspecs.erp = 1;
- lspecs.position = btVector3(0,0,0);
- lspecs.position=wheels[0];pa->appendLinearJoint(lspecs,pfl);
- lspecs.position=wheels[1];pa->appendLinearJoint(lspecs,pfr);
- lspecs.position=wheels[2];pa->appendLinearJoint(lspecs,prl);
- lspecs.position=wheels[3];pa->appendLinearJoint(lspecs,prr);
- btSoftBody::AJoint::Specs aspecs;
- aspecs.cfm = 1;
- aspecs.erp = 1;
- aspecs.axis = btVector3(1,0,0);
- aspecs.icontrol = &steercontrol_f;
- pa->appendAngularJoint(aspecs,pfl);
- pa->appendAngularJoint(aspecs,pfr);
- aspecs.icontrol = &motorcontrol;
- pa->appendAngularJoint(aspecs,prl);
- pa->appendAngularJoint(aspecs,prr);
- pa->rotate(orientation);
- pfl->rotate(orientation);
- pfr->rotate(orientation);
- prl->rotate(orientation);
- prr->rotate(orientation);
- pa->translate(origin);
- pfl->translate(origin);
- pfr->translate(origin);
- prl->translate(origin);
- prr->translate(origin);
- pfl->m_cfg.piterations =
- pfr->m_cfg.piterations =
- prl->m_cfg.piterations =
- prr->m_cfg.piterations = 1;
- pfl->m_clusters[0]->m_matching =
- pfr->m_clusters[0]->m_matching =
- prl->m_clusters[0]->m_matching =
- prr->m_clusters[0]->m_matching = 0.05;
- pfl->m_clusters[0]->m_ndamping =
- pfr->m_clusters[0]->m_ndamping =
- prl->m_clusters[0]->m_ndamping =
- prr->m_clusters[0]->m_ndamping = 0.05;
- Ctor_LinearStair(pdemo,btVector3(0,-8,0),btVector3(3,2,40),0,20);
- Ctor_RbUpStack(pdemo,50);
- pdemo->m_autocam=true;
- }
- //
- static void Init_ClusterRobot(SoftDemo* pdemo)
- {
- struct Functor
- {
- static btSoftBody* CreateBall(SoftDemo* pdemo,const btVector3& pos)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateEllipsoid(pdemo->m_softBodyWorldInfo,pos,btVector3(1,1,1)*3,512);
- psb->m_materials[0]->m_kLST = 0.45;
- psb->m_cfg.kVC = 20;
- psb->setTotalMass(50,true);
- psb->setPose(true,false);
- psb->generateClusters(1);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- return(psb);
- }
- };
- const btVector3 base=btVector3(0,25,8);
- btSoftBody* psb0=Functor::CreateBall(pdemo,base+btVector3(-8,0,0));
- btSoftBody* psb1=Functor::CreateBall(pdemo,base+btVector3(+8,0,0));
- btSoftBody* psb2=Functor::CreateBall(pdemo,base+btVector3(0,0,+8*btSqrt(2)));
- const btVector3 ctr=(psb0->clusterCom(0)+psb1->clusterCom(0)+psb2->clusterCom(0))/3;
- btCylinderShape* pshp=new btCylinderShape(btVector3(8,1,8));
- btRigidBody* prb=pdemo->createRigidBody(50,btTransform(btQuaternion(0,0,0),ctr+btVector3(0,5,0)),pshp);
- btSoftBody::LJoint::Specs ls;
- ls.erp=0.5f;
- ls.position=psb0->clusterCom(0);psb0->appendLinearJoint(ls,prb);
- ls.position=psb1->clusterCom(0);psb1->appendLinearJoint(ls,prb);
- ls.position=psb2->clusterCom(0);psb2->appendLinearJoint(ls,prb);
- btBoxShape* pbox=new btBoxShape(btVector3(20,1,40));
- btRigidBody* pgrn=pdemo->createRigidBody(0,btTransform(btQuaternion(0,-SIMD_HALF_PI/2,0),btVector3(0,0,0)),pbox);
- pdemo->m_autocam=true;
- }
- //
- static void Init_ClusterStackSoft(SoftDemo* pdemo)
- {
- for(int i=0;i<10;++i)
- {
- btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,-9+8.25*i,0),btVector3(0,0,0));
- psb->m_cfg.kDF=1;
- }
- }
- //
- static void Init_ClusterStackMixed(SoftDemo* pdemo)
- {
- for(int i=0;i<10;++i)
- {
- if((i+1)&1)
- {
- Ctor_BigPlate(pdemo,50,-9+4.25*i);
- }
- else
- {
- btSoftBody* psb=Ctor_ClusterTorus(pdemo,btVector3(0,-9+4.25*i,0),btVector3(0,0,0));
- psb->m_cfg.kDF=1;
- }
- }
- }
- //
- // TetraBunny
- //
- static void Init_TetraBunny(SoftDemo* pdemo)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenData(pdemo->m_softBodyWorldInfo,
- TetraBunny::getElements(),
- 0,
- TetraBunny::getNodes(),
- false,true,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- psb->rotate(btQuaternion(SIMD_PI/2,0,0));
- psb->setVolumeMass(150);
- psb->m_cfg.piterations=2;
- //psb->m_cfg.piterations=1;
- pdemo->m_cutting=false;
- //psb->getCollisionShape()->setMargin(0.01);
- psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS
- //+ btSoftBody::fCollision::CL_SELF
- ;
- ///pass zero in generateClusters to create cluster for each tetrahedron or triangle
- psb->generateClusters(0);
- //psb->m_materials[0]->m_kLST=.2;
- psb->m_cfg.kDF = 10. ;
-
- }
- //
- // TetraCube
- //
- static void Init_TetraCube(SoftDemo* pdemo)
- {
- btSoftBody* psb=btSoftBodyHelpers::CreateFromTetGenData(pdemo->m_softBodyWorldInfo,
- TetraCube::getElements(),
- 0,
- TetraCube::getNodes(),
- false,true,true);
- pdemo->getSoftDynamicsWorld()->addSoftBody(psb);
- psb->scale(btVector3(4,4,4));
- psb->translate(btVector3(0,5,0));
- psb->setVolumeMass(300);
-
-
- ///fix one vertex
- //psb->setMass(0,0);
- //psb->setMass(10,0);
- //psb->setMass(20,0);
- psb->m_cfg.piterations=1;
- //psb->generateClusters(128);
- psb->generateClusters(16);
- //psb->getCollisionShape()->setMargin(0.5);
- psb->getCollisionShape()->setMargin(0.01);
- psb->m_cfg.collisions = btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS
- //+ btSoftBody::fCollision::CL_SELF
- ;
- psb->m_materials[0]->m_kLST=0.8;
- pdemo->m_cutting=false;
- }
- /* Init */
- void (*demofncs[])(SoftDemo*)=
- {
- Init_Cloth,
- Init_Pressure,
- Init_Volume,
- Init_Ropes,
- Init_RopeAttach,
- Init_ClothAttach,
- Init_Sticks,
- Init_CapsuleCollision,
- Init_Collide,
- Init_Collide2,
- Init_Collide3,
- Init_Impact,
- Init_Aero,
- Init_Aero2,
- Init_Friction,
- Init_Torus,
- Init_TorusMatch,
- Init_Bunny,
- Init_BunnyMatch,
- Init_Cutting1,
- Init_ClusterDeform,
- Init_ClusterCollide1,
- Init_ClusterCollide2,
- Init_ClusterSocket,
- Init_ClusterHinge,
- Init_ClusterCombine,
- Init_ClusterCar,
- Init_ClusterRobot,
- Init_ClusterStackSoft,
- Init_ClusterStackMixed,
- Init_TetraCube,
- Init_TetraBunny,
- };
- #if 0
- void SoftDemo::clientResetScene()
- {
- m_azi = 0;
- m_cameraDistance = 30.f;
- m_cameraTargetPosition.setValue(0,0,0);
-
- /* Clean up */
- for(int 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();
- }
- while(m_dynamicsWorld->getNumConstraints())
- {
- btTypedConstraint* pc=m_dynamicsWorld->getConstraint(0);
- m_dynamicsWorld->removeConstraint(pc);
- delete pc;
- }
- btSoftBody* softBody = btSoftBody::upcast(obj);
- if (softBody)
- {
- getSoftDynamicsWorld()->removeSoftBody(softBody);
- } else
- {
- btRigidBody* body = btRigidBody::upcast(obj);
- if (body)
- m_dynamicsWorld->removeRigidBody(body);
- else
- m_dynamicsWorld->removeCollisionObject(obj);
- }
- delete obj;
- }
-
- }
- #if 0
- void SoftDemo::clientMoveAndDisplay()
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
- float ms = getDeltaTimeMicroseconds();
- float dt = ms / 1000000.f;//1.0/60.;
- if (m_dynamicsWorld)
- {
-
- if (sDemoMode)
- {
- static float demoCounter = DEMO_MODE_TIMEOUT;
- demoCounter-= dt;
- if (demoCounter<0)
- {
-
- demoCounter=DEMO_MODE_TIMEOUT;
- current_demo++;
- current_demo=current_demo%(sizeof(demofncs)/sizeof(demofncs[0]));
- clientResetScene();
- }
- }
-
- //#define FIXED_STEP
- #ifdef FIXED_STEP
- m_dynamicsWorld->stepSimulation(dt=1.0f/60.f,0);
- #else
- //during idle mode, just run 1 simulation step maximum, otherwise 4 at max
- // int maxSimSubSteps = m_idle ? 1 : 4;
- //if (m_idle)
- // dt = 1.0/420.f;
- int numSimSteps;
- numSimSteps = m_dynamicsWorld->stepSimulation(dt);
- //numSimSteps = m_dynamicsWorld->stepSimulation(dt,10,1./240.f);
- #ifdef VERBOSE_TIMESTEPPING_CONSOLEOUTPUT
- if (!numSimSteps)
- printf("Interpolated transforms\n");
- else
- {
- if (numSimSteps > maxSimSubSteps)
- {
- //detect dropping frames
- printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps);
- } else
- {
- printf("Simulated (%i) steps\n",numSimSteps);
- }
- }
- #endif //VERBOSE_TIMESTEPPING_CONSOLEOUTPUT
- #endif
- #ifdef USE_AMD_OPENCL
- if (g_openCLSIMDSolver)
- g_openCLSIMDSolver->copyBackToSoftBodies();
- #endif //USE_AMD_OPENCL
- if(m_drag)
- {
- m_node->m_v*=0;
- }
- m_softBodyWorldInfo.m_sparsesdf.GarbageCollect();
- //optional but useful: debug drawing
- }
- #ifdef USE_QUICKPROF
- btProfiler::beginBlock("render");
- #endif //USE_QUICKPROF
- renderme();
- //render the graphics objects, with center of mass shift
- updateCamera();
- #ifdef USE_QUICKPROF
- btProfiler::endBlock("render");
- #endif
- glFlush();
- //some additional debugging info
- #ifdef PRINT_CONTACT_STATISTICS
- printf("num manifolds: %i\n",gNumManifold);
- printf("num gOverlappingPairs: %i\n",gOverlappingPairs);
-
- #endif //PRINT_CONTACT_STATISTICS
- swapBuffers();
- }
- #endif
- #if 0
- void SoftDemo::renderme()
- {
- btIDebugDraw* idraw=m_dynamicsWorld->getDebugDrawer();
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_LIGHTING);
- m_dynamicsWorld->debugDrawWorld();
- //int debugMode = m_dynamicsWorld->getDebugDrawer()? m_dynamicsWorld->getDebugDrawer()->getDebugMode() : -1;
- btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
- //btIDebugDraw* sdraw = softWorld ->getDebugDrawer();
- for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
- {
- btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
- if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
- {
- btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
- btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
- }
- }
- /* Bodies */
- btVector3 ps(0,0,0);
- int nps=0;
- btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray();
- for(int ib=0;ib<sbs.size();++ib)
- {
- btSoftBody* psb=sbs[ib];
- nps+=psb->m_nodes.size();
- for(int i=0;i<psb->m_nodes.size();++i)
- {
- ps+=psb->m_nodes[i].m_x;
- }
- }
- ps/=nps;
- if(m_autocam)
- m_cameraTargetPosition+=(ps-m_cameraTargetPosition)*0.05;
- /* Anm */
- if(!isIdle())
- m_animtime=m_clock.getTimeMilliseconds()/1000.f;
- /* Ray cast */
- if(m_raycast)
- {
- /* Prepare rays */
- const int res=64;
- const btScalar fres=res-1;
- const btScalar size=8;
- const btScalar dist=10;
- btTransform trs;
- trs.setOrigin(ps);
- btScalar rayLength = 1000.f;
- const btScalar angle=m_animtime*0.2;
- trs.setRotation(btQuaternion(angle,SIMD_PI/4,0));
- btVector3 dir=trs.getBasis()*btVector3(0,-1,0);
- trs.setOrigin(ps-dir*dist);
- btAlignedObjectArray<btVector3> origins;
- btAlignedObjectArray<btScalar> fractions;
- origins.resize(res*res);
- fractions.resize(res*res,1.f);
- for(int y=0;y<res;++y)
- {
- for(int x=0;x<res;++x)
- {
- const int idx=y*res+x;
- origins[idx]=trs*btVector3(-size+size*2*x/fres,dist,-size+size*2*y/fres);
- }
- }
- /* Cast rays */
- {
- m_clock.reset();
- if (sbs.size())
- {
- btVector3* org=&origins[0];
- btScalar* fraction=&fractions[0];
- btSoftBody** psbs=&sbs[0];
- btSoftBody::sRayCast results;
- for(int i=0,ni=origins.size(),nb=sbs.size();i<ni;++i)
- {
- for(int ib=0;ib<nb;++ib)
- {
- btVector3 rayFrom = *org;
- btVector3 rayTo = rayFrom+dir*rayLength;
- if(psbs[ib]->rayTest(rayFrom,rayTo,results))
- {
- *fraction=results.fraction;
- }
- }
- ++org;++fraction;
- }
- long ms=btMax<long>(m_clock.getTimeMilliseconds(),1);
- long rayperseconds=(1000*(origins.size()*sbs.size()))/ms;
- printf("%d ms (%d rays/s)\r\n",int(ms),int(rayperseconds));
- }
- }
- /* Draw rays */
- const btVector3 c[]={ origins[0],
- origins[res-1],
- origins[res*(res-1)],
- origins[res*(res-1)+res-1]};
- idraw->drawLine(c[0],c[1],btVector3(0,0,0));
- idraw->drawLine(c[1],c[3],btVector3(0,0,0));
- idraw->drawLine(c[3],c[2],btVector3(0,0,0));
- idraw->drawLine(c[2],c[0],btVector3(0,0,0));
- for(int i=0,ni=origins.size();i<ni;++i)
- {
- const btScalar fraction=fractions[i];
- const btVector3& org=origins[i];
- if(fraction<1.f)
- {
- idraw->drawLine(org,org+dir*rayLength*fraction,btVector3(1,0,0));
- }
- else
- {
- idraw->drawLine(org,org-dir*rayLength*0.1,btVector3(0,0,0));
- }
- }
- #undef RES
- }
- /* Water level */
- static const btVector3 axis[]={btVector3(1,0,0),
- btVector3(0,1,0),
- btVector3(0,0,1)};
- if(m_softBodyWorldInfo.water_density>0)
- {
- const btVector3 c= btVector3((btScalar)0.25,(btScalar)0.25,1);
- const btScalar a= (btScalar)0.5;
- const btVector3 n= m_softBodyWorldInfo.water_normal;
- const btVector3 o= -n*m_softBodyWorldInfo.water_offset;
- const btVector3 x= btCross(n,axis[n.minAxis()]).normalized();
- const btVector3 y= btCross(x,n).normalized();
- const btScalar s= 25;
- idraw->drawTriangle(o-x*s-y*s,o+x*s-y*s,o+x*s+y*s,c,a);
- idraw->drawTriangle(o-x*s-y*s,o+x*s+y*s,o-x*s+y*s,c,a);
- }
- //
- int lineWidth=280;
- int xStart = m_glutScreenWidth - lineWidth;
- int yStart = 20;
- if((getDebugMode() & btIDebugDraw::DBG_NoHelpText)==0)
- {
- setOrthographicProjection();
- glDisable(GL_LIGHTING);
- glColor3f(0, 0, 0);
- char buf[124];
-
- glRasterPos3f(xStart, yStart, 0);
- if (sDemoMode)
- {
- sprintf(buf,"d to toggle demo mode (on)");
- } else
- {
- sprintf(buf,"d to toggle demo mode (off)");
- }
- GLDebugDrawString(xStart,20,buf);
- glRasterPos3f(xStart, yStart, 0);
- sprintf(buf,"] for next demo (%d)",current_demo);
- yStart+=20;
- GLDebugDrawString(xStart,yStart,buf);
- glRasterPos3f(xStart, yStart, 0);
- sprintf(buf,"c to visualize clusters");
- yStart+=20;
- GLDebugDrawString(xStart,yStart,buf);
- glRasterPos3f(xStart, yStart, 0);
- sprintf(buf,"; to toggle camera mode");
- yStart+=20;
- GLDebugDrawString(xStart,yStart,buf);
- glRasterPos3f(xStart, yStart, 0);
- sprintf(buf,"n,m,l,k for power and steering");
- yStart+=20;
- GLDebugDrawString(xStart,yStart,buf);
- resetPerspectiveProjection();
- glEnable(GL_LIGHTING);
- }
- DemoApplication::renderme();
- }
- #endif
- #endif
- void SoftDemo::setDrawClusters(bool drawClusters)
- {
- if (drawClusters)
- {
- getSoftDynamicsWorld()->setDrawFlags(getSoftDynamicsWorld()->getDrawFlags()|fDrawFlags::Clusters);
- } else
- {
- getSoftDynamicsWorld()->setDrawFlags(getSoftDynamicsWorld()->getDrawFlags()& (~fDrawFlags::Clusters));
- }
- }
- #if 0
- void SoftDemo::keyboardCallback(unsigned char key, int x, int y)
- {
- switch(key)
- {
- case 'd': sDemoMode = !sDemoMode; break;
- case 'n': motorcontrol.maxtorque=10;motorcontrol.goal+=1;break;
- case 'm': motorcontrol.maxtorque=10;motorcontrol.goal-=1;break;
- case 'l': steercontrol_f.angle+=0.1;steercontrol_r.angle+=0.1;break;
- case 'k': steercontrol_f.angle-=0.1;steercontrol_r.angle-=0.1;break;
- case ']': ++current_demo;clientResetScene();break;
- case '[': --current_demo;clientResetScene();break;
- case ',': m_raycast=!m_raycast;break;
- case ';': m_autocam=!m_autocam;break;
- case 'c': getSoftDynamicsWorld()->setDrawFlags(getSoftDynamicsWorld()->getDrawFlags()^fDrawFlags::Clusters);break;
- case '`':
- {
- btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray();
- for(int ib=0;ib<sbs.size();++ib)
- {
- btSoftBody* psb=sbs[ib];
- psb->staticSolve(128);
- }
- }
- break;
- default: DemoApplication::keyboardCallback(key,x,y);
- }
- }
- #endif
- //
- void SoftDemo::mouseMotionFunc(int x,int y)
- {
- if(m_node&&(m_results.fraction<1.f))
- {
- if(!m_drag)
- {
- #define SQ(_x_) (_x_)*(_x_)
- if((SQ(x-m_lastmousepos[0])+SQ(y-m_lastmousepos[1]))>6)
- {
- m_drag=true;
- }
- #undef SQ
- }
- if(m_drag)
- {
- m_lastmousepos[0] = x;
- m_lastmousepos[1] = y;
- }
- }
- }
- #if 0
- //
- void SoftDemo::mouseFunc(int button, int state, int x, int y)
- {
- if(button==0)
- {
- switch(state)
- {
- case 0:
- {
- m_results.fraction=1.f;
- DemoApplication::mouseFunc(button,state,x,y);
- if(!m_pickConstraint)
- {
- const btVector3 rayFrom=m_cameraPosition;
- const btVector3 rayTo=getRayTo(x,y);
- const btVector3 rayDir=(rayTo-rayFrom).normalized();
- btSoftBodyArray& sbs=getSoftDynamicsWorld()->getSoftBodyArray();
- for(int ib=0;ib<sbs.size();++ib)
- {
- btSoftBody* psb=sbs[ib];
- btSoftBody::sRayCast res;
- if(psb->rayTest(rayFrom,rayTo,res))
- {
- m_results=res;
- }
- }
- if(m_results.fraction<1.f)
- {
- m_impact = rayFrom+(rayTo-rayFrom)*m_results.fraction;
- m_drag = m_cutting ? false : true;
- m_lastmousepos[0] = x;
- m_lastmousepos[1] = y;
- m_node = 0;
- switch(m_results.feature)
- {
- case btSoftBody::eFeature::Tetra:
- {
- btSoftBody::Tetra& tet=m_results.body->m_tetras[m_results.index];
- m_node=tet.m_n[0];
- for(int i=1;i<4;++i)
- {
- if( (m_node->m_x-m_impact).length2()>
- (tet.m_n[i]->m_x-m_impact).length2())
- {
- m_node=tet.m_n[i];
- }
- }
- break;
- }
- case btSoftBody::eFeature::Face:
- {
- btSoftBody::Face& f=m_results.body->m_faces[m_results.index];
- m_node=f.m_n[0];
- for(int i=1;i<3;++i)
- {
- if( (m_node->m_x-m_impact).length2()>
- (f.m_n[i]->m_x-m_impact).length2())
- {
- m_node=f.m_n[i];
- }
- }
- }
- break;
- }
- if(m_node) m_goal=m_node->m_x;
- return;
- }
- }
- }
- break;
- case 1:
- if((!m_drag)&&m_cutting&&(m_results.fraction<1.f))
- {
- ImplicitSphere isphere(m_impact,1);
- printf("Mass before: %f\r\n",m_results.body->getTotalMass());
- m_results.body->refine(&isphere,0.0001,true);
- printf("Mass after: %f\r\n",m_results.body->getTotalMass());
- }
- m_results.fraction=1.f;
- m_drag=false;
- DemoApplication::mouseFunc(button,state,x,y);
- break;
- }
- }
- else
- {
- DemoApplication::mouseFunc(button,state,x,y);
- }
- }
- #endif
- void SoftDemo::initPhysics()
- {
- ///create concave ground mesh
- m_guiHelper->setUpAxis(1);
- // m_azi = 0;
- //reset and disable motorcontrol at the start
- motorcontrol.goal = 0;
- motorcontrol.maxtorque = 0;
- btCollisionShape* groundShape = 0;
- {
- int i;
- int j;
- const int NUM_VERTS_X = 30;
- const int NUM_VERTS_Y = 30;
- const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y;
- const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1);
- gGroundVertices = new btVector3[totalVerts];
- gGroundIndices = new int[totalTriangles*3];
- btScalar offset(-50);
- for ( i=0;i<NUM_VERTS_X;i++)
- {
- for (j=0;j<NUM_VERTS_Y;j++)
- {
- gGroundVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE,
- //0.f,
- waveheight*sinf((float)i)*cosf((float)j+offset),
- (j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE);
- }
- }
- int vertStride = sizeof(btVector3);
- int indexStride = 3*sizeof(int);
- int index=0;
- for ( i=0;i<NUM_VERTS_X-1;i++)
- {
- for (int j=0;j<NUM_VERTS_Y-1;j++)
- {
- gGroundIndices[index++] = j*NUM_VERTS_X+i;
- gGroundIndices[index++] = j*NUM_VERTS_X+i+1;
- gGroundIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
- gGroundIndices[index++] = j*NUM_VERTS_X+i;
- gGroundIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
- gGroundIndices[index++] = (j+1)*NUM_VERTS_X+i;
- }
- }
- btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles,
- gGroundIndices,
- indexStride,
- totalVerts,(btScalar*) &gGroundVertices[0].x(),vertStride);
- bool useQuantizedAabbCompression = true;
- groundShape = new btBvhTriangleMeshShape(indexVertexArrays,useQuantizedAabbCompression);
- groundShape->setMargin(0.5);
- }
- m_collisionShapes.push_back(groundShape);
- btCollisionShape* groundBox = new btBoxShape (btVector3(100,CUBE_HALF_EXTENTS,100));
- m_collisionShapes.push_back(groundBox);
- btCompoundShape* cylinderCompound = new btCompoundShape;
- btCollisionShape* cylinderShape = new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS));
- btTransform localTransform;
- localTransform.setIdentity();
- cylinderCompound->addChildShape(localTransform,cylinderShape);
- btQuaternion orn(btVector3(0,1,0),SIMD_PI);
- localTransform.setRotation(orn);
- cylinderCompound->addChildShape(localTransform,cylinderShape);
- m_collisionShapes.push_back(cylinderCompound);
- m_dispatcher=0;
- ///register some softbody collision algorithms on top of the default btDefaultCollisionConfiguration
- m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
- m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
- m_softBodyWorldInfo.m_dispatcher = m_dispatcher;
- ////////////////////////////
- ///Register softbody versus softbody collision algorithm
- ///Register softbody versus rigidbody collision algorithm
- ////////////////////////////
- btVector3 worldAabbMin(-1000,-1000,-1000);
- btVector3 worldAabbMax(1000,1000,1000);
- m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
- m_softBodyWorldInfo.m_broadphase = m_broadphase;
- btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
- m_solver = solver;
- btSoftBodySolver* softBodySolver = 0;
- #ifdef USE_AMD_OPENCL
- static bool once = true;
- if (once)
- {
- once=false;
- initCL(0,0);
- }
- if( g_openCLSIMDSolver )
- delete g_openCLSIMDSolver;
- if( g_softBodyOutput )
- delete g_softBodyOutput;
- if (1)
- {
- g_openCLSIMDSolver = new btOpenCLSoftBodySolverSIMDAware( g_cqCommandQue, g_cxMainContext);
- // g_openCLSIMDSolver = new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext);
- g_openCLSIMDSolver->setCLFunctions(new CachingCLFunctions(g_cqCommandQue, g_cxMainContext));
- }
- softBodySolver = g_openCLSIMDSolver;
- g_softBodyOutput = new btSoftBodySolverOutputCLtoCPU;
- #endif //USE_AMD_OPENCL
- btDiscreteDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration,softBodySolver);
- m_dynamicsWorld = world;
- m_dynamicsWorld->setInternalTickCallback(pickingPreTickCallback,this,true);
- m_dynamicsWorld->getDispatchInfo().m_enableSPU = true;
- m_dynamicsWorld->setGravity(btVector3(0,-10,0));
- m_softBodyWorldInfo.m_gravity.setValue(0,-10,0);
- m_guiHelper->createPhysicsDebugDrawer(world);
- // clientResetScene();
- m_softBodyWorldInfo.m_sparsesdf.Initialize();
- // clientResetScene();
- //create ground object
- btTransform tr;
- tr.setIdentity();
- tr.setOrigin(btVector3(0,-12,0));
- btCollisionObject* newOb = new btCollisionObject();
- newOb->setWorldTransform(tr);
- newOb->setInterpolationWorldTransform( tr);
- int lastDemo = (sizeof(demofncs)/sizeof(demofncs[0]))-1;
- if (current_demo<0)
- current_demo = lastDemo;
- if (current_demo > lastDemo)
- current_demo =0;
-
- if (current_demo>19)
- {
- newOb->setCollisionShape(m_collisionShapes[0]);
- } else
- {
- newOb->setCollisionShape(m_collisionShapes[1]);
- }
- m_dynamicsWorld->addCollisionObject(newOb);
- m_softBodyWorldInfo.m_sparsesdf.Reset();
-
- motorcontrol.goal = 0;
- motorcontrol.maxtorque = 0;
- m_softBodyWorldInfo.air_density = (btScalar)1.2;
- m_softBodyWorldInfo.water_density = 0;
- m_softBodyWorldInfo.water_offset = 0;
- m_softBodyWorldInfo.water_normal = btVector3(0,0,0);
- m_softBodyWorldInfo.m_gravity.setValue(0,-10,0);
- m_autocam = false;
- m_raycast = false;
- m_cutting = false;
- m_results.fraction = 1.f;
-
- demofncs[current_demo](this);
- m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
- }
- void SoftDemo::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];
- m_collisionShapes[j] = 0;
- delete shape;
- }
- //delete dynamics world
- delete m_dynamicsWorld;
- m_dynamicsWorld = 0;
- //delete solver
- delete m_solver;
- //delete broadphase
- delete m_broadphase;
- //delete dispatcher
- delete m_dispatcher;
- delete m_collisionConfiguration;
- }
- class CommonExampleInterface* SoftDemoCreateFunc(struct CommonExampleOptions& options)
- {
- current_demo = options.m_option;
- return new SoftDemo(options.m_guiHelper);
- }
|