Sign in to follow this  
aws357

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

Recommended Posts

aws357    132

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.

Share this post


Link to post
Share on other sites
L. Spiro    25638
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

Share this post


Link to post
Share on other sites
aws357    132

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";
    }
}

Share this post


Link to post
Share on other sites
JordanBonser    839

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 );
   }
}

Share this post


Link to post
Share on other sites
aws357    132

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.

Share this post


Link to post
Share on other sites
Alundra    2316

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this