Frictions between pellets and rotating bowl

ant_the_mohican
Posts: 4
Joined: Wed Sep 09, 2015 3:46 am

Frictions between pellets and rotating bowl

Post by ant_the_mohican »

Dear all,

First thank you for the on-going and outstanding work on Bullet, especially regarding OpenCL integration.

But I have encountered a difficulty while trying to simulate a rotating bowl loaded with pellets.
I used "btBvhTriangleMeshShape" for the bowl, which is a concave mesh, and "btCapsuleShape" for the pellets.

Image

The pellets fall to the bottom, but then ignore the motion of the bowl.
I have set both "friction" and "rolling friction" to 1.0, with no effect.
You can test the actual simulation here: http://www.angstrom-precision.com/dump/Bowl.zip

Any help with understanding how to make the pellets react to the bowl rotation would be great.
Here are some snippets of the important code bits:

Code: Select all

void BasicExample::initPhysics()
{
	m_guiHelper->setUpAxis(1);
	createEmptyDynamicsWorld();	
	m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
	m_dynamicsWorld->setGravity( btVector3(0, -1000*scale, 0) );

	if (m_dynamicsWorld->getDebugDrawer())
		m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);	

	//load polishing bowl
	const char* fileName = "bowl.stl";
	char relativeFileName[1024];
	if (!b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024)) {
		b3Warning("Cannot find file %s\n", fileName);
		return;
	}

	GLInstanceGraphicsShape* glmesh = LoadMeshFromSTL(relativeFileName);
	if (glmesh && (glmesh->m_numvertices>0)) {
		btTriangleMesh* m_TriMesh = new btTriangleMesh();
		for (int i=0;i<glmesh->m_numvertices/3;i++) {
			m_TriMesh->addTriangle( btVector3(scale*glmesh->m_vertices->at(3*i+0).xyzw[0], scale*glmesh->m_vertices->at(3*i+0).xyzw[1], scale*glmesh->m_vertices->at(3*i+0).xyzw[2]), 
									btVector3(scale*glmesh->m_vertices->at(3*i+1).xyzw[0], scale*glmesh->m_vertices->at(3*i+1).xyzw[1], scale*glmesh->m_vertices->at(3*i+1).xyzw[2]),
									btVector3(scale*glmesh->m_vertices->at(3*i+2).xyzw[0], scale*glmesh->m_vertices->at(3*i+2).xyzw[1], scale*glmesh->m_vertices->at(3*i+2).xyzw[2]) );
		}
		btBvhTriangleMeshShape* bowlShape = new btBvhTriangleMeshShape(m_TriMesh, true, true);

		m_collisionShapes.push_back(bowlShape);
		btTransform bowlTransform;
		bowlTransform.setIdentity();
		btScalar mass(0.);
		bowl = createRigidBody(mass,bowlTransform,bowlShape, btVector4(0,0,1,1));
		bowl->setFriction(1.0);
		bowl->setRollingFriction(1.0);
	}

	//create a few dynamic rigidbodies
	// Re-using the same collision is better for memory usage and performance
	btCapsuleShape* colShape = new btCapsuleShape(btScalar(5*scale), btScalar(10*scale));
	m_collisionShapes.push_back(colShape);

	/// Create Dynamic Objects
	btTransform startTransform;
	startTransform.setIdentity();
	
	btScalar mass(1.0*scale);
	btVector3 localInertia(0,0,0);
	colShape->calculateLocalInertia(mass,localInertia);

	float inRad = 130.0*scale;
	float outRad = 270.0*scale;

	for (int k=0;k<ARRAY_SIZE_Y;k++) {
		for (int i=0;i<ARRAY_SIZE_X;i++) {
			for(int j = 0;j<ARRAY_SIZE_Z;j++) {
				startTransform.setOrigin(btVector3( btScalar( (inRad+(outRad-inRad)*i/ARRAY_SIZE_X) * cos(6.28*j/ARRAY_SIZE_Z) ),
													btScalar( (125+10*k)*scale ),
													btScalar( (inRad+(outRad-inRad)*i/ARRAY_SIZE_X) * sin(6.28*j/ARRAY_SIZE_Z) ) ));
			
				btRigidBody* particle;createRigidBody(mass,startTransform,colShape);					
				particle->setFriction(1.0);
				particle->setRollingFriction(1.0);
			}
		}
	}

	m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}

Code: Select all

void BasicExample::stepSimulation(float deltaTime)
{
	if (m_dynamicsWorld) {
		m_dynamicsWorld->stepSimulation(0.001);
	}

	clock += 0.001;
	btTransform bowlTransform = bowl->getWorldTransform();
	bowlTransform.setRotation( btQuaternion(clock, 0, 0) );
	bowl->setWorldTransform(bowlTransform);
Many thanks,
Anthony
anthrax11
Posts: 72
Joined: Wed Feb 24, 2010 9:49 pm

Re: Frictions between pellets and rotating bowl

Post by anthrax11 »

Hi,
btBvhTriangleMeshShape is for static (non-moving) geometry.
You need to use either GImpact shapes, btConvexTriangleMeshShape or HACD (convex decomposition). GImpact is probably easiest to way.
ant_the_mohican
Posts: 4
Joined: Wed Sep 09, 2015 3:46 am

Re: Frictions between pellets and rotating bowl

Post by ant_the_mohican »

Thanks for the reply anthrax.

I decided to make a simpler test: a rotating ground and small boxes instead of pellets.
Everything is now based on btBoxShape: http://www.angstrom-precision.com/dump/Sliding.zip

Image

But I still get no motion of the small boxes when the ground rotates.
There is something else missing... any other ideas?

Code: Select all

void BasicExample::initPhysics()
{
	m_guiHelper->setUpAxis(1);
	createEmptyDynamicsWorld();	
	m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
	m_dynamicsWorld->setGravity( btVector3(0, -10000*scale, 0) );

	if (m_dynamicsWorld->getDebugDrawer())
		m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);	


	///create a few basic rigid bodies
	btCollisionShape* bowlShape = new btBoxShape(btVector3(btScalar(300.),btScalar(50.),btScalar(300.)));	
	m_collisionShapes.push_back(bowlShape);

	btTransform groundTransform;
	groundTransform.setIdentity();
	groundTransform.setOrigin(btVector3(0,-50,0));
	bowlShape->calculateLocalInertia(0, btVector3(0,0,0));

	//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
	btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
	btRigidBody::btRigidBodyConstructionInfo rbInfo(0,myMotionState,bowlShape,btVector3(0,0,0));
	bowl = new btRigidBody(rbInfo);
	bowl->setFriction(1.0);
	bowl->setRollingFriction(1.0);

	//add the body to the dynamics world
	m_dynamicsWorld->addRigidBody(bowl);

	btBoxShape* colShape = createBoxShape(btVector3(5*scale,5*scale,5*scale));
	m_collisionShapes.push_back(colShape);

	/// Create Dynamic Objects
	btTransform startTransform;
	startTransform.setIdentity();
	
	btScalar mass(1.0*scale);
	btVector3 localInertia(0,0,0);
	colShape->calculateLocalInertia(mass,localInertia);

	float inRad = 130.0*scale;
	float outRad = 270.0*scale;

	for (int k=0;k<ARRAY_SIZE_Y;k++) {
		for (int i=0;i<ARRAY_SIZE_X;i++) {
			for(int j = 0;j<ARRAY_SIZE_Z;j++) {
				startTransform.setOrigin(btVector3( btScalar( (inRad+(outRad-inRad)*i/ARRAY_SIZE_X) * cos(6.28*j/ARRAY_SIZE_Z) ),
													btScalar( (125+10*k)*scale ),
													btScalar( (inRad+(outRad-inRad)*i/ARRAY_SIZE_X) * sin(6.28*j/ARRAY_SIZE_Z) ) ));
			
				btRigidBody* pellet = createRigidBody(mass,startTransform,colShape);					
				pellet->setFriction(1.0);
				pellet->setRollingFriction(1.0);
			}
		}
	}

	m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
ant_the_mohican
Posts: 4
Joined: Wed Sep 09, 2015 3:46 am

Re: Frictions between pellets and rotating bowl

Post by ant_the_mohican »

From what I gather so far, the problem is that I am modifying the transform directly.
Is there another way to make the ground/bowl (kinematic object) move in a specific manner, without having to use forces/impulses?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Frictions between pellets and rotating bowl

Post by drleviathan »

You also need to set the angular velocity of the kinematic bowl -- the physics engine won't update the bowl's rotation, but collisions with it will pick up velocities at the contact points. In fact, you don't even need to update the bowl's rotation to get the pellets to move -- just set its angular velocity once and the dynamic pellets should move around as if they are on a magic circular conveyor belt.
ant_the_mohican
Posts: 4
Joined: Wed Sep 09, 2015 3:46 am

Re: Frictions between pellets and rotating bowl

Post by ant_the_mohican »

I can now rotate the bowl with the pellets following the motion.
Thanks a lot for the useful pointers!