zoukankan      html  css  js  c++  java
  • Bullet 学习笔记之 软体仿真流程(一)

    下面梳理软体对象的仿真过程。

    在例程 VolumetricDeformable 中,使用了 btDeformableMultiBodyDynamicsWrold 类以及 btDeformableBodySolver 类,因此,该仿真流程即为对 btDeformableMultiBodyDynamicsWroldbtDeformableBodySolver 的梳理。


    1、仿真主流程

    仿真主要流程,由 btDeformableMultiBodyDynamicsWrold 类控制,细节部分则由 btDeformableBodySolver 类控制。主要有以下几个步骤:

    • 初始化工作
    • 计算无约束运动
    • 碰撞检测
    • 求解约束
    • 位移积分
    (1) 初始化工作

    细节略

    (2)计算无约束运动

    这部分内容由函数 btDeformableRigidDynamicsWorld::predictUnconstraintMotion(..) 完成。是计算场景中的物体(软体/刚体)仅在重力和弹性力作用下的运动,不考虑约束、接触等。具体来说,这部分工作包含了以下内容:

    btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep);
    btDeformableBodySolver::predictMotion(timeStep);
    

    btDeformableBodySolver::predictMotion(..) 中,计算软体在重力、弹性力作用下的运动,得到了一个临时位置(a temporary position),存放在 node.m_q 中,在此后的仿真步骤中,是基于这个临时位置做碰撞检测。

    具体内容参考文章:btDeformableBodySolver::predictMotion(..)

    (3) 碰撞检测

    这部分内容由函数 btDiscreteDynamicsWorld::performDiscreteCollisionDetection() 和 函数 btDeformableRigidDynamicsWorld::softBodySelfCollision() 完成。在计算得到本时间步骤,场景中物体的临时位置(temporary position)后,进行了碰撞检测。在仿真场景中,已将所有软体作为碰撞对象加入到了 btDiscreteDynamicsWorld 中,因此,直接对两两做碰撞检测就可以了。此外,如果需要对软体做自碰撞检测,还需要执行 psb->defaultCollisionHandler(psb) 函数。

    软体碰撞检测所执行的函数应该是 btSoftBody::defaultCollisionHandler(..) ,得到的结果应该是放在了 btSoftBody::m_nodeRigidContacts btSoftBody::m_faceNodeContacts btSoftBody::m_faceRigidContacts 里面。不同的检测方法,应该是对应于不同的碰撞结果的。

    (4)求解约束

    (略)

    (5)位移积分

    这部分工作由函数 btDeformableRigidDynamicsWorld::integrateTransforms(..) 完成。具体来说,应该有刚体位移积分 btDiscreteDynamicsWorld::integrateTransforms(..) 和软体位移积分两部分组成。其中,软体位移积分可用以下公式表述:

    node.m_x = node.m_x + timeStep * node.m_v;
    

    也就是说,在约束求解时,计算得到的是软体在本时间步骤内的速度值 node.m_v


    下面,详细介绍其中的一些细节。

    2、软体的无约束运动

    软体的无约束运动计算,是由函数 srDeformableBodySolver::predictMotion(..) 完成,其具体步骤可如下表示:

    calculate forces applied on node
    node.m_v += f / m
    node.m_q = m_x + m_v * dt
    

    首先,通过函数 btDeformableBackwardEulerObjective::applyExplicitForce(..) 计算得到作用在软体质点上的合力(只考虑重力和弹性力),并更新软体的(临时)速度。具体来说,分为三个部分:(1)通过函数 btSoftBody::advanceDeformation() 计算当前软体的形变度量,如 F、J、C、tr(C) 等。(2)通过函数 btDeformableLagrangianForce::addScaledExplicitForce() 计算得到作用在节点上的合力,(统一存放在一个数组中)。(3)通过函数 btDeformableBackwardEulerObjective::applyForce(..) 计算软体节点的速度值,即 node.m_v += f / m 。

    接下来,通过函数 btDeformableBodySolver::predictDeformableMotion(..) 更新软体节点的(临时)位置,即 node.m_q = m_x + m_v * dt 。

    此外,在这个过程中,还涉及到碰撞对象(信息)的更新,比如,更新碰撞包围盒的边界信息等,(毕竟软体发生了形变)。这部分工作主要涉及到成员变量 btSoftBody::m_ndbvtbtSoftBody::m_ndbvt 的更新。同时,清空上一个时间步骤中的碰撞检测结果,即成员变量 btSoftBody::m_nodeRigidContacts btSoftBody::m_faceRigidContacts btSoftBody::m_faceNodeContacts

    3、碰撞检测

    先大致弄清楚碰撞检测的类型,执行函数,结果存放在哪儿,以及结果中都包含了那些信息

    4、约束求解

    约束求解是这里面最为复杂的内容了,专门写一篇笔记:软体的约束求解

    5、位置更新

    这部分最简单了,更新得到本时间步骤的最终位置。


    小结

    (待续)

  • 相关阅读:
    POJ 3278 Catch That Cow (附有Runtime Error和Wrong Answer的常见原因)
    POJ 2251 Dungeon Master (三维BFS)
    HDU 1372 Knight moves
    [Ubuntu] <uptime>命令
    【C】哈夫曼编码
    【C++】开辟数组未初始化问题
    免费下载IEEE论文
    随机换装
    BFS解迷宫问题(Go实现)
    DFS解迷宫问题(Go实现)
  • 原文地址:https://www.cnblogs.com/wghou09/p/13174645.html
Copyright © 2011-2022 走看看