zoukankan      html  css  js  c++  java
  • FEMFX 仿真之 场景类 FmScene

    在 FEMFX 中,场景类 FmScene 包含了仿真场景中几乎所有的对象、信息等,比如 tetMesh 、constraints、rigidBodies、params 等等数据。下面对 FmScene 中的成员变量进行梳理。

    具体的数据可分为三部分:软体(四面体单元)和刚体、约束及碰撞、其他


    一、软体及刚体相关

    其中,与软体(四面体单元)及刚体 有关的成员变量为:

    FmTetMeshBuffer**          tetMeshBuffers;             // Array of pointers to FmTetMesh buffers
    
    uint*                      awakeTetMeshIds;            // Ids of awake tet meshes in current simulation step (that are not SIMULATION_DISABLED)
    uint*                      awakeRigidBodyIds;          // Ids of awake rigid bodies in current simulation step (that are not SIMULATION_DISABLED)
    
    uint*                      sleepingTetMeshIds;         // Ids of sleeping tet meshes in current simulation step (that are not SIMULATION_DISABLED); points into awakeTetMeshIds array
    uint*                      sleepingRigidBodyIds;       // Ids of sleeping rigid bodies in current simulation step (that are not SIMULATION_DISABLED); points into awakeRigidBodyIds array
    
    FmTetMesh**                tetMeshPtrFromId;           // Map from FmTetMesh::objectId to tet mesh pointer
    uint*                      tetMeshIdxFromId;           // Map from FmTetMesh::objectId to index in awake ids list
    uint*                      rigidBodyIdxFromId;         // Map from FmRigidBody::objectId to index in awake ids list
    
    FmFreeIds                  freeTetMeshIds;             // Array of free mesh ids
    FmFreeIds                  freeRigidBodyIds;           // Array of free rigid body ids
    
    FmRigidBody**              rigidBodies;                // Array of pointers to rigid bodies
    
    uint                       numRigidBodySlots;          // Number of rigid body slots used, some of which may be marked deleted
    uint                       numAwakeRigidBodies;        // Number of awake rigid bodies simulated in current step
    uint                       numAwakenedRigidBodies;     // Number of rigid bodies added to ids list on waking
    uint                       maxRigidBodies;
    
    uint                       numTetMeshBufferSlots;      // Number of entries in tetMeshBuffers array (some of which may be NULL if removed)
    uint                       numAwakeTetMeshes;          // Number of awake tet meshes simulated in current step
    uint                       numAwakenedTetMeshes;       // Number of tet meshes added to ids list on waking
    uint                       numTetMeshesTotal;          // Number of tet meshes created in all tet mesh buffers, must not exceed maxTetMeshes
    uint                       maxTetMeshBuffers;
    uint                       maxTetMeshes;
    uint                       maxSceneVerts;
    uint                       maxTetMeshBufferFeatures;
    
    uint                       numSleepingTetMeshes;       // Number of sleeping tet meshes, placed at end awakeTetMeshIds array
    uint                       numSleepingRigidBodies;     // Number of sleeping rigid bodies, placed at end awakeRigidBodyIds array
    

    在这里解释一下相关成员变量的含义、存储方法,并由此探讨 FEMFX 仿真流程的执行理念。

    首先,解释一下刚体和软体在 FEMFX 中的类型定义。
    在 FEMFX 中,一个刚体定义为类型 FmRigidBody,由该刚体而产生的碎片,仍然依附与该刚体,相关数据也存储于该 FmRigidBody 中。此外, FmRigidBody中还包含了质量、摩擦系数、惯性张量、速度、以及碰撞相关的变量。其中,该刚体的碰撞对象仍然为 FmTetMeshBuffer 类型,这样一个好处就是,在碰撞检测时,不用区分是刚体还是软体。
    软体(也就是 tetMesh)定义为类型 FmTetMeshBuffer,由该软体产生的碎片,仍然依附于该软体,相关数据存储于 FmTetMeshBuffer 中。其中,包括了像 tetMesh 网格数据、solver 求解数据、碎片数据、节点数据等等。

    回到刚体、软体在 FmScene 中的存储。在 FEMFX 中,数据多以指针的形式存储。同样,对于 FmScene 中的刚体 FmRigidBody 和软体 FmTetMeshBuffer 也都是用二级指针指向一系列这些对象的指针数组。示意:

    此外,通过上述变量可知,与软体、刚体有关的还有 Ids Slot 等编号,及由指针到编号的映射 tetMeshPtrFromId ,以及 Awake Sleeping 等状态,以及 numTetMeshBuffernumTetMesh 等数量统计。

    总体上来讲,可以这么解释:(FmTetMeshBuffer**)tetMeshBuffers 指向了一个数组 tetMeshBuffers[xx],其中每一个单元称之为一个 Slot ,存放有一个 TetMeshBuffer*指针,该指针又指向了一个 TetMeshBuffer 实例,参见以上图片。

    TetMeshBuffer*指针在 tetMeshBuffers[xx] 中的位置,记作了 meshBufferIdx,并写入了 TetMeshBuffer::bufferId 中。此外,numTetMeshBufferSlotstetMeshBuffers[xx] 中已经被使用的单元个数,不过已使用的这些里面也存在被移除(NULL)的情况。

    前面提到,每个 TetMeshBuffer 对应一个初始时的软体,由此产生的碎片,也会存放在这里。也就是说,每个 TetMeshBuffer 里面有许多(>=1)个 TetMesh。每一个 TetMesh 都会拥有一个全局独一无二的 objectId 。(由 FmFreeIds 管理和生成。)
    那么,(1)各个 TetMesh 以指针的形式存放在 TetMeshBuffer::tetMeshes 中。并且,他的 objectId 则存放在 TetMesh::objectId 中。另外,在 FmScene::tetMeshPtrFromId[] 中,建立了由 objectId*TetMesh 指针的映射。
    (2)在每个 TetMesh 中,也记录了它是属于哪个 TetMeshBuffer 的。通过 TetMeshe::bufferId 记录。
    (3)每当添加新的 TetMesh 时,也会将它的 objectId 追加到 FmScene::awakeTetMeshIds[] 中。同时,在 FmScene::tetMeshIdxFromId[] 中也会建立从 id 到 idx 的映射,即 tetMeshIdxFromId[id] = idx 。这里面,id 为 tetMesh 的 objectId,而 idx 为该 tetMesh 的 objectId 在 FmScene::awakeTetMeshIds[] 中的位置,即 awakeTetMeshIds[Idx] = objectId 。

    刚体相关的成员函数也有类似的功能。


    下面分别介绍一下各个变量的具体含义和用法:

    FmScene::tetMeshBuffers 为二级指针,指向了存放 tetMeshBufer 的数组。用法为,gScene->tetMeshBuffers[bufferId] 指向了一个 tetMeshBuffer 实例。

    FmScene::awakeTetMeshIds 指向了存放 awake 状态的 tetMesh 的 objectId 的数组。也就是说,gScene->awakeTetMeshIds[0] 中存放的是一个处于 awake 状态的 tetMesh 实例的 objectId。在 tetMeshBuffers 中存放有许多个(>=1)tetMesh,存放在 FmTetMeshBuffers::tetMeshs[] 中,而每一个 tetMesh 都有一个全局独一无二的 objectId

    FmScene::awakeRigidBodyIds 同理,存放的处于 awake 状态的 rigidObject 的 objectId。

    FmScene::sleepingTetMeshIds 同理。

    FmScene::sleepingRigidBodyIds 同理。

    FmScene::tetMeshPtrFromId 指向一个数组,建立由 tetMeshobjectId 到 指向该 tetMesh 的指针的映射。用法为,gScene->tetMeshPtrFromId[tetMesh->objectId] = tetMesh

    FmScene::tetMeshIdxFromId 指向一个数组,建立由 tetMeshobjectId 到 该 objectIdFmScene::awakeRigidBodyIds 中位置的映射。用法为,idx = gScene->tetMeshIdxFromId[tetMesh->objectId]; gScene->awakeTetMeshIds[idx] == tetMesh->objectId;

    FmScene::rigidBodyIdxFromId 同理。

    FmScene::freeTetMeshIds

    FmScene::freeRigidBodyIds

    FmScene::rigidBodies 同理,为二级指针,指向了存放 FmRigidBody 的数组。

    FmScene::numRigidBodySlots 为已经被使用的 rigidBody Slot 的数量。在 rigidBodies[] 中,每个单元称之为一个 slot 。

    FmScene::numAwakeRigidBodies 为(xxx)处于 awake 状态的 rigidBody 的个数。

    FmScene::numAwakenedRigidBodies 为(xxx)处于 awake 状态的 rigidBody 的个数。

    FmScene::maxRigidBodiesFmScene 中可容纳的 rigidBody 的最大个数。在初始化时即确定下来,并由此确定 rigidBodies[] 数组等的大小。

    FmScene::numTetMeshBufferSlots 同理。

    FmScene::numAwakeTetMeshes 同理。

    FmScene::numAwakenedTetMeshes 同理。

    FmScene::numTetMeshesTotal 同理。

    FmScene::maxTetMeshBuffersgScene 中可容纳的 tetMeshBuffer 的数量。

    FmScene::maxTetMeshesgScene 中可容纳的 tetMesh 的数量。在初始化时便确定下来,由此确定 sleepingTetMeshIds[] tetMeshIdxFromId[] 等数组的大小。

    FmScene::maxSceneVerts

    FmScene::maxTetMeshBufferFeatures

    FmScene::numSleepingTetMeshes

    FmScene::numSleepingRigidBodies


    以上便是 FmScene 中各个成员函数的含义,并顺带介绍了 FmTetMeshBuffer FmTetMesh FmRigidBody 等的数据结构,以及其中的 bufferId objectId ptr 等编号方式,以及 awake sleeping 等状体的记录方式。

  • 相关阅读:
    I NEED A OFFER!
    水题 Codeforces Round #303 (Div. 2) A. Toy Cars
    模拟 HDOJ 5099 Comparison of Android versions
    模拟 HDOJ 5095 Linearization of the kernel functions in SVM
    贪心 HDOJ 5090 Game with Pearls
    Kruskal HDOJ 1863 畅通工程
    Kruskal HDOJ 1233 还是畅通工程
    并查集 HDOJ 1232 畅通工程
    DFS/并查集 Codeforces Round #286 (Div. 2) B
    水题 Codeforces Round #286 (Div. 2) A Mr. Kitayuta's Gift
  • 原文地址:https://www.cnblogs.com/wghou09/p/12702168.html
Copyright © 2011-2022 走看看