ConstraintDemo.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. /*
  2. Bullet Continuous Collision Detection and Physics Library
  3. Copyright (c) 2003-2015 Erwin Coumans http://continuousphysics.com/Bullet/
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it freely,
  8. subject to the following restrictions:
  9. 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.
  10. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. 3. This notice may not be removed or altered from any source distribution.
  12. */
  13. #include "ConstraintDemo.h"
  14. #include "btBulletDynamicsCommon.h"
  15. #include "LinearMath/btIDebugDraw.h"
  16. #include <stdio.h> //printf debugging
  17. #include "../CommonInterfaces/CommonRigidBodyBase.h"
  18. ///AllConstraintDemo shows how to create a constraint, like Hinge or btGenericD6constraint
  19. class AllConstraintDemo : public CommonRigidBodyBase
  20. {
  21. //keep track of variables to delete memory at the end
  22. void setupEmptyDynamicsWorld();
  23. public:
  24. AllConstraintDemo(struct GUIHelperInterface* helper);
  25. virtual ~AllConstraintDemo();
  26. virtual void initPhysics();
  27. virtual void exitPhysics();
  28. virtual void resetCamera()
  29. {
  30. float dist = 27;
  31. float pitch = 720;
  32. float yaw = 30;
  33. float targetPos[3]={2,0,-10};
  34. m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
  35. }
  36. virtual void keyboardCallback(unsigned char key, int x, int y);
  37. // for cone-twist motor driving
  38. float m_Time;
  39. class btConeTwistConstraint* m_ctc;
  40. };
  41. const int numObjects = 3;
  42. #define ENABLE_ALL_DEMOS 1
  43. #define CUBE_HALF_EXTENTS 1.f
  44. #define SIMD_PI_2 ((SIMD_PI)*0.5f)
  45. #define SIMD_PI_4 ((SIMD_PI)*0.25f)
  46. btTransform sliderTransform;
  47. btVector3 lowerSliderLimit = btVector3(-10,0,0);
  48. btVector3 hiSliderLimit = btVector3(10,0,0);
  49. btRigidBody* d6body0 =0;
  50. btHingeConstraint* spDoorHinge = NULL;
  51. btHingeConstraint* spHingeDynAB = NULL;
  52. btGeneric6DofConstraint* spSlider6Dof = NULL;
  53. static bool s_bTestConeTwistMotor = false;
  54. void AllConstraintDemo::setupEmptyDynamicsWorld()
  55. {
  56. m_collisionConfiguration = new btDefaultCollisionConfiguration();
  57. m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
  58. m_broadphase = new btDbvtBroadphase();
  59. m_solver = new btSequentialImpulseConstraintSolver();
  60. m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
  61. }
  62. void AllConstraintDemo::initPhysics()
  63. {
  64. m_guiHelper->setUpAxis(1);
  65. m_Time = 0;
  66. setupEmptyDynamicsWorld();
  67. m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
  68. //btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(40.),btScalar(50.)));
  69. btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),40);
  70. m_collisionShapes.push_back(groundShape);
  71. btTransform groundTransform;
  72. groundTransform.setIdentity();
  73. groundTransform.setOrigin(btVector3(0,-56,0));
  74. btRigidBody* groundBody;
  75. groundBody= createRigidBody(0, groundTransform, groundShape);
  76. btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS));
  77. m_collisionShapes.push_back(shape);
  78. btTransform trans;
  79. trans.setIdentity();
  80. trans.setOrigin(btVector3(0,20,0));
  81. float mass = 1.f;
  82. #if ENABLE_ALL_DEMOS
  83. ///gear constraint demo
  84. #define THETA SIMD_PI/4.f
  85. #define L_1 (2 - tan(THETA))
  86. #define L_2 (1 / cos(THETA))
  87. #define RATIO L_2 / L_1
  88. btRigidBody* bodyA=0;
  89. btRigidBody* bodyB=0;
  90. {
  91. btCollisionShape* cylA = new btCylinderShape(btVector3(0.2,0.25,0.2));
  92. btCollisionShape* cylB = new btCylinderShape(btVector3(L_1,0.025,L_1));
  93. btCompoundShape* cyl0 = new btCompoundShape();
  94. cyl0->addChildShape(btTransform::getIdentity(),cylA);
  95. cyl0->addChildShape(btTransform::getIdentity(),cylB);
  96. btScalar mass = 6.28;
  97. btVector3 localInertia;
  98. cyl0->calculateLocalInertia(mass,localInertia);
  99. btRigidBody::btRigidBodyConstructionInfo ci(mass,0,cyl0,localInertia);
  100. ci.m_startWorldTransform.setOrigin(btVector3(-8,1,-8));
  101. btRigidBody* body = new btRigidBody(ci);//1,0,cyl0,localInertia);
  102. m_dynamicsWorld->addRigidBody(body);
  103. body->setLinearFactor(btVector3(0,0,0));
  104. body->setAngularFactor(btVector3(0,1,0));
  105. bodyA = body;
  106. }
  107. {
  108. btCollisionShape* cylA = new btCylinderShape(btVector3(0.2,0.26,0.2));
  109. btCollisionShape* cylB = new btCylinderShape(btVector3(L_2,0.025,L_2));
  110. btCompoundShape* cyl0 = new btCompoundShape();
  111. cyl0->addChildShape(btTransform::getIdentity(),cylA);
  112. cyl0->addChildShape(btTransform::getIdentity(),cylB);
  113. btScalar mass = 6.28;
  114. btVector3 localInertia;
  115. cyl0->calculateLocalInertia(mass,localInertia);
  116. btRigidBody::btRigidBodyConstructionInfo ci(mass,0,cyl0,localInertia);
  117. ci.m_startWorldTransform.setOrigin(btVector3(-10,2,-8));
  118. btQuaternion orn(btVector3(0,0,1),-THETA);
  119. ci.m_startWorldTransform.setRotation(orn);
  120. btRigidBody* body = new btRigidBody(ci);//1,0,cyl0,localInertia);
  121. body->setLinearFactor(btVector3(0,0,0));
  122. btHingeConstraint* hinge = new btHingeConstraint(*body,btVector3(0,0,0),btVector3(0,1,0),true);
  123. m_dynamicsWorld->addConstraint(hinge);
  124. bodyB= body;
  125. body->setAngularVelocity(btVector3(0,3,0));
  126. m_dynamicsWorld->addRigidBody(body);
  127. }
  128. btVector3 axisA(0,1,0);
  129. btVector3 axisB(0,1,0);
  130. btQuaternion orn(btVector3(0,0,1),-THETA);
  131. btMatrix3x3 mat(orn);
  132. axisB = mat.getRow(1);
  133. btGearConstraint* gear = new btGearConstraint(*bodyA,*bodyB, axisA,axisB,RATIO);
  134. m_dynamicsWorld->addConstraint(gear,true);
  135. #endif
  136. #if ENABLE_ALL_DEMOS
  137. //point to point constraint with a breaking threshold
  138. {
  139. trans.setIdentity();
  140. trans.setOrigin(btVector3(1,30,-5));
  141. createRigidBody( mass,trans,shape);
  142. trans.setOrigin(btVector3(0,0,-5));
  143. btRigidBody* body0 = createRigidBody( mass,trans,shape);
  144. trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0));
  145. mass = 1.f;
  146. // btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape);
  147. btVector3 pivotInA(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,0);
  148. btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA);
  149. m_dynamicsWorld->addConstraint(p2p);
  150. p2p ->setBreakingImpulseThreshold(10.2);
  151. p2p->setDbgDrawSize(btScalar(5.f));
  152. }
  153. #endif
  154. #if ENABLE_ALL_DEMOS
  155. //point to point constraint (ball socket)
  156. {
  157. btRigidBody* body0 = createRigidBody( mass,trans,shape);
  158. trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0));
  159. mass = 1.f;
  160. // btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape);
  161. // btRigidBody* body1 = createRigidBody( 0.0,trans,0);
  162. //body1->setActivationState(DISABLE_DEACTIVATION);
  163. //body1->setDamping(0.3,0.3);
  164. btVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS);
  165. btVector3 axisInA(0,0,1);
  166. // btVector3 pivotInB = body1 ? body1->getCenterOfMassTransform().inverse()(body0->getCenterOfMassTransform()(pivotInA)) : pivotInA;
  167. // btVector3 axisInB = body1?
  168. // (body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) :
  169. body0->getCenterOfMassTransform().getBasis() * axisInA;
  170. #define P2P
  171. #ifdef P2P
  172. btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA);
  173. //btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB);
  174. //btTypedConstraint* hinge = new btHingeConstraint(*body0,*body1,pivotInA,pivotInB,axisInA,axisInB);
  175. m_dynamicsWorld->addConstraint(p2p);
  176. p2p->setDbgDrawSize(btScalar(5.f));
  177. #else
  178. btHingeConstraint* hinge = new btHingeConstraint(*body0,pivotInA,axisInA);
  179. //use zero targetVelocity and a small maxMotorImpulse to simulate joint friction
  180. //float targetVelocity = 0.f;
  181. //float maxMotorImpulse = 0.01;
  182. float targetVelocity = 1.f;
  183. float maxMotorImpulse = 1.0f;
  184. hinge->enableAngularMotor(true,targetVelocity,maxMotorImpulse);
  185. m_dynamicsWorld->addConstraint(hinge);
  186. hinge->setDbgDrawSize(btScalar(5.f));
  187. #endif //P2P
  188. }
  189. #endif
  190. #if ENABLE_ALL_DEMOS
  191. {
  192. btTransform trans;
  193. trans.setIdentity();
  194. btVector3 worldPos(-20,0,30);
  195. trans.setOrigin(worldPos);
  196. btTransform frameInA, frameInB;
  197. frameInA = btTransform::getIdentity();
  198. frameInB = btTransform::getIdentity();
  199. btRigidBody* pRbA1 = createRigidBody(mass, trans, shape);
  200. // btRigidBody* pRbA1 = createRigidBody(0.f, trans, shape);
  201. pRbA1->setActivationState(DISABLE_DEACTIVATION);
  202. // add dynamic rigid body B1
  203. worldPos.setValue(-30,0,30);
  204. trans.setOrigin(worldPos);
  205. btRigidBody* pRbB1 = createRigidBody(mass, trans, shape);
  206. // btRigidBody* pRbB1 = createRigidBody(0.f, trans, shape);
  207. pRbB1->setActivationState(DISABLE_DEACTIVATION);
  208. // create slider constraint between A1 and B1 and add it to world
  209. btSliderConstraint* spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true);
  210. // spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, false);
  211. spSlider1->setLowerLinLimit(-15.0F);
  212. spSlider1->setUpperLinLimit(-5.0F);
  213. // spSlider1->setLowerLinLimit(5.0F);
  214. // spSlider1->setUpperLinLimit(15.0F);
  215. // spSlider1->setLowerLinLimit(-10.0F);
  216. // spSlider1->setUpperLinLimit(-10.0F);
  217. spSlider1->setLowerAngLimit(-SIMD_PI / 3.0F);
  218. spSlider1->setUpperAngLimit( SIMD_PI / 3.0F);
  219. m_dynamicsWorld->addConstraint(spSlider1, true);
  220. spSlider1->setDbgDrawSize(btScalar(5.f));
  221. }
  222. #endif
  223. #if ENABLE_ALL_DEMOS
  224. //create a slider, using the generic D6 constraint
  225. {
  226. mass = 1.f;
  227. btVector3 sliderWorldPos(0,10,0);
  228. btVector3 sliderAxis(1,0,0);
  229. btScalar angle=0.f;//SIMD_RADS_PER_DEG * 10.f;
  230. btMatrix3x3 sliderOrientation(btQuaternion(sliderAxis ,angle));
  231. trans.setIdentity();
  232. trans.setOrigin(sliderWorldPos);
  233. //trans.setBasis(sliderOrientation);
  234. sliderTransform = trans;
  235. d6body0 = createRigidBody( mass,trans,shape);
  236. d6body0->setActivationState(DISABLE_DEACTIVATION);
  237. btRigidBody* fixedBody1 = createRigidBody(0,trans,0);
  238. m_dynamicsWorld->addRigidBody(fixedBody1);
  239. btTransform frameInA, frameInB;
  240. frameInA = btTransform::getIdentity();
  241. frameInB = btTransform::getIdentity();
  242. frameInA.setOrigin(btVector3(0., 5., 0.));
  243. frameInB.setOrigin(btVector3(0., 5., 0.));
  244. // bool useLinearReferenceFrameA = false;//use fixed frame B for linear llimits
  245. bool useLinearReferenceFrameA = true;//use fixed frame A for linear llimits
  246. spSlider6Dof = new btGeneric6DofConstraint(*fixedBody1, *d6body0,frameInA,frameInB,useLinearReferenceFrameA);
  247. spSlider6Dof->setLinearLowerLimit(lowerSliderLimit);
  248. spSlider6Dof->setLinearUpperLimit(hiSliderLimit);
  249. //range should be small, otherwise singularities will 'explode' the constraint
  250. // spSlider6Dof->setAngularLowerLimit(btVector3(-1.5,0,0));
  251. // spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0));
  252. // spSlider6Dof->setAngularLowerLimit(btVector3(0,0,0));
  253. // spSlider6Dof->setAngularUpperLimit(btVector3(0,0,0));
  254. spSlider6Dof->setAngularLowerLimit(btVector3(-SIMD_PI,0,0));
  255. spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0));
  256. spSlider6Dof->getTranslationalLimitMotor()->m_enableMotor[0] = true;
  257. spSlider6Dof->getTranslationalLimitMotor()->m_targetVelocity[0] = -5.0f;
  258. spSlider6Dof->getTranslationalLimitMotor()->m_maxMotorForce[0] = 0.1f;
  259. m_dynamicsWorld->addConstraint(spSlider6Dof);
  260. spSlider6Dof->setDbgDrawSize(btScalar(5.f));
  261. }
  262. #endif
  263. #if ENABLE_ALL_DEMOS
  264. { // create a door using hinge constraint attached to the world
  265. btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f));
  266. m_collisionShapes.push_back(pDoorShape);
  267. btTransform doorTrans;
  268. doorTrans.setIdentity();
  269. doorTrans.setOrigin(btVector3(-5.0f, -2.0f, 0.0f));
  270. btRigidBody* pDoorBody = createRigidBody( 1.0, doorTrans, pDoorShape);
  271. pDoorBody->setActivationState(DISABLE_DEACTIVATION);
  272. const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f ); // right next to the door slightly outside
  273. btVector3 btAxisA( 0.0f, 1.0f, 0.0f ); // pointing upwards, aka Y-axis
  274. spDoorHinge = new btHingeConstraint( *pDoorBody, btPivotA, btAxisA );
  275. // spDoorHinge->setLimit( 0.0f, SIMD_PI_2 );
  276. // test problem values
  277. // spDoorHinge->setLimit( -SIMD_PI, SIMD_PI*0.8f);
  278. // spDoorHinge->setLimit( 1.f, -1.f);
  279. // spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI);
  280. // spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.3f, 0.0f);
  281. // spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.01f, 0.0f); // "sticky limits"
  282. spDoorHinge->setLimit( -SIMD_PI * 0.25f, SIMD_PI * 0.25f );
  283. // spDoorHinge->setLimit( 0.0f, 0.0f );
  284. m_dynamicsWorld->addConstraint(spDoorHinge);
  285. spDoorHinge->setDbgDrawSize(btScalar(5.f));
  286. //doorTrans.setOrigin(btVector3(-5.0f, 2.0f, 0.0f));
  287. //btRigidBody* pDropBody = createRigidBody( 10.0, doorTrans, shape);
  288. }
  289. #endif
  290. #if ENABLE_ALL_DEMOS
  291. { // create a generic 6DOF constraint
  292. btTransform tr;
  293. tr.setIdentity();
  294. tr.setOrigin(btVector3(btScalar(10.), btScalar(6.), btScalar(0.)));
  295. tr.getBasis().setEulerZYX(0,0,0);
  296. // btRigidBody* pBodyA = createRigidBody( mass, tr, shape);
  297. btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
  298. // btRigidBody* pBodyA = createRigidBody( 0.0, tr, 0);
  299. pBodyA->setActivationState(DISABLE_DEACTIVATION);
  300. tr.setIdentity();
  301. tr.setOrigin(btVector3(btScalar(0.), btScalar(6.), btScalar(0.)));
  302. tr.getBasis().setEulerZYX(0,0,0);
  303. btRigidBody* pBodyB = createRigidBody(mass, tr, shape);
  304. // btRigidBody* pBodyB = createRigidBody(0.f, tr, shape);
  305. pBodyB->setActivationState(DISABLE_DEACTIVATION);
  306. btTransform frameInA, frameInB;
  307. frameInA = btTransform::getIdentity();
  308. frameInA.setOrigin(btVector3(btScalar(-5.), btScalar(0.), btScalar(0.)));
  309. frameInB = btTransform::getIdentity();
  310. frameInB.setOrigin(btVector3(btScalar(5.), btScalar(0.), btScalar(0.)));
  311. btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, true);
  312. // btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, false);
  313. pGen6DOF->setLinearLowerLimit(btVector3(-10., -2., -1.));
  314. pGen6DOF->setLinearUpperLimit(btVector3(10., 2., 1.));
  315. // pGen6DOF->setLinearLowerLimit(btVector3(-10., 0., 0.));
  316. // pGen6DOF->setLinearUpperLimit(btVector3(10., 0., 0.));
  317. // pGen6DOF->setLinearLowerLimit(btVector3(0., 0., 0.));
  318. // pGen6DOF->setLinearUpperLimit(btVector3(0., 0., 0.));
  319. // pGen6DOF->getTranslationalLimitMotor()->m_enableMotor[0] = true;
  320. // pGen6DOF->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f;
  321. // pGen6DOF->getTranslationalLimitMotor()->m_maxMotorForce[0] = 0.1f;
  322. // pGen6DOF->setAngularLowerLimit(btVector3(0., SIMD_HALF_PI*0.9, 0.));
  323. // pGen6DOF->setAngularUpperLimit(btVector3(0., -SIMD_HALF_PI*0.9, 0.));
  324. // pGen6DOF->setAngularLowerLimit(btVector3(0., 0., -SIMD_HALF_PI));
  325. // pGen6DOF->setAngularUpperLimit(btVector3(0., 0., SIMD_HALF_PI));
  326. pGen6DOF->setAngularLowerLimit(btVector3(-SIMD_HALF_PI * 0.5f, -0.75, -SIMD_HALF_PI * 0.8f));
  327. pGen6DOF->setAngularUpperLimit(btVector3(SIMD_HALF_PI * 0.5f, 0.75, SIMD_HALF_PI * 0.8f));
  328. // pGen6DOF->setAngularLowerLimit(btVector3(0.f, -0.75, SIMD_HALF_PI * 0.8f));
  329. // pGen6DOF->setAngularUpperLimit(btVector3(0.f, 0.75, -SIMD_HALF_PI * 0.8f));
  330. // pGen6DOF->setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI * 0.8f, SIMD_HALF_PI * 1.98f));
  331. // pGen6DOF->setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI * 0.8f, -SIMD_HALF_PI * 1.98f));
  332. // pGen6DOF->setAngularLowerLimit(btVector3(-0.75,-0.5, -0.5));
  333. // pGen6DOF->setAngularUpperLimit(btVector3(0.75,0.5, 0.5));
  334. // pGen6DOF->setAngularLowerLimit(btVector3(-0.75,0., 0.));
  335. // pGen6DOF->setAngularUpperLimit(btVector3(0.75,0., 0.));
  336. // pGen6DOF->setAngularLowerLimit(btVector3(0., -0.7,0.));
  337. // pGen6DOF->setAngularUpperLimit(btVector3(0., 0.7, 0.));
  338. // pGen6DOF->setAngularLowerLimit(btVector3(-1., 0.,0.));
  339. // pGen6DOF->setAngularUpperLimit(btVector3(1., 0., 0.));
  340. m_dynamicsWorld->addConstraint(pGen6DOF, true);
  341. pGen6DOF->setDbgDrawSize(btScalar(5.f));
  342. }
  343. #endif
  344. #if ENABLE_ALL_DEMOS
  345. { // create a ConeTwist constraint
  346. btTransform tr;
  347. tr.setIdentity();
  348. tr.setOrigin(btVector3(btScalar(-10.), btScalar(5.), btScalar(0.)));
  349. tr.getBasis().setEulerZYX(0,0,0);
  350. btRigidBody* pBodyA = createRigidBody( 1.0, tr, shape);
  351. // btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
  352. pBodyA->setActivationState(DISABLE_DEACTIVATION);
  353. tr.setIdentity();
  354. tr.setOrigin(btVector3(btScalar(-10.), btScalar(-5.), btScalar(0.)));
  355. tr.getBasis().setEulerZYX(0,0,0);
  356. btRigidBody* pBodyB = createRigidBody(0.0, tr, shape);
  357. // btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
  358. btTransform frameInA, frameInB;
  359. frameInA = btTransform::getIdentity();
  360. frameInA.getBasis().setEulerZYX(0, 0, SIMD_PI_2);
  361. frameInA.setOrigin(btVector3(btScalar(0.), btScalar(-5.), btScalar(0.)));
  362. frameInB = btTransform::getIdentity();
  363. frameInB.getBasis().setEulerZYX(0,0, SIMD_PI_2);
  364. frameInB.setOrigin(btVector3(btScalar(0.), btScalar(5.), btScalar(0.)));
  365. m_ctc = new btConeTwistConstraint(*pBodyA, *pBodyB, frameInA, frameInB);
  366. // m_ctc->setLimit(btScalar(SIMD_PI_4), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f);
  367. // m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 1.0f); // soft limit == hard limit
  368. m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 0.5f);
  369. m_dynamicsWorld->addConstraint(m_ctc, true);
  370. m_ctc->setDbgDrawSize(btScalar(5.f));
  371. // s_bTestConeTwistMotor = true; // use only with old solver for now
  372. s_bTestConeTwistMotor = false;
  373. }
  374. #endif
  375. #if ENABLE_ALL_DEMOS
  376. { // Hinge connected to the world, with motor (to hinge motor with new and old constraint solver)
  377. btTransform tr;
  378. tr.setIdentity();
  379. tr.setOrigin(btVector3(btScalar(0.), btScalar(0.), btScalar(0.)));
  380. btRigidBody* pBody = createRigidBody( 1.0, tr, shape);
  381. pBody->setActivationState(DISABLE_DEACTIVATION);
  382. const btVector3 btPivotA( 10.0f, 0.0f, 0.0f );
  383. btVector3 btAxisA( 0.0f, 0.0f, 1.0f );
  384. btHingeConstraint* pHinge = new btHingeConstraint( *pBody, btPivotA, btAxisA );
  385. // pHinge->enableAngularMotor(true, -1.0, 0.165); // use for the old solver
  386. pHinge->enableAngularMotor(true, -1.0f, 1.65f); // use for the new SIMD solver
  387. m_dynamicsWorld->addConstraint(pHinge);
  388. pHinge->setDbgDrawSize(btScalar(5.f));
  389. }
  390. #endif
  391. #if ENABLE_ALL_DEMOS
  392. {
  393. // create a universal joint using generic 6DOF constraint
  394. // create two rigid bodies
  395. // static bodyA (parent) on top:
  396. btTransform tr;
  397. tr.setIdentity();
  398. tr.setOrigin(btVector3(btScalar(20.), btScalar(4.), btScalar(0.)));
  399. btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
  400. pBodyA->setActivationState(DISABLE_DEACTIVATION);
  401. // dynamic bodyB (child) below it :
  402. tr.setIdentity();
  403. tr.setOrigin(btVector3(btScalar(20.), btScalar(0.), btScalar(0.)));
  404. btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
  405. pBodyB->setActivationState(DISABLE_DEACTIVATION);
  406. // add some (arbitrary) data to build constraint frames
  407. btVector3 parentAxis(1.f, 0.f, 0.f);
  408. btVector3 childAxis(0.f, 0.f, 1.f);
  409. btVector3 anchor(20.f, 2.f, 0.f);
  410. btUniversalConstraint* pUniv = new btUniversalConstraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis);
  411. pUniv->setLowerLimit(-SIMD_HALF_PI * 0.5f, -SIMD_HALF_PI * 0.5f);
  412. pUniv->setUpperLimit(SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f);
  413. // add constraint to world
  414. m_dynamicsWorld->addConstraint(pUniv, true);
  415. // draw constraint frames and limits for debugging
  416. pUniv->setDbgDrawSize(btScalar(5.f));
  417. }
  418. #endif
  419. #if ENABLE_ALL_DEMOS
  420. { // create a generic 6DOF constraint with springs
  421. btTransform tr;
  422. tr.setIdentity();
  423. tr.setOrigin(btVector3(btScalar(-20.), btScalar(16.), btScalar(0.)));
  424. tr.getBasis().setEulerZYX(0,0,0);
  425. btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
  426. pBodyA->setActivationState(DISABLE_DEACTIVATION);
  427. tr.setIdentity();
  428. tr.setOrigin(btVector3(btScalar(-10.), btScalar(16.), btScalar(0.)));
  429. tr.getBasis().setEulerZYX(0,0,0);
  430. btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
  431. pBodyB->setActivationState(DISABLE_DEACTIVATION);
  432. btTransform frameInA, frameInB;
  433. frameInA = btTransform::getIdentity();
  434. frameInA.setOrigin(btVector3(btScalar(10.), btScalar(0.), btScalar(0.)));
  435. frameInB = btTransform::getIdentity();
  436. frameInB.setOrigin(btVector3(btScalar(0.), btScalar(0.), btScalar(0.)));
  437. btGeneric6DofSpringConstraint* pGen6DOFSpring = new btGeneric6DofSpringConstraint(*pBodyA, *pBodyB, frameInA, frameInB, true);
  438. pGen6DOFSpring->setLinearUpperLimit(btVector3(5., 0., 0.));
  439. pGen6DOFSpring->setLinearLowerLimit(btVector3(-5., 0., 0.));
  440. pGen6DOFSpring->setAngularLowerLimit(btVector3(0.f, 0.f, -1.5f));
  441. pGen6DOFSpring->setAngularUpperLimit(btVector3(0.f, 0.f, 1.5f));
  442. m_dynamicsWorld->addConstraint(pGen6DOFSpring, true);
  443. pGen6DOFSpring->setDbgDrawSize(btScalar(5.f));
  444. pGen6DOFSpring->enableSpring(0, true);
  445. pGen6DOFSpring->setStiffness(0, 39.478f);
  446. pGen6DOFSpring->setDamping(0, 0.5f);
  447. pGen6DOFSpring->enableSpring(5, true);
  448. pGen6DOFSpring->setStiffness(5, 39.478f);
  449. pGen6DOFSpring->setDamping(0, 0.3f);
  450. pGen6DOFSpring->setEquilibriumPoint();
  451. }
  452. #endif
  453. #if ENABLE_ALL_DEMOS
  454. {
  455. // create a Hinge2 joint
  456. // create two rigid bodies
  457. // static bodyA (parent) on top:
  458. btTransform tr;
  459. tr.setIdentity();
  460. tr.setOrigin(btVector3(btScalar(-20.), btScalar(4.), btScalar(0.)));
  461. btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape);
  462. pBodyA->setActivationState(DISABLE_DEACTIVATION);
  463. // dynamic bodyB (child) below it :
  464. tr.setIdentity();
  465. tr.setOrigin(btVector3(btScalar(-20.), btScalar(0.), btScalar(0.)));
  466. btRigidBody* pBodyB = createRigidBody(1.0, tr, shape);
  467. pBodyB->setActivationState(DISABLE_DEACTIVATION);
  468. // add some data to build constraint frames
  469. btVector3 parentAxis(0.f, 1.f, 0.f);
  470. btVector3 childAxis(1.f, 0.f, 0.f);
  471. btVector3 anchor(-20.f, 0.f, 0.f);
  472. btHinge2Constraint* pHinge2 = new btHinge2Constraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis);
  473. pHinge2->setLowerLimit(-SIMD_HALF_PI * 0.5f);
  474. pHinge2->setUpperLimit( SIMD_HALF_PI * 0.5f);
  475. // add constraint to world
  476. m_dynamicsWorld->addConstraint(pHinge2, true);
  477. // draw constraint frames and limits for debugging
  478. pHinge2->setDbgDrawSize(btScalar(5.f));
  479. }
  480. #endif
  481. #if ENABLE_ALL_DEMOS
  482. {
  483. // create a Hinge joint between two dynamic bodies
  484. // create two rigid bodies
  485. // static bodyA (parent) on top:
  486. btTransform tr;
  487. tr.setIdentity();
  488. tr.setOrigin(btVector3(btScalar(-20.), btScalar(-2.), btScalar(0.)));
  489. btRigidBody* pBodyA = createRigidBody( 1.0f, tr, shape);
  490. pBodyA->setActivationState(DISABLE_DEACTIVATION);
  491. // dynamic bodyB:
  492. tr.setIdentity();
  493. tr.setOrigin(btVector3(btScalar(-30.), btScalar(-2.), btScalar(0.)));
  494. btRigidBody* pBodyB = createRigidBody(10.0, tr, shape);
  495. pBodyB->setActivationState(DISABLE_DEACTIVATION);
  496. // add some data to build constraint frames
  497. btVector3 axisA(0.f, 1.f, 0.f);
  498. btVector3 axisB(0.f, 1.f, 0.f);
  499. btVector3 pivotA(-5.f, 0.f, 0.f);
  500. btVector3 pivotB( 5.f, 0.f, 0.f);
  501. spHingeDynAB = new btHingeConstraint(*pBodyA, *pBodyB, pivotA, pivotB, axisA, axisB);
  502. spHingeDynAB->setLimit(-SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f);
  503. // add constraint to world
  504. m_dynamicsWorld->addConstraint(spHingeDynAB, true);
  505. // draw constraint frames and limits for debugging
  506. spHingeDynAB->setDbgDrawSize(btScalar(5.f));
  507. }
  508. #endif
  509. #if ENABLE_ALL_DEMOS
  510. { // 6DOF connected to the world, with motor
  511. btTransform tr;
  512. tr.setIdentity();
  513. tr.setOrigin(btVector3(btScalar(10.), btScalar(-15.), btScalar(0.)));
  514. btRigidBody* pBody = createRigidBody( 1.0, tr, shape);
  515. pBody->setActivationState(DISABLE_DEACTIVATION);
  516. btTransform frameB;
  517. frameB.setIdentity();
  518. btGeneric6DofConstraint* pGen6Dof = new btGeneric6DofConstraint( *pBody, frameB, false );
  519. m_dynamicsWorld->addConstraint(pGen6Dof);
  520. pGen6Dof->setDbgDrawSize(btScalar(5.f));
  521. pGen6Dof->setAngularLowerLimit(btVector3(0,0,0));
  522. pGen6Dof->setAngularUpperLimit(btVector3(0,0,0));
  523. pGen6Dof->setLinearLowerLimit(btVector3(-10., 0, 0));
  524. pGen6Dof->setLinearUpperLimit(btVector3(10., 0, 0));
  525. pGen6Dof->getTranslationalLimitMotor()->m_enableMotor[0] = true;
  526. pGen6Dof->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f;
  527. pGen6Dof->getTranslationalLimitMotor()->m_maxMotorForce[0] = 0.1f;
  528. }
  529. #endif
  530. m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
  531. }
  532. void AllConstraintDemo::exitPhysics()
  533. {
  534. int i;
  535. //removed/delete constraints
  536. for (i=m_dynamicsWorld->getNumConstraints()-1; i>=0 ;i--)
  537. {
  538. btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i);
  539. m_dynamicsWorld->removeConstraint(constraint);
  540. delete constraint;
  541. }
  542. m_ctc = NULL;
  543. //remove the rigidbodies from the dynamics world and delete them
  544. for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
  545. {
  546. btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
  547. btRigidBody* body = btRigidBody::upcast(obj);
  548. if (body && body->getMotionState())
  549. {
  550. delete body->getMotionState();
  551. }
  552. m_dynamicsWorld->removeCollisionObject( obj );
  553. delete obj;
  554. }
  555. //delete collision shapes
  556. for (int j=0;j<m_collisionShapes.size();j++)
  557. {
  558. btCollisionShape* shape = m_collisionShapes[j];
  559. delete shape;
  560. }
  561. m_collisionShapes.clear();
  562. //delete dynamics world
  563. delete m_dynamicsWorld;
  564. m_dynamicsWorld=0;
  565. //delete solver
  566. delete m_solver;
  567. m_solver=0;
  568. //delete broadphase
  569. delete m_broadphase;
  570. m_broadphase=0;
  571. //delete dispatcher
  572. delete m_dispatcher;
  573. delete m_collisionConfiguration;
  574. }
  575. AllConstraintDemo::AllConstraintDemo(struct GUIHelperInterface* helper)
  576. :CommonRigidBodyBase(helper)
  577. {
  578. }
  579. AllConstraintDemo::~AllConstraintDemo()
  580. {
  581. //cleanup in the reverse order of creation/initialization
  582. btAssert(m_dynamicsWorld==0);
  583. }
  584. #if 0
  585. void AllConstraintDemo::clientMoveAndDisplay()
  586. {
  587. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  588. float dt = float(getDeltaTimeMicroseconds()) * 0.000001f;
  589. //printf("dt = %f: ",dt);
  590. // drive cone-twist motor
  591. m_Time += 0.03f;
  592. if (s_bTestConeTwistMotor)
  593. { // this works only for obsolete constraint solver for now
  594. // build cone target
  595. btScalar t = 1.25f*m_Time;
  596. btVector3 axis(0,sin(t),cos(t));
  597. axis.normalize();
  598. btQuaternion q1(axis, 0.75f*SIMD_PI);
  599. // build twist target
  600. //btQuaternion q2(0,0,0);
  601. //btQuaternion q2(btVehictor3(1,0,0), -0.3*sin(m_Time));
  602. btQuaternion q2(btVector3(1,0,0), -1.49f*btSin(1.5f*m_Time));
  603. // compose cone + twist and set target
  604. q1 = q1 * q2;
  605. m_ctc->enableMotor(true);
  606. m_ctc->setMotorTargetInConstraintSpace(q1);
  607. }
  608. {
  609. static bool once = true;
  610. if ( m_dynamicsWorld->getDebugDrawer() && once)
  611. {
  612. m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits);
  613. once=false;
  614. }
  615. }
  616. {
  617. //during idle mode, just run 1 simulation step maximum
  618. int maxSimSubSteps = m_idle ? 1 : 1;
  619. if (m_idle)
  620. dt = 1.0f/420.f;
  621. int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps);
  622. //optional but useful: debug drawing
  623. m_dynamicsWorld->debugDrawWorld();
  624. bool verbose = false;
  625. if (verbose)
  626. {
  627. if (!numSimSteps)
  628. printf("Interpolated transforms\n");
  629. else
  630. {
  631. if (numSimSteps > maxSimSubSteps)
  632. {
  633. //detect dropping frames
  634. printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps);
  635. } else
  636. {
  637. printf("Simulated (%i) steps\n",numSimSteps);
  638. }
  639. }
  640. }
  641. }
  642. renderme();
  643. // drawLimit();
  644. glFlush();
  645. swapBuffers();
  646. }
  647. void AllConstraintDemo::displayCallback(void) {
  648. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  649. if (m_dynamicsWorld)
  650. m_dynamicsWorld->debugDrawWorld();
  651. // drawLimit();
  652. renderme();
  653. glFlush();
  654. swapBuffers();
  655. }
  656. #endif
  657. void AllConstraintDemo::keyboardCallback(unsigned char key, int x, int y)
  658. {
  659. (void)x;
  660. (void)y;
  661. switch (key)
  662. {
  663. case 'O' :
  664. {
  665. bool offectOnOff;
  666. if(spDoorHinge)
  667. {
  668. offectOnOff = spDoorHinge->getUseFrameOffset();
  669. offectOnOff = !offectOnOff;
  670. spDoorHinge->setUseFrameOffset(offectOnOff);
  671. printf("DoorHinge %s frame offset\n", offectOnOff ? "uses" : "does not use");
  672. }
  673. if(spHingeDynAB)
  674. {
  675. offectOnOff = spHingeDynAB->getUseFrameOffset();
  676. offectOnOff = !offectOnOff;
  677. spHingeDynAB->setUseFrameOffset(offectOnOff);
  678. printf("HingeDynAB %s frame offset\n", offectOnOff ? "uses" : "does not use");
  679. }
  680. if(spSlider6Dof)
  681. {
  682. offectOnOff = spSlider6Dof->getUseFrameOffset();
  683. offectOnOff = !offectOnOff;
  684. spSlider6Dof->setUseFrameOffset(offectOnOff);
  685. printf("Slider6Dof %s frame offset\n", offectOnOff ? "uses" : "does not use");
  686. }
  687. }
  688. break;
  689. default :
  690. {
  691. }
  692. break;
  693. }
  694. }
  695. class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options)
  696. {
  697. return new AllConstraintDemo(options.m_guiHelper);
  698. }