123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /*
- Bullet Continuous Collision Detection and Physics Library
- Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
- This software is provided 'as-is', without any express or implied warranty.
- In no event will the authors be held liable for any damages arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it freely,
- subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- ///create 125 (5x5x5) dynamic object
- #define ARRAY_SIZE_X 5
- #define ARRAY_SIZE_Y 5
- #define ARRAY_SIZE_Z 5
- //maximum number of objects (and allow user to shoot additional boxes)
- #define MAX_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z + 1024)
- ///scaling of the objects (0.1 = 20 centimeter boxes )
- #define SCALING 1.
- #define START_POS_X -5
- #define START_POS_Y -5
- #define START_POS_Z -3
- #include "RollingFrictionDemo.h"
- ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
- #include "btBulletDynamicsCommon.h"
- #include <stdio.h> //printf debugging
- #include "../CommonInterfaces/CommonRigidBodyBase.h"
- #include "../Utils/b3ResourcePath.h"
- ///The RollingFrictionDemo shows the use of rolling friction.
- ///Spheres will come to a rest on a sloped plane using a constraint. Damping cannot achieve the same.
- ///Generally it is best to leave the rolling friction coefficient zero (or close to zero).
- class RollingFrictionDemo : public CommonRigidBodyBase
- {
- public:
-
- RollingFrictionDemo(struct GUIHelperInterface* helper)
- :CommonRigidBodyBase(helper)
- {
- }
- virtual ~RollingFrictionDemo()
- {
-
- }
- void initPhysics();
-
- void exitPhysics();
-
- void resetCamera()
- {
- float dist = 35;
- float pitch = 0;
- float yaw = 14;
- float targetPos[3]={0,0,0};
- m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]);
- }
-
- };
- void RollingFrictionDemo::initPhysics()
- {
-
- m_guiHelper->setUpAxis(2);
-
-
- ///collision configuration contains default setup for memory, collision setup
- m_collisionConfiguration = new btDefaultCollisionConfiguration();
- //m_collisionConfiguration->setConvexConvexMultipointIterations();
- ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
- m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
- m_broadphase = new btDbvtBroadphase();
- ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
- btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
- m_solver = sol;
- m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
- // m_dynamicsWorld->getSolverInfo().m_singleAxisRollingFrictionThreshold = 0.f;//faster but lower quality
- m_dynamicsWorld->setGravity(btVector3(0,0,-10));
- m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
-
- {
- ///create a few basic rigid bodies
- btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.),btScalar(5.),btScalar(25.)));
-
- m_collisionShapes.push_back(groundShape);
- btTransform groundTransform;
- groundTransform.setIdentity();
- groundTransform.setOrigin(btVector3(0,0,-28));
- groundTransform.setRotation(btQuaternion(btVector3(0,1,0),SIMD_PI*0.03));
- //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
- btScalar mass(0.);
- //rigidbody is dynamic if and only if mass is non zero, otherwise static
- bool isDynamic = (mass != 0.f);
- btVector3 localInertia(0,0,0);
- if (isDynamic)
- groundShape->calculateLocalInertia(mass,localInertia);
- //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
- btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
- btRigidBody* body = new btRigidBody(rbInfo);
- body->setFriction(1);
- body->setRollingFriction(1);
- //add the body to the dynamics world
- m_dynamicsWorld->addRigidBody(body);
- }
- {
- ///create a few basic rigid bodies
- btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(100.),btScalar(100.),btScalar(50.)));
-
- m_collisionShapes.push_back(groundShape);
- btTransform groundTransform;
- groundTransform.setIdentity();
- groundTransform.setOrigin(btVector3(0,0,-54));
- //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
- btScalar mass(0.);
- //rigidbody is dynamic if and only if mass is non zero, otherwise static
- bool isDynamic = (mass != 0.f);
- btVector3 localInertia(0,0,0);
- if (isDynamic)
- groundShape->calculateLocalInertia(mass,localInertia);
- //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
- btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
- btRigidBody* body = new btRigidBody(rbInfo);
- body->setFriction(1);
- body->setRollingFriction(1);
- //add the body to the dynamics world
- m_dynamicsWorld->addRigidBody(body);
- }
- {
- //create a few dynamic rigidbodies
- // Re-using the same collision is better for memory usage and performance
- #define NUM_SHAPES 10
- btCollisionShape* colShapes[NUM_SHAPES] = {
- new btSphereShape(btScalar(0.5)),
- new btCapsuleShape(0.25,0.5),
- new btCapsuleShapeX(0.25,0.5),
- new btCapsuleShapeZ(0.25,0.5),
- new btConeShape(0.25,0.5),
- new btConeShapeX(0.25,0.5),
- new btConeShapeZ(0.25,0.5),
- new btCylinderShape(btVector3(0.25,0.5,0.25)),
- new btCylinderShapeX(btVector3(0.5,0.25,0.25)),
- new btCylinderShapeZ(btVector3(0.25,0.25,0.5)),
- };
- for (int i=0;i<NUM_SHAPES;i++)
- m_collisionShapes.push_back(colShapes[i]);
- /// Create Dynamic Objects
- btTransform startTransform;
- startTransform.setIdentity();
- btScalar mass(1.f);
- //rigidbody is dynamic if and only if mass is non zero, otherwise static
-
- float start_x = START_POS_X - ARRAY_SIZE_X/2;
- float start_y = START_POS_Y;
- float start_z = START_POS_Z - ARRAY_SIZE_Z/2;
- {
- int shapeIndex = 0;
- for (int k=0;k<ARRAY_SIZE_Y;k++)
- {
- for (int i=0;i<ARRAY_SIZE_X;i++)
- {
- for(int j = 0;j<ARRAY_SIZE_Z;j++)
- {
- startTransform.setOrigin(SCALING*btVector3(
- btScalar(2.0*i + start_x),
- btScalar(2.0*j + start_z),
- btScalar(20+2.0*k + start_y)));
- shapeIndex++;
- btCollisionShape* colShape = colShapes[shapeIndex%NUM_SHAPES];
- bool isDynamic = (mass != 0.f);
- btVector3 localInertia(0,0,0);
- if (isDynamic)
- colShape->calculateLocalInertia(mass,localInertia);
- //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
- btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
- btRigidBody* body = new btRigidBody(rbInfo);
- body->setFriction(1.f);
- body->setRollingFriction(.3);
- body->setAnisotropicFriction(colShape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
- m_dynamicsWorld->addRigidBody(body);
- }
- }
- }
- }
- }
- m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
- if (0)
- {
- btSerializer* s = new btDefaultSerializer;
- m_dynamicsWorld->serialize(s);
- char resourcePath[1024];
- if (b3ResourcePath::findResourcePath("slope.bullet",resourcePath,1024))
- {
- FILE* f = fopen(resourcePath,"wb");
- fwrite(s->getBufferPointer(),s->getCurrentBufferSize(),1,f);
- fclose(f);
- }
- }
- }
- void RollingFrictionDemo::exitPhysics()
- {
- //cleanup in the reverse order of creation/initialization
- //remove the rigidbodies from the dynamics world and delete them
- int i;
- for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
- {
- btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
- btRigidBody* body = btRigidBody::upcast(obj);
- if (body && body->getMotionState())
- {
- delete body->getMotionState();
- }
- m_dynamicsWorld->removeCollisionObject( obj );
- delete obj;
- }
- //delete collision shapes
- for (int j=0;j<m_collisionShapes.size();j++)
- {
- btCollisionShape* shape = m_collisionShapes[j];
- delete shape;
- }
- m_collisionShapes.clear();
- delete m_dynamicsWorld;
-
- delete m_solver;
-
- delete m_broadphase;
-
- delete m_dispatcher;
- delete m_collisionConfiguration;
-
- }
- class CommonExampleInterface* RollingFrictionCreateFunc(struct CommonExampleOptions& options)
- {
- return new RollingFrictionDemo(options.m_guiHelper);
-
- }
|