CDynamics3DCylinderModel::CDynamics3DCylinderModel(CDynamics3DEngine& c_engine, CCylinderEntity& c_cylinder) : CDynamics3DSingleBodyObjectModel(c_engine, c_cylinder), m_pcBody(nullptr) { /* Fetch a collision shape for this model */ std::shared_ptr<btCollisionShape> ptrShape = CDynamics3DShapeManager::RequestBox( btVector3(c_cylinder.GetRadius(), c_cylinder.GetHeight() * 0.5f, c_cylinder.GetRadius())); /* Get the origin anchor */ SAnchor& sAnchor = c_cylinder.GetEmbodiedEntity().GetOriginAnchor(); const CQuaternion& cOrientation = sAnchor.Orientation; const CVector3& cPosition = sAnchor.Position; /* Calculate the start transform */ const btTransform& cStartTransform = btTransform( btQuaternion(cOrientation.GetX(), cOrientation.GetZ(), -cOrientation.GetY(), cOrientation.GetW()), btVector3(cPosition.GetX(), cPosition.GetZ(), -cPosition.GetY())); /* Calculate the center of mass offset */ const btTransform& cCenterOfMassOffset = btTransform( btQuaternion(0.0f, 0.0f, 0.0f, 1.0f), btVector3(0.0f, -c_cylinder.GetHeight() * 0.5f, 0.0f)); /* Initialize mass and inertia to zero (static object) */ Real fMass = 0.0f; btVector3 cInertia(0.0f, 0.0f, 0.0f); /* If the cylinder is movable calculate its mass and inertia */ if(c_cylinder.GetEmbodiedEntity().IsMovable()) { fMass = c_cylinder.GetMass(); ptrShape->calculateLocalInertia(fMass, cInertia); } /* Use the default friction */ btScalar fFriction = GetEngine().GetDefaultFriction(); /* Set up the body */ CBody* m_pcBody = new CBody(*this, sAnchor, ptrShape, CBody::SData(cStartTransform, cCenterOfMassOffset, cInertia, fMass, fFriction)); /* Transfer the body to the base class */ m_vecBodies.push_back(m_pcBody); /* Synchronize with the entity in the space */ UpdateEntityStatus(); }
void CQTOpenGLCylinder::Draw(CCylinderEntity& c_entity) { /* Draw the body */ if(c_entity.GetEmbodiedEntity().IsMovable()) { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, MOVABLE_COLOR); } else { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, NONMOVABLE_COLOR); } glPushMatrix(); glScalef(c_entity.GetRadius(), c_entity.GetRadius(), c_entity.GetHeight()); glCallList(m_unBodyList); glPopMatrix(); }
CDynamics2DCylinderEntity::CDynamics2DCylinderEntity(CDynamics2DEngine& c_engine, CCylinderEntity& c_entity) : CDynamics2DEntity(c_engine, c_entity.GetEmbodiedEntity()), m_cCylinderEntity(c_entity), m_fMass(c_entity.GetMass()), m_ptShape(NULL), m_ptBody(NULL) { /* Get the radius of the entity */ Real fRadius = c_entity.GetRadius(); m_fHalfHeight = c_entity.GetHeight() * 0.5f; /* Create a circle object in the physics space */ const CVector3& cPosition = GetEmbodiedEntity().GetPosition(); if(c_entity.IsMovable()) { /* The cylinder is movable */ /* Create the body */ m_ptBody = cpSpaceAddBody(m_cEngine.GetPhysicsSpace(), cpBodyNew(m_fMass, cpMomentForCircle(m_fMass, 0, fRadius + fRadius, cpvzero))); m_ptBody->p = cpv(cPosition.GetX(), cPosition.GetY()); CRadians cXAngle, cYAngle, cZAngle; GetEmbodiedEntity().GetOrientation().ToEulerAngles(cZAngle, cYAngle, cXAngle); cpBodySetAngle(m_ptBody, cZAngle.GetValue()); /* Create the geometry */ m_ptShape = cpSpaceAddShape(m_cEngine.GetPhysicsSpace(), cpCircleShapeNew(m_ptBody, fRadius, cpvzero)); /* This object is grippable */ m_ptShape->collision_type = CDynamics2DEngine::SHAPE_GRIPPABLE; m_ptShape->data = reinterpret_cast<void*>(&c_entity); /* No elasticity */ m_ptShape->e = 0.0; /* Lots surface contact friction to help pushing */ m_ptShape->u = 0.7; /* Friction with ground */ m_ptLinearFriction = cpSpaceAddConstraint(m_cEngine.GetPhysicsSpace(), cpPivotJointNew2(m_cEngine.GetGroundBody(), m_ptBody, cpvzero, cpvzero)); m_ptLinearFriction->biasCoef = 0.0f; // disable joint correction m_ptLinearFriction->maxForce = 1.0f; // emulate linear friction m_ptAngularFriction = cpSpaceAddConstraint(m_cEngine.GetPhysicsSpace(), cpGearJointNew(m_cEngine.GetGroundBody(), m_ptBody, 0.0f, 1.0f)); m_ptAngularFriction->biasCoef = 0.0f; // disable joint correction m_ptAngularFriction->maxForce = 5.0f; // emulate angular friction } else { /* The cylinder is not movable */ /* Create the geometry */ m_ptShape = cpSpaceAddStaticShape(m_cEngine.GetPhysicsSpace(), cpCircleShapeNew(m_cEngine.GetGroundBody(), fRadius, cpv(cPosition.GetX(), cPosition.GetY()))); /* This object is normal */ m_ptShape->collision_type = CDynamics2DEngine::SHAPE_NORMAL; m_ptShape->data = reinterpret_cast<void*>(&c_entity); /* No elasticity */ m_ptShape->e = 0.0; /* Little contact friction to help sliding away */ m_ptShape->u = 0.1; } }