Panda PhysX


#25

Thanks, I’m getting things to work now, finally.

Just want to know…
When I want to use a shape like the capsule, does my model have to be centered over the origin, or must it be placed above the origin? Is there a way to set the direction of it?


#26

I don’t understand your question, sorry. Can you elaborate a little bit about what you mean with “model” and “origin”? Best would be to use Pand3D or PandaPhysX class names.

You mean the NodePath assigend to a PhysActor, or the PhysShape added to the PhysActor?

“Origin” is a property of a coordinate system. There are several coordinate systems involved, for example the global CS or rendered geometry (NodePath “render”), the local CS of a NodePath (relative to it’s parent NodePath), the CS of the PhysScene, the global CS of a PhysActor (relative to the PhysScene), the local CS of a physShape (relative to PhysActor), just to name the most important ones.

enn0x


#27

When I say model I meant the actual model that the 3d artist builds in Blender or etc. and with shape I meant both the PhysShape and the blender model’s shape.
About the origin, I meant the model origin, as in blender. Example:

About the direction. Why I ask is because I get this result:

The capsule is rolling sideways and the model is obviously not correctly oriented with the PhysShape or whatever. I don’t know, thats why I ask. This is my code:

		self.m_Model=loader.loadModel(modelname)
		self.m_Model.reparentTo(render)
		self.m_Model.setPos(0,0,10)
		self.m_Model.setHpr(0,0,0)
		
		tmpshape = PhysCapsuleShapeDesc()
		tmpshape.setHeight( 1.8 )
		tmpshape.setRadius( 0.35 )

		tmpbody = PhysBodyDesc( )
		tmpbody.setMass( weight )

		tmpactor = PhysActorDesc( )
		tmpactor.setBody( tmpbody )
		tmpactor.addShape( tmpshape )
		tmpactor.setGlobalPos( self.m_Model.getPos(render) )

		self.m_PhXActor = world.m_PhXScene.createActor( tmpactor )
		self.m_PhXActor.attachNodePath( self.m_Model )

#28

Not really obvious, since the screenshot only shows rendered geometry. It does not show the collision geometry. Turn on physx debug rendering, and do another screenshot. Then it will be obvious.

My best guess it that you have aligned the visible capsule along the z-axis. Your blender screenshots don’t reveral what axis is up, so making random guesses is verything I can do. PhysCapsuleShape is aligned along the y-axis.

If this is true then you have two options. Both ways work fine:
1.) either rotate the PhysCapsuleShape by setting a local transform.
2.) or rotate your visible geometry in Blender, then export again.

enn0x


#29

Thanks for the help so far enn0x.

I just rotated the visible geometry for now, but it was the PhysCapsuleShape’s local transform that I was really looking for, I believe.

Anyway, is there a way to visualize a PhysRay when rendering the PhysScene’s debug node? I’m trying to use the PhysRay for a 3rd Person camera to check if its going through anything.

By the way, PhysX works 10x better and easier than ODE, in my opinion.


#30

The rays used in raycasting are not part of the PhysScene, they are just temporary objects. The debug renderer can not show them.

There are two other options for visualizing them:

1.) What I have done in the raycast sample: use two spheres, and move them to the origin and the end of the ray every frame.

2.) Use the Panda3D class “LineSegs” to create a NodePath which is a line from the ray’s origin to it’s end every frame. If I find some time I will modify the raycast sample this way for the next release.

Performance is not an issue here since this is just for debugging.

Thanks, but it comes at a high cost: PhysX is not open source, and my bindings for PhysX are still at an early stage.

enn0x


#31

Hey enn0x,
Is there a way to monitor whether a PhysActor or shape has been hit by a raycast?

I saw that the PhysShape can be set to be a trigger. Could it be done with a RayCast? I thought of creating a trigger physshape at the ray’s hit point, but maybe there’s a better way?


#32

Have you seen the setPythonData/getPythonData methods available on any object that is derived from PhysObject? They allows you to assign an arbitray python object to any PhysShape, PhysActor, …

Just iterate over the shapes returned by the raycast, get the object you have assigned to the shapes previously, and call whatever method you want on this object.

enn0x


#33

I don’t know if this is a bug or not. I’m currently compensating by using a large,flat,box shape, but character controllers don’t seem to be colliding with planes.

EDIT: Also, I am trying to do a raycast originating from the camera. However, the ray is colliding with the character controller, and so always returns the position of the camera and a length of 0. Should I use a RaycastAll and use the second hit, or is there a better way to do this.


#34

Not a bug, but the way PhysX is implemented. You should use a static triangle mesh instead, like in the sample. The triangle mesh can be just two triangles, but usually you want to have an uneven ground. Or a heightfield mesh.

This is because you probably start the ray INSIDE the character’s shape. So the character’s shap is the first shape the ray hits, with distance 0.
There are several options:

  • start the ray outside the capsule
  • use shape groups and a PhysMask32 to disable/enable specific shape groups.
  • use raycastAll, and skip the raycast hit with the own character’s shape. Cave: the raycast hit’s are not guaranteed to be sorted. Not recommended.
  • Not yet supported is the way more powerful 128-bit masking system. This would be a third option.

enn0x


#35

I’m having trouble when removing a PhysActor with its remove() function. I get the following assertion error:

Any ideas why? I can’t see anything wrong with my code. Is there anything I need to call before calling remove(), or is there a different way to remove actors?


#36

This means that your actor has been removed already by someone else, and thus _error_type is no longer “ET_OK”. This could be

  • because you have called remove() on another reference of this PhysActor
  • you have called remove() on the scene that owns the actor. All actors get automatically invalidated this way.
  • the actor has been automatically created by an controller, and you removed the controller. The automatically created objects get invalidated also.

This is exactly the same behaviour your have implemented in PandaNode (I admit that I have been cheating here - to make PhysX usage the same as core Panda3D usage).

I will add a “getErrorType” method to all objects for the next release. Then you could check before you try to remove. I have wondered for a long time if I should swallow this error and just return if the actor is already removed, but I think this leads to sloppy programming. It’s better to see that something has gone wrong. But this is a rather philosophical question, and good reasons exist for both ways.

enn0x


#37

EDIT | Reposted…
This message showed up before the next, but I posted after. Could be something with GMT differences?


#38

Ok, I’ve checked my code but I’m not calling remove twice. Anyway, I tried it on one of the samples, 03_Forces. I only added one line to the doScreenshot event:

It creates only one screenshot file, which means its only being called once, unless I don’t know of something that keeps it from making another, but its still giving me the same error. Can you check if it does the same for you. Any other ideas?


#39

Hmmm… I have not choosen my words clear enough here, sorry.

After you called remove() on an actor is is no longer valid. It has been destroyed, and the python object is an empty shell. This means: calling ANY other method on this actor after calling remove() will cause raise an exception. Not only calling remove() a second time - ANY other method. I payed some effort on guarding every method with an assert to achive this.

This is what happens if you modify the sample 03 like you did in the above post: You press F5 key, and self.boxActor.remove() is called. The actor is destroyed now. But there is still a task running which is called once a frame, to update the simulation and to process user input. Have a look at the code:

  def updateWorld( self, task ):
    dt = globalClock.getDt( )

    self.processInput( )
    self.scene.doPhysics( dt )

    return task.cont

  def processInput( self ):
    ....
    self.boxActor.addForce( force )
    self.boxActor.addTorque( torque )

So you call addForce() AFTER calling remove() on the same actor. Raising an exception is correct here, since you can’t add a force to a destroyed actor.

I suggest you do something like this in your code:

    ...
    self.yourActor.remove()
    self.yourActor = None
    ...

Then you will probably get a different error message: a python traceback complaining that “None object has no method xyz.” The codeline shows to you where you call a method AFTER calling remove() on your actor.

enn0x


#40

I was wondering if my own post was a bit confusing.

Anyway. I added the following line to my edited doScreenshot function:

self.boxActor=None

And also changed the forces part to this:

if self.boxActor:
   self.boxActor.addForce( force )
   self.boxActor.addTorque( torque )

Now the assertion occurs at this line: self.scene.doPhysics( dt ). I don’t know how PhysX works, but if I called remove(), shouldn’t my actor have been removed from the PhysScene and not be part of what doPhysics() is trying to do? You say invalidated, is doPhysics() trying to do physics calculations on my invalidated actor?

I’m sorry if I am bothering you, and thanks for the help, so far.


#41

This last one is a bug, but easy to fix, I even can choose between two ways to fix it. Since this is a rather serious bug I will do a new release next week (around Thuesday or Wednesday).

Of course doPhysics() should not do anything on already destroyed actors, but I am using PhysX active transforms to minimize the number of transforms to update. Updating transforms happens while PhysX simulates the scene, in two different threads. This saves a lot of time, but it means that the active transform list which I get from PhysX is the active transform list from the previous simulation step. This list might contain removed actors.

enn0x


#42

Ah, thanks. I’m waiting with anticipation.


#43

http://enn0x.p3dp.com/libpandaphysx_0.4.3.zip

Mainly a bugfix release, but cloth simulation has been added also (currently only for windows).

  • Adds simulation of clothes (ALPHA stage, API may change in future releases!).
  • setSharpness() has moved from PhysBoxController to PhysController.
  • Fixed a bug in the controller callback implementations.
  • Fixed a bug in the controller creation (actor had NULL pointer as name).
  • Fixed a bug with removing actors.
  • Replaces set/getPythonData with them more flexible set/getPythonTag system.
  • Updated some of the samples.
  • Add some variants of PhysActor.addForce/addTorque.
  • Add methods to set/get linear and angular momentum on PhysActor.

(see included file doc/RELEASE-NOTES.txt)

The included binaries are built for Panda3D-1.5.4.
Many thanks to all who helped finding bugs. :slight_smile:

enn0x


#44

Thanks for the great library. Would you recommend using force fields for modeling buoyancy or is there a better way I’m missing?