Physics--Issues

Hello. I am trying to use the Panda3D built-in physics system to apply gravity on my panda model, but when I set the panda’s z to 100, it just stays there. Code:

import direct.directbase.DirectStart
from panda3d.core import *
from panda3d.physics import *

base.physicsMgr = PhysicsManager()

scene = loader.loadModel("models/environment")
scene.setScale(0.25, 0.25, 0.25)
scene.setPos(-8, 42, 0)
scene.reparentTo(render)

node = NodePath("PhysicsNode")
node.reparentTo(render)
an = ActorNode("Panda-Physics")
anp = node.attachNewNode(an)
base.physicsMgr.attachPhysicalNode(an)

panda = loader.loadModel("models/panda-model")
panda.setScale(0.005, 0.005, 0.005)
panda.setZ(100)
panda.reparentTo(anp)

gravityFN = ForceNode("world-forces")
gravityFNP = render.attachNewNode(gravityFN)
gravityForce = LinearVectorForce(0, 0, -9.81)
gravityFN.addForce(gravityForce)

base.physicsMgr.addLinearForce(gravityForce)

base.run()

Hmm… What happens if you set the panda’s z-value to 50000?

Not in the scene graph anymore, maybe because it is too high for visibility

It’s probably in the scene-graph, but outside the camera’s view.

Still, that seems to show that setting the z-coordinate does work.

What I think is happening is that you’re setting the z-coordinate on an object with a scale of 0.005. As a result, a z-coordinate of 100 in the object’s coordinate-space has a value of 0.5 in the world’s coordinate-space, if I’m not much mistaken.

So what should I do?

Yeah, what I meant.

Well, what are you trying to do?

Offhand, a few options occur to me:

  • When setting the object’s position, keep in mind that scaling factor
  • Apply your position and your scale to separate nodes, with the scale being applied to a node that is a child of the node to which position is applied.
  • Apply your position relative to a node higher in the scene-graph than the node to which the scaling is applied, so that it circumvents the problem.

I want the panda to fall down from z 100 to z 0.
What do you mean by setting scale in a diffferent node and pos in different node.
Like this?:
np -> pandaNode -> posNode -> scaleNode
If yes, how?

That looks about right, yes.

Just as you’ve done with other nodes: create them, and parent them to each other.

Can you give me a code snippet. What I tried isn’t working.

Why don’t you show me what you’ve tried, and I’ll try to diagnose the problem, I intend.

(As always, please just show the relevant section of code, not your whole program.)

node = NodePath("PhysicsNode")
node.reparentTo(render)
an = ActorNode("Panda-Physics")
anp = node.attachNewNode(an)
base.physicsMgr.attachPhysicalNode(an)

panda = loader.loadModel("models/panda-model")
panda.reparentTo(anp)

posNode = NodePath("PosNode")
posNode.setZ(100)
posNode.reparentTo(panda)

scaleNode = NodePath("ScaleNode")
scaleNode.setScale(0.005, 0.005, 0.005)
scaleNode.reparentTo(posNode)

gravityFN = ForceNode("world-forces")
gravityFNP = render.attachNewNode(gravityFN)
gravityForce = LinearVectorForce(0, 0, -9.81)
gravityFN.addForce(gravityForce)

base.physicsMgr.addLinearForce(gravityForce)

Okay, you simply have the order of your nodes mixed up, by the looks of it.

Think of it this way: Consider a node attached as a child of another node to be located “below” that node in the hierarchy. Looking at it this way, transformations (e.g. positions, scalings, etc.) affect the node to which they’re applied, and any nodes below them. They don’t affect nodes above them.

In this case, you have your physics-node, and below that your model, and below that your position-node, and below that your scaling-node.

As a result, change to your physics-node affect all of the others; changes to your model affect the model, your position-node, and your scaling-node; changes to your position-node affect your position-node and your scaling node; and changes to your scaling node affect only your scaling node.

Thus, if you want your position-node to affect your physics-node, you can achieve that by placing it “above” the physics-node in your hierarchy. If you want your scaling node to affect your model, but not your physics-node, then you can achieve that by placing it “above” the model, but below the physics-node.

Do you see?

So basically, I should do:
anp
|
v
posNode
|
v
scaleNode
|
v
panda

right?

Yes

About right, yes! :slight_smile:

One thing does occur to me: since you want to move the object, and have it be moved by physics, it might actually be better to drop the “position” node and instead just adjust the position of the “physics” node. That should be unaffected by the scaling, and should mean that you don’t have the effects of the two nodes disjointed.

In which case, you might be able to drop the “scaling” node, too, and just scale the model: since you would no longer be trying to move a node that’s scaled, there should be no more conflict.

So I should just use a posNode and scale the panda from it’s node path or vice-versa, right?

More than that: I’m saying that you can use your “physics”-node as your “position”-node, and your model as your “scaling”-node, meaning that you don’t need separate “scaling”- and “position”- nodes.

(Although you may later want similar intervening nodes if you find yourself wanting to do more-complex things, of course.)

So:

anp.setZ(100)
# and
panda.setScale(0.005, 0005, 0.005)

Exactly, yes. :slight_smile:

No, not falling down. Though the pos and scaling is perfect.

That it’s not falling down is a separate issue from positioning and scaling, I believe. Sorry, I thought that the original problem was the positioning of the model, not that it wasn’t responding to gravity!

Unfortunately, I don’t use Panda’s physics system (only its collision system, and the Bullet physics system). Thus I’m afraid that I don’t know much about setting up gravity in Panda’s physics system.