在 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 等状态,以及 numTetMeshBuffer 、numTetMesh 等数量统计。
总体上来讲,可以这么解释:(FmTetMeshBuffer**)tetMeshBuffers 指向了一个数组 tetMeshBuffers[xx],其中每一个单元称之为一个 Slot ,存放有一个 TetMeshBuffer*指针,该指针又指向了一个 TetMeshBuffer 实例,参见以上图片。
TetMeshBuffer*指针在 tetMeshBuffers[xx] 中的位置,记作了 meshBufferIdx,并写入了 TetMeshBuffer::bufferId 中。此外,numTetMeshBufferSlots 是 tetMeshBuffers[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 指向一个数组,建立由 tetMesh 的 objectId 到 指向该 tetMesh 的指针的映射。用法为,gScene->tetMeshPtrFromId[tetMesh->objectId] = tetMesh
FmScene::tetMeshIdxFromId 指向一个数组,建立由 tetMesh 的 objectId 到 该 objectId 在 FmScene::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::maxRigidBodies 为 FmScene 中可容纳的 rigidBody 的最大个数。在初始化时即确定下来,并由此确定 rigidBodies[] 数组等的大小。
FmScene::numTetMeshBufferSlots 同理。
FmScene::numAwakeTetMeshes 同理。
FmScene::numAwakenedTetMeshes 同理。
FmScene::numTetMeshesTotal 同理。
FmScene::maxTetMeshBuffers 该 gScene 中可容纳的 tetMeshBuffer 的数量。
FmScene::maxTetMeshes 该 gScene 中可容纳的 tetMesh 的数量。在初始化时便确定下来,由此确定 sleepingTetMeshIds[] tetMeshIdxFromId[] 等数组的大小。
FmScene::maxSceneVerts
FmScene::maxTetMeshBufferFeatures
FmScene::numSleepingTetMeshes
FmScene::numSleepingRigidBodies
以上便是 FmScene 中各个成员函数的含义,并顺带介绍了 FmTetMeshBuffer FmTetMesh FmRigidBody 等的数据结构,以及其中的 bufferId objectId ptr 等编号方式,以及 awake sleeping 等状体的记录方式。
原文:https://www.cnblogs.com/wghou09/p/12702168.html