Panda Physic engine : simulating gravity.

Hey there,

I am trying to enable simple physics behaviour using the internal physic engine, which should be enough for my needs.

I have a generated model, built vertex per vertex (using GeomVertexData…). I need this model to be affected by a gravity force.

The problem is, the section of the manual is quite unclear and uses python code, even in the c++ version.

I have tried to “translate” into c++ but that does not work. My code is as follow :

PT(GeomNode) gn = c->generate();

	pm = new PhysicsManager();

	NodePath test = window->get_render().attach_new_node(gn);
	ActorNode an("an-physics");
	NodePath anp = test.attach_new_node(&an);
	test.set_pos(0,0,1.0);
	test.set_scale(1.0,1.0,1.0);

	ForceNode gravityFN("world-forces");
	NodePath gravityFNP = test.attach_new_node(&gravityFN);
	LinearVectorForce gravityForce(0,0,-9.81);
	gravityForce.set_mass_dependent(true);
	gravityFN.add_force(&gravityForce);

	pm->attach_physical_node(&an);
	an.get_physics_object()->set_mass(136.077); 

	an.get_physical(0)->add_linear_force(&gravityForce);

This simply does nothing. Using PhysicsManager.debug_output() gives me this :

PhysicsManager li0 ai0
 _physicals 1
 _linear_forces (1 forces)
 LinearVectorForce:
  _fvec 0 0 -9.81
  LinearForce(id 0030FA8C)
   _amplitude 1
   _mass_dependent 1
   _x_mask 1
   _y_mask 1
   _z_mask 1
   BaseForce (id 0030FA8C):
    _force_node render/gn*/world-forces
    _active 1
   _angular_forces 0

I’m running out of ideas here, if anyone got one…

Thanks in advance !

Hi

Did you create an AsyncTask ?

I know when I was doing particle system I had to add a task to update the PhysicsManager.

example:

In my include file:

PhysicsManager mPhysicsManager;

static AsyncTask::DoneStatus updateEffectsTask(GenericAsyncTask* task, void* data);

PT(AsyncTaskManager) mTaskMgr;

PT(GenericAsyncTask) mUpdateEffectsTask;

In my cpp file:
Constructor…
LinearEulerIntegrator *lei = new LinearEulerIntegrator();
mPhysicsManager.attach_linear_integrator(lei);

mUpdateEffectsTask = new GenericAsyncTask("mUpdateEffectsTask", (GenericAsyncTask::TaskFunc*)Effects::updateEffectsTask, this);

mTaskMgr = AsyncTaskManager::get_global_ptr();
mTaskMgr->add(mUpdateEffectsTask);
.
.
then in your task (my class is called Effects)
AsyncTask::DoneStatus Effects::updateEffectsTask(GenericAsyncTask* task, void* data) {

Effects effects = (Effects)data;

float dt = ClockObject::get_global_clock()->get_dt();
effects->mEffectsManager.do_particles(dt);
effects->mPhysicsManager.do_physics(dt);

return AsyncTask::DS_cont;

}

You might need to do something like this, but in your
case just do the:
pm.do_physics(dt);

tim

Hi,

Thank you for your answer :slight_smile:

I actually forgot to mention it but I do have an AsyncTask including the pm->do_physics(dt), yet it still doesn’t work.

I must have messed up with something along the creation of the force, but in a lack of any example to refer to, I can’t find it. Which is pretty frustrating, actually :confused:

Hi again

looking at your code I see you attached actor node to the model node (test). In the manual they show attaching the model to the actor. Also they show attaching the gravityFN to the top render node, it looks like you attach it to the model node.

see:
http://www.panda3d.org/manual/index.php/Enabling_physics_on_a_node
and
http://www.panda3d.org/manual/index.php/Applying_physics_to_a_node

I think since your gravityFN is “hanging” under the model node as a child, so that force never gets applied to the model. That’s why they put the forces at the same parent level as the models that need to have the force applied to them.

try doing:
NodePath gravityFNP = window->get_render().attach_new_node(&gravityFN);

Hi,

Once again, thank you for looking into this :slight_smile:

I tried your solution, that did not change anything.

I know this thread is most of a year old, but for posterity’s sake I think I know what your problem is, having recently gone through a similar situation myself. I don’t think you attached an integrator to your PhysicsManager. To copy a few lines out of of tah’s big reply:

LinearEulerIntegrator *lei = new LinearEulerIntegrator();
mPhysicsManager.attach_linear_integrator(lei);

Physics simply does not work in Panda3d unless your physics manager has an integrator attached to it AND do_physics is called every frame.