刚体碰撞

1、刚体碰撞

案例位置examples/Cuda/Rigidbody/GL_CollisionDetectionIn3D

功能介绍:该案例主要用于测试刚体系统的碰撞功能。

案例说明:案例展示了三个场景,分别是正方体与正方体的碰撞、四面体与四面体的碰撞,以及四面体与正方体的碰撞。通过不同形状的刚体间的碰撞,测试刚体碰撞功能是否正确。

2、程序实现

接下来介绍案例的实现过程:

  • 创建场景图及渲染节点:
	std::shared_ptr<SceneGraph> scn = std::make_shared<SceneGraph>();

	auto rigid = scn->addNode(std::make_shared<RigidBodySystem<DataType3f>>());

	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));
	sRender->setAlpha(0.8f);
	mapper->outTriangleSet()->connect(sRender->inTriangleSet());
	rigid->graphicsPipeline()->pushModule(sRender);


	//TODO: to enable using internal modules inside a node
	auto elementQuery = std::make_shared<NeighborElementQuery<DataType3f>>();
	rigid->stateTopology()->connect(elementQuery->inDiscreteElements());
	rigid->stateCollisionMask()->connect(elementQuery->inCollisionMask());
	rigid->graphicsPipeline()->pushModule(elementQuery);

	//Visualize contact normals
	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, 0, 1));
	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);

	createTwoBoxes(rigid);//调用两个正方体碰撞
	createTwoTets(rigid);//调用两个四面体碰撞
	createTetBox(rigid);//调用四面体和正方体碰撞

  • 创建两个刚体碰撞场景:
void createTwoBoxes(std::shared_ptr<RigidBodySystem<DataType3f>> rigid)
{
	RigidBodyInfo rigidBody;
	rigidBody.linearVelocity = Vec3f(0.0, 0, 0);
	BoxInfo box;
	box.center = Vec3f(-0.3, 0.1, 0.5);
	box.halfLength = Vec3f(0.1, 0.1, 0.1);
	rigid->addBox(box, rigidBody);

	rigidBody.linearVelocity = Vec3f(0.0, 0, 0);
	box.center = Vec3f(-0.3, 0.3, 0.59);
	box.halfLength = Vec3f(0.1, 0.1, 0.1);
	rigid->addBox(box, rigidBody);
}
  • 创建两个四面体碰撞场景:
void createTwoTets(std::shared_ptr<RigidBodySystem<DataType3f>> rigid)
{
	RigidBodyInfo rigidBody;
	rigidBody.linearVelocity = Vec3f(0.0, 0, 0);
	
	TetInfo tet0;
	tet0.v[0] = Vec3f(0.45f, 0.3f, 0.45f);
	tet0.v[1] = Vec3f(0.45f, 0.55f, 0.45f);
	tet0.v[2] = Vec3f(0.7f, 0.3f, 0.45f);
	tet0.v[3] = Vec3f(0.45f, 0.3f, 0.7f);
	rigid->addTet(tet0, rigidBody);

	TetInfo tet1;
	tet1.v[0] = Vec3f(0.45f, 0.0f, 0.45f);
	tet1.v[1] = Vec3f(0.45f, 0.25f, 0.45f);
	tet1.v[2] = Vec3f(0.7f, 0.0f, 0.45f);
	tet1.v[3] = Vec3f(0.45f, 0.0f, 0.7f);
	rigid->addTet(tet1, rigidBody);
}
  • 创建四面体和正方体碰撞场景:
void createTetBox(std::shared_ptr<RigidBodySystem<DataType3f>> rigid) {

	RigidBodyInfo rigidBody;
	rigidBody.linearVelocity = Vec3f(0.0, 0, 0);
	BoxInfo box;
	box.center = Vec3f(1.3, 0.1, 0.5);
	box.halfLength = Vec3f(0.1, 0.1, 0.1);
	rigid->addBox(box, rigidBody);

	TetInfo tet0;
	tet0.v[0] = Vec3f(1.25f, 0.25f, 0.45f);
	tet0.v[1] = Vec3f(1.25f, 0.5f, 0.45f);
	tet0.v[2] = Vec3f(1.5f, 0.25f, 0.45f);
	tet0.v[3] = Vec3f(1.25f, 0.25f, 0.7f);
	rigid->addTet(tet0, rigidBody);
}