现实两足骨架的物理模拟

时间:2011-05-13 21:37:45

标签: physics simulation game-physics physics-engine bulletphysics

我希望利用子弹物理学或类似的物理引擎来创建一个有两条腿的人体状的逼真骨架模拟。也就是说,在两条“腿”的顶部创建一个由圆形质量制成的“身体”模拟,其中每条腿由3个实心连接,通过3个关节连接,每个关节具有一定的自由度和有限的移动范围。每个方向,类似于人体臀部,膝盖和脚踝。

我的目标是一个真实的模型,因此只有当所有关节都正确平衡时它才会“站立”,否则它会掉落。

对现有教程或资源的任何指示,建议或指示表示赞赏!这看起来像是从头开始做的大量工作......

4 个答案:

答案 0 :(得分:6)

查看OpenSim项目(opensim.stanford.edu),该项目被生物力学界广泛用于研究人体运动,例如临床应用。在OpenSim中,人体模型通常由肌肉驱动,而不仅仅是关节处的扭矩。

OpenSim建立在Simbody多体动力学库之上。请参阅Simbody的这个示例,使用人形模型https://github.com/simbody/simbody/blob/master/Simbody/examples/JaredsDude.cpp开始运行。

答案 1 :(得分:4)

我正在研究类似的代码。我的方法是使用Bullet Physics Rag Doll Demo作为起点。它有一个布娃娃,身体部位由关节连接。

然后我使用Bullet物理动态控制演示来学习弯曲关节。目前具有挑战性的部分是设置所有参数。

我建议您学习如何创建两个由约束连接的刚体,然后激活约束马达以弯曲关节。

以下是我正在使用的一些代码,用于了解Bullet Physics中刚体和约束的工作原理。该代码创建了两个通过铰链约束连接的块。更新功能随时间缓慢地弯曲铰链约束。

现在我已经得到了这个,我将回到Rag Doll并调整关节。

class Simple
{
private:
    btScalar targetAngle;

    btCollisionShape* alphaCollisionShape;
    btCollisionShape* bravoCollisionShape;
    btRigidBody* alphaRigidBody;
    btRigidBody* bravoRigidBody;
    btHingeConstraint* hingeConstraint;

    btDynamicsWorld* dynamicsWorld;

public:
    ~Simple( void )
    {
    }

    btRigidBody* createRigidBody( btCollisionShape* collisionShape, 
                  btScalar mass, 
                  const btTransform& transform ) const
    {
    // calculate inertia
    btVector3 localInertia( 0.0f, 0.0f, 0.0f );
    collisionShape->calculateLocalInertia( mass, localInertia );    

    // create motion state
    btDefaultMotionState* defaultMotionState 
        = new btDefaultMotionState( transform );

    // create rigid body
    btRigidBody::btRigidBodyConstructionInfo rigidBodyConstructionInfo( 
        mass, defaultMotionState, collisionShape, localInertia );
    btRigidBody* rigidBody = new btRigidBody( rigidBodyConstructionInfo );      

    return rigidBody;
    }

    void Init( btDynamicsWorld* dynamicsWorld )
    {
    this->targetAngle = 0.0f;

    this->dynamicsWorld = dynamicsWorld;

    // create collision shapes
    const btVector3 alphaBoxHalfExtents( 0.5f, 0.5f, 0.5f );
    alphaCollisionShape = new btBoxShape( alphaBoxHalfExtents );

    //
    const btVector3 bravoBoxHalfExtents( 0.5f, 0.5f, 0.5f );
    bravoCollisionShape = new btBoxShape( bravoBoxHalfExtents );

    // create alpha rigid body
    const btScalar alphaMass = 10.0f;
    btTransform alphaTransform;
    alphaTransform.setIdentity();
    const btVector3 alphaOrigin( 54.0f, 0.5f, 50.0f );  
    alphaTransform.setOrigin( alphaOrigin );
    alphaRigidBody = createRigidBody( alphaCollisionShape, alphaMass, alphaTransform );
    dynamicsWorld->addRigidBody( alphaRigidBody );

    // create bravo rigid body
    const btScalar bravoMass = 1.0f;
    btTransform bravoTransform;
    bravoTransform.setIdentity();
    const btVector3 bravoOrigin( 56.0f, 0.5f, 50.0f );  
    bravoTransform.setOrigin( bravoOrigin );
    bravoRigidBody = createRigidBody( bravoCollisionShape, bravoMass, bravoTransform );
    dynamicsWorld->addRigidBody( bravoRigidBody );

    // create a constraint
    const btVector3 pivotInA( 1.0f, 0.0f, 0.0f );   
    const btVector3 pivotInB( -1.0f, 0.0f, 0.0f );
    btVector3 axisInA( 0.0f, 1.0f, 0.0f );
    btVector3 axisInB( 0.0f, 1.0f, 0.0f );
    bool useReferenceFrameA = false;
    hingeConstraint = new btHingeConstraint( 
        *alphaRigidBody,
        *bravoRigidBody,
        pivotInA,
        pivotInB,
        axisInA,
        axisInB,
        useReferenceFrameA );

    // set constraint limit
    const btScalar low = -M_PI;
    const btScalar high = M_PI;
    hingeConstraint->setLimit( low, high );

    // add constraint to the world
    const bool isDisableCollisionsBetweenLinkedBodies = false;
    dynamicsWorld->addConstraint( hingeConstraint, 
                      isDisableCollisionsBetweenLinkedBodies );
    }

    void Update( float deltaTime )
    {
    alphaRigidBody->activate();
    bravoRigidBody->activate();

    bool isEnableMotor = true;
    btScalar maxMotorImpulse = 1.0f; // 1.0f / 8.0f is about the minimum

    hingeConstraint->enableMotor( isEnableMotor );
    hingeConstraint->setMaxMotorImpulse( maxMotorImpulse );

    targetAngle += 0.1f * deltaTime;
    hingeConstraint->setMotorTarget( targetAngle, deltaTime );  
    }

};

答案 2 :(得分:1)

刚刚在Hase& amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; Yamazaki(2002),提供

  

提出了一种具有三维全身结构并由神经系统和肌肉 - 骨骼系统组成的模型,以精确模拟人类行走运动。人体的动力学由14刚性连杆系统和60个肌肉模型表示

答案 3 :(得分:0)

从头开始做起来很难,毫无疑问。我不知道你的目标是什么。但你不必重新设计轮子。你看过Unreal Engine了吗?您可能会发现可以在那里重用的东西许多游戏都建立在这个引擎的顶部。