[physx] go through all the dynamic rigid bodies in a scene

Started by
7 comments, last by Alundra 8 years, 6 months ago

In physx you create a body and add it as an actor to a scene.

The thing I am trying to do is to go through the rigid bodies in the scene to apply a random force impulse on each rigid bodies.

So I am looking for the most efficient way to loop through all the bodies in a scene.

Thanks for any hints.

Advertisement
PhysX is costly to use in any form of released product (free or otherwise).
You’re going to have to be more specific if you can’t just loop through the objects in your scene and update them. The fastest way to loop through them is to loop through them. Any specific problem doing that? Why can’t you just run over all the objects in your scene manager object array?


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

The thing is, I am not sure how to access the bodies in the simulation (C++ && Physx noob alert, bear with me please).

There is a PxScene::getActors but no PxScene::getBodies. So it is not really clear for me where the bodies are stored in physx and how they can be accessed if i wish to loop through them.

Here is a code I glued together to loop through actors e.g.

I guess actors are linked to bodies but I don't really know how to access the bodies so I can use PxRigidBody::addForce on them...

Hope it makes the question clearer.


void countActor(void)
{
    PxU32 nbActors = gScene->getNbActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC);
	PxActor** actors = new PxActor*[nbActors];
	gScene->getActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC,actors,nbActors);
 
	
	while(nbActors--)
    {
		cout<<"nb"<<nbActors<<"_"<<"actor"<<actors<<"\n";
    }
}

Okay so having a quick look through the API and headers for Physx that I have.

It seems that a PxRigidBody derives from PxRigidActor which derives from PxActor.

What I think you will either want to do is store all the PxRigidBodies in an array when you create them. (Most likely using CreateRigidDynamic() or equivalent functionality).

Or alternatively loop casting the actors to rigidbodies to then apply the force to them. e.g.


for( unsigned int i = 0; i < nbActors; i++ )
{
   auto rigidBody = dynamic_cast<PxRigidBody*>(actors[i]);
   if( rigidBody )
   {
      rigidBody->AddForce( forceVal );
   }
}

PhysX does not own your list of objects. Your scene manager does, and that is made by you, so you should have no problems traversing it.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

You can store a pointer of the object in the user type of the physx actor.

Thanks for all the replies. It helped, even when I could not make sense of them (give hint and google search terms etc...).

Plus i was probably looking for a complicated solution when a simple one works just fine.

Here is the solution I finally settled for. A vector to store bodies.


vector <PxRigidBody*> arrayofBodies;

PxTransform		boxPos1(initpos,PxQuat(PxHalfPi, PxVec3(0.0f, 1.0f, 0.0f)));	//Position and orientation(transform) for box actor 
PxRigidDynamic	*gBoxOri = NULL;				//Instance of box actor 
PxCapsuleGeometry	sphereGeometry(radius,height);											//Defining geometry for box actor
gBoxOri = PxCreateDynamic(*gPhysicsSDK, boxPos1, sphereGeometry, *material, 1.0f);		//Creating rigid static actor
gScene->addActor(*gBoxOri);														//Adding box actor to PhysX scene
arrayofBodies.push_back(gBoxOri); //vector is filled with bodies here...

for (PxU32 i=1; i<numberofblocks; i++)
{
	PxTransform		boxPos1(initpos+PxVec3(0.0f, 0.0f, 2*i*height/*2.0f*/),PxQuat(PxHalfPi, PxVec3(0.0f, 1.0f, 0.0f)));												//Position and orientation(transform) for box actor 
	PxRigidDynamic	*gBox = NULL;				//Instance of box actor 
	PxCapsuleGeometry	sphereGeometry(radius,height);											//Defining geometry for box actor
					gBox = PxCreateDynamic(*gPhysicsSDK, boxPos1, sphereGeometry, *material, 1.0f);		//Creating rigid static actor
					gScene->addActor(*gBox);														//Adding box actor to PhysX scene

					// adding some joint to the mix
	//PxSphericalJoint* joint = PxSphericalJointCreate(*gPhysicsSDK, gBoxOri, PxTransform(-offset), gBox, PxTransform(offset));
	//PxSphericalJoint* joint = PxSphericalJointCreate(*gPhysicsSDK, gBoxOri, PxTransform(offset0), gBox, PxTransform(offset1)); //uncomment to use spherical joints
	PxD6Joint* joint = PxD6JointCreate(*gPhysicsSDK, gBoxOri, PxTransform(offset0), gBox, PxTransform(offset1));

	//add some limits to the joint
	//joint->setLimitCone(PxJointLimitCone(0.00000001f,0.00000001f,0.1f));
	//joint->setSphericalJointFlag(PxSphericalJointFlag::eLIMIT_ENABLED,true);
	joint->setSwingLimit(PxJointLimitCone(1.57f,1.57f,0.00000001f));
	joint->setConstraintFlag(PxConstraintFlag::eVISUALIZATION, true);
	joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eLOCKED);
	joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eLIMITED);
	joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eLIMITED);
	//joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE); //free to rotate around y axis

	//add the body to the array before renaming the original box...
	arrayofBodies.push_back(gBox); //vector is filled with bodies here...

	gBoxOri=gBox;

I can then run through the vector of bodies with ease.


void countActor(void)
{
    //PxU32 nbActors = gScene->getNbActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC);
	//PxActor** actors = new PxActor*[nbActors];
	//gScene->getActors(physx::PxActorTypeSelectionFlag::eRIGID_DYNAMIC,actors,nbActors);
 
	int nbActors=arrayofBodies.size();

	//arrayofBodies[1]->addForce(PxVec3(0,800,0),PxForceMode::eACCELERATION);

	while(nbActors--)
	{
		int fx=rand()%50;
		int fy=rand()%50;
		int fz=rand()%50;
		
		//cout<<fx<<"_"<<fy<<"_"<<fz<<"\n";
		//arrayofBodies[nbActors];
		arrayofBodies[nbActors]->addForce(PxVec3(fx,fy,fz),PxForceMode::eIMPULSE);
		arrayofBodies[nbActors]->getLinearVelocity
	}
}

Again, kudo to all.

int nbActors=arrayofBodies.size();
Should be:
size_t nbActors=arrayofBodies.size();

Your random-number generation is wrong.

http://stackoverflow.com/questions/288739/generate-random-numbers-uniformly-over-an-entire-range

Although I assume this part is just for testing.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Nice about the rand, surely I should make a try because I use :


NextInt() % (End - Begin + 1) + Begin;

The stackoverflow message says :


(static_cast<double>(NextInt()) / (RAND_MAX + 1)) * (End - Begin + 1) + Begin

This topic is closed to new replies.

Advertisement