案例位置:examples/Cuda/Rigidbody/GL_Bricks
功能介绍:该案例主要用于测试刚体系统的仿真功能。案例展示了 RigidBodySystem 类的的基本使用。刚体系统已经包含球体、圆柱体、圆锥体、长方体等常用的几何体仿真模型。用户只需要设置几何形体的中心位置、边长以及旋转矩阵等简单的参数就可以构成出常见的几何模型。
案例说明:案例中展示了刚体动力学功能。初始化时地面放置了许多正方体刚体,空中放置了四面体和球体刚体。程序运行后四面体和球体掉落,与正方体刚体发生碰撞。该案例主要用于测试PeriDyno刚体动力学系统是否正确。
接下来介绍案例的实现过程:
std::shared_ptr<SceneGraph> scn = std::make_shared<SceneGraph>();
auto rigid = scn->addNode(std::make_shared<RigidBodySystem<DataType3f>>());
RigidBodyInfo rigidBody;
rigidBody.linearVelocity = Vec3f(0.5, 0, 0);
BoxInfo box;
for (int i = 8; i > 1; i--)
for (int j = 0; j < i + 1; j++)
{
box.center = 0.5f * Vec3f(0.5f, 1.1 - 0.13 * i, 0.12f + 0.21 * j + 0.1 * (8 - i));
box.halfLength = 0.5f * Vec3f(0.065, 0.065, 0.1);
rigid->addBox(box, rigidBody);
}
SphereInfo sphere;
sphere.center = Vec3f(0.5f, 0.75f, 0.5f);
sphere.radius = 0.025f;
RigidBodyInfo rigidSphere;
rigid->addSphere(sphere, rigidSphere);
sphere.center = Vec3f(0.5f, 0.95f, 0.5f);
sphere.radius = 0.025f;
rigid->addSphere(sphere, rigidSphere);
sphere.center = Vec3f(0.5f, 0.65f, 0.5f);
sphere.radius = 0.05f;
rigid->addSphere(sphere, rigidSphere);
TetInfo tet;
tet.v[0] = Vec3f(0.5f, 1.1f, 0.5f);
tet.v[1] = Vec3f(0.5f, 1.2f, 0.5f);
tet.v[2] = Vec3f(0.6f, 1.1f, 0.5f);
tet.v[3] = Vec3f(0.5f, 1.1f, 0.6f);
rigid->addTet(tet, rigidSphere);
auto mapper = std::make_shared<DiscreteElementsToTriangleSet<DataType3f>>();
rigid->stateTopology()->connect(mapper->inDiscreteElements());
rigid->graphicsPipeline()->pushModule(mapper);
auto sRender = std::make_shared<GLSurfaceVisualModule>();
sRender->setColor(Vec3f(1, 1, 0));
mapper->outTriangleSet()->connect(sRender->inTriangleSet());
rigid->graphicsPipeline()->pushModule(sRender);
//TODO: to enable using internal modules inside a node
//Visualize contact normals
auto elementQuery = std::make_shared<NeighborElementQuery<DataType3f>>();
rigid->stateTopology()->connect(elementQuery->inDiscreteElements());
rigid->stateCollisionMask()->connect(elementQuery->inCollisionMask());
rigid->graphicsPipeline()->pushModule(elementQuery);
auto contactMapper = std::make_shared<ContactsToEdgeSet<DataType3f>>();
elementQuery->outContacts()->connect(contactMapper->inContacts());
contactMapper->varScale()->setValue(0.02);
rigid->graphicsPipeline()->pushModule(contactMapper);
auto wireRender = std::make_shared<GLWireframeVisualModule>();
wireRender->setColor(Vec3f(0, 1, 0));
contactMapper->outEdgeSet()->connect(wireRender->inEdgeSet());
rigid->graphicsPipeline()->pushModule(wireRender);
//Visualize contact points
auto contactPointMapper = std::make_shared<ContactsToPointSet<DataType3f>>();
elementQuery->outContacts()->connect(contactPointMapper->inContacts());
rigid->graphicsPipeline()->pushModule(contactPointMapper);
auto pointRender = std::make_shared<GLPointVisualModule>();
pointRender->setColor(Vec3f(1, 0, 0));
contactPointMapper->outPointSet()->connect(pointRender->inPointSet());
rigid->graphicsPipeline()->pushModule(pointRender);