• 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 等状体的记录方式。

  • 相关阅读:
    【PyTorch深度学习60分钟快速入门 】Part1:PyTorch是什么?
    如何编写一个gulp插件
    进阶之初探nodeJS
    模拟Vue之数据驱动5
    模拟Vue之数据驱动4
    模拟Vue之数据驱动3
    模拟Vue之数据驱动2
    树结构之JavaScript
    模拟Vue之数据驱动1
    CORS详解[译]
  • 原文地址:https://www.cnblogs.com/wghou09/p/12702168.html
Copyright © 2020-2023  润新知