XML
<?xml version="1.0"?>
<!-- Rigid object in a scene -->
<Node name="root" dt="0.01" gravity="0 0 0">
<!-- When using components from SOFA modules, plugins, you can import them -->
<RequiredPlugin name="Sofa.Component.StateContainer"/> <!-- Needed to use components [MechanicalObject] -->
<DefaultAnimationLoop />
<Node name="Particle" bbox="-1 -1 -1 1 1 1">
<!-- Rigid DOFS = x y z + quaternion -->
<MechanicalObject template="Rigid3d" name="myParticle" position="0 0 0 0 0 0 1" showObject="1" />
</Node>
</Node>
1.MechanicalObject
MechanicalObject 是 SOFA 里的一个 passive component。它不计算东西,只保存每个时间步我们关心的状态,比如自由度、位置、位移、速度。MechanicalObject 可以理解为状态容器。
2.template="Rigid3d"
当你读一个 SOFA 文件时,看到一个 child node,首先要看里面有没有 MechanicalObject;如果有,最先看它的 template。因为 template 决定这个对象的 自由度性质。
template="Rigid3d" 意思是:这个 Particle 是一个三维刚体(不是可变形物体)。
3.Rigid3d 和 Vec3d 的区别
(1)Vec3d
如果是 template="Vec3d",那一般表示每个点只有 x, y, z,也就是三维空间中的一个点的位置。适合可变形物体的节点,比如软体、网格点。每个点都可以有自己的位置和速度。
(2)Rigid3d
如果是 template="Rigid3d",那表示一个刚体自由度,不只是位置,还包括方向。
一个刚体在 3D 空间中需要:位置:x y z 姿态:orientation
这里前 3 个数是 x y z,后 4 个数是四元数 quaternion,用来表示方向。
position="0 0 0 0 0 0 1" 可以拆成:
0 0 0 → 位置 x y z
0 0 0 1 → 姿态 quaternion
所以 position="0 0 0 0 0 0 1" 不是 7 个点,而是一个刚体状态。意识是这个刚体初始状态是:位置在原点、姿态是默认姿态。
四元数 quaternion = 用来表示三维旋转/姿态的方法,它本质上就是 orientation,表示方向/姿态。
4.速度不是 7 个数
Rigid3d 的 position 状态 是:x y z + quaternion = 3 + 4 = 7
但它的 velocity 速度状态 不是 7 个数,而是:线速度 vx vy vz + 角速度 wx wy wz = 3 + 3 = 6
因为姿态用四元数表示,但姿态变化率通常用绕 x/y/z 的角速度表示。
5.showObject="1"
showObject 是一个显示/调试选项。它会强制把这个刚体 frame 显示出来,让你看到这个刚体粒子在哪里。
showObject="1":显示这个对象/小坐标架
showObject="0":不显示
6.RequiredPlugin
<RequiredPlugin name="Sofa.Component.StateContainer"/>
MechanicalObject 这个组件属于 Sofa.Component.StateContainer 这个模块。
RequiredPlugin = 加载某个 SOFA 模块
这里它是为了使用 MechanicalObject 这个组件。
如果不写,有时候也能运行,因为这是 SOFA 自带库,但终端里会有 warning。写上它会让场景文件更清楚、更规范。