#include "GyroscopicSetup.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" struct GyroscopicSetup : public CommonRigidBodyBase { GyroscopicSetup(struct GUIHelperInterface* helper); virtual ~GyroscopicSetup() { } virtual void initPhysics(); virtual void physicsDebugDraw(int debugFlags); void resetCamera() { float dist = 20; float pitch = -16; float yaw = 180; float targetPos[3] = {-2.4, 0.4, -0.24}; m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; static int gyroflags[4] = { 0, //none, no gyroscopic term BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT, BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD, BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY}; static const char* gyroNames[4] = { "No Gyroscopic", "Explicit", "Implicit (World)", "Implicit (Body)"}; GyroscopicSetup::GyroscopicSetup(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper) { } void GyroscopicSetup::initPhysics() { m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); m_dynamicsWorld->setGravity(btVector3(0, 0, 0)); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); btVector3 positions[4] = { btVector3(-10, 8, 4), btVector3(-5, 8, 4), btVector3(0, 8, 4), btVector3(5, 8, 4), }; for (int i = 0; i < 4; i++) { btCylinderShapeZ* pin = new btCylinderShapeZ(btVector3(0.1, 0.1, 0.2)); btBoxShape* box = new btBoxShape(btVector3(1, 0.1, 0.1)); box->setMargin(0.01); pin->setMargin(0.01); btCompoundShape* compound = new btCompoundShape(); compound->addChildShape(btTransform::getIdentity(), pin); btTransform offsetBox(btMatrix3x3::getIdentity(), btVector3(0, 0, 0.2)); compound->addChildShape(offsetBox, box); btScalar masses[2] = {0.3, 0.1}; btVector3 localInertia; btTransform principal; compound->calculatePrincipalAxisTransform(masses, principal, localInertia); btRigidBody* body = new btRigidBody(1, 0, compound, localInertia); btTransform tr; tr.setIdentity(); tr.setOrigin(positions[i]); body->setCenterOfMassTransform(tr); body->setAngularVelocity(btVector3(0, 0.1, 10)); //51)); //body->setLinearVelocity(btVector3(3, 0, 0)); body->setFriction(btSqrt(1)); m_dynamicsWorld->addRigidBody(body); body->setFlags(gyroflags[i]); m_dynamicsWorld->getSolverInfo().m_maxGyroscopicForce = 10.f; body->setDamping(0.0000f, 0.000f); } { //btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(0.5))); btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 0); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0, 0, 0)); btRigidBody* groundBody; groundBody = createRigidBody(0, groundTransform, groundShape); groundBody->setFriction(btSqrt(2)); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } void GyroscopicSetup::physicsDebugDraw(int debugFlags) { CommonRigidBodyBase::physicsDebugDraw(debugFlags); //render method names above objects for (int i = 0; i < m_dynamicsWorld->getNumCollisionObjects(); i++) { btRigidBody* body = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[i]); if (body && body->getInvMass() > 0) { btTransform tr = body->getWorldTransform(); btVector3 pos = tr.getOrigin() + btVector3(0, 0, 2); btScalar size = 1; m_guiHelper->drawText3D(gyroNames[i], pos.x(), pos.y(), pos.z(), size); } } } class CommonExampleInterface* GyroscopicCreateFunc(CommonExampleOptions& options) { return new GyroscopicSetup(options.m_guiHelper); }