Panda Bullet

If I understand you right then you see exactly the desired behaviour. The scale applied to a shape is the global scale of the body’s parent, times the local scale of the body itself. Just one correction: global transform is not “with respect to render”, but also including the transform set on render itself.

About mass and other properties: no, mass is not scales. But the mass properties are recomputed after a changed in transform (inverse inertia etc.).

I may be jumping the gun a bit as I haven’t found the need for it yet, but has anyone needed to partition their world collisions (static shapes built from world geoms) using something like a kd or octtree?

I know there were a couple octtree partioners written for the built in collision system that saw some good performance increases.

Has any felt the need to do this yet, or is everyone just manually partitioning their world collision shapes? Or does bullet do something to optimize collisions that would make this unnecessary?

BulletWorld is, by default, automatically partitioned using an AABB tree. Using the config parameter “bullet-broadphase-algorithm” it is possible to choose between eiter AABB tree (BA_dynamic_aabb_tree, “aabb”) or SAP (BA_sweep_and_prune, “sap”).

Ennox, did you have any luck with framerate dependance problems for character controller?

I found out that it is dependant on framerate only if dt is smaller than amountofsteps and stepsize.

So for example lets say that i have average frame time of 0.002s
(500) FPS.

doPhysics(dt,5,0.0002) #runs fine
doPhysics(dt,5,0.00002) #runs fine
#Those run exactly the same, as long as dt > numSteps*stepSize

doPhysics(dt,5,0.002) #does not run fine, character moves slower if i decrease frame time (more fps).

Easy way to impact framerate is to have several bullet nodes around and just alter debug visuals.

Not much luck, I’m afraid. But first, your “works fine” examples have a slight disadvantage: they loose simulation time! Let me explain why:

doPhysics(dt, max_substeps, substep)

If called this way Bullet will advance the simulation using fixed size substeps. The step size if “substep”. It will do up to max_substeps substeps. The remaining time will be used to interpolate the scene (not simulate). A few examples:

1.) doPhysics(0.32, 5, 0.1): Bullet will do 3 substeps, each 0.1 seconds. The remaining 0.02 seconds will be interpolated.

2.) doPhysics(0.16, 5, 0.2): Bullet will do no simulation substep at all, just interpolate.

3.) doPhysics(0.56, 4, 0.1): Bullet will do 4 substeps, since 4 is the max numer of substeps it is told to do.

In your case you have doPhysics(dt~0.002, 5, 0.00002). Bullet will do 5 substeps each 0.00002 = 0.0001 seconds. The remaining time to 0.002 seconds is lost.
In your case you could also call Bullet this way: doPhysics(0.0002, 0). This way Bullet will do no substep, just one simulation step of fixed length each frame, no matter what the frame duration is.

Back to the little insight gained. The problem is that Panda3D’s framerate is not constant. Now and then there are “spikes”. These spikes cause the problems. In general, physics engines run best with constant stepsize. Variable stepsize and interpolation are the death of determinism. Somehow Bullet seems to be very vulnerable to such spikes.

In order to get more stable character movement you could try the following:
1.) A cheap way would be to tell Panda to clamp framerate at, say, 60fps. You will still get single frames which are much longer. Don’t care about frame rate fluctuation. Pass 1./60. to Bullet’s doPhysics. The result will be that the character velocity will change together with the framerate fluctuation, but the huge spikes should be gone.

2.) Collect the elapsed time (task.getDt) in a variable, and before stepping the simulation chekc this accululator. Remove only multiples of a fixed stepsize from the accumulator, and pass these timesteps to Bullet. A good fixed stepsize would be maybe a third of the average frametime, so on average you do 3 simulation steps each frame. Sometimes 2, sometimes 4. This won’t give perfect results, but for me the character movement has become more smooth since interpolation is no longer applied.

First, thank you very much!
I know about loosing time, you gave me link earlier which explains this stuff.

Now, deal is that i tried most of that stuff, and spikes are “solved”.

Problem is for example:
I have 100 “meters” level.
When framerate is 300FPS i need 20 seconds to run trough level.

When framerate is 600FPS i need 40 seconds to run trough level.

From my observations what happens is:
(this could be totally wrong as i am not that smart)

doPhysics(0.0201,5,0.002) will move 5 meters/do 5 substeps.
doPhysics(0.0101,5,0.002) will move 5 meters
doPhysics(0.0061,5,0.002) will move 3 meters.
doPhysics(0.0042,5,0.002) will move 2 meters/do 2 substeps.

So it would seem that there is no interpolation?

PS, i am testing whole time with characterController!

enn0x, let me know if you’ll want other illustrations for the manual.

@redpanda:
Thank you for the offer. I currently write no additional pages for the manual, so right now there is no need. But I will keep your offer in mind.

@GrizzLyCRO
Yes, this is something I noticed too. The absolute velocity of the character is not what it should be (i. e. what you set in processInput). From my observations it seems that it is multiplied by the number of substeps.
–> setting speed “3 units per second”
–> no substeps: actual speed is “3 units per second”
–> 2 substeps: actual speed is “6 units per second”
–> 5 substeps: actual speed is “15 units per second”

A corection within the Panda3D wrapper would be possible, but I first want to verify this behaviour.

Oh, and also, changing “third” argument(stepsize) also has direct(proportional) impact on character speed.

Also, did you try asking for help from bullet devs?

@enn0x

Until this situation with Character Controller is resolved, do you have any recommendations about how to move rigid body relative to self?
Currently i am on my way to implement that with setLinearVelocity()

EDIT1:
Ah, almost forgot to post it, here is easy way to get relative movement on rigidbody

    def processInput(self, Task):
        force = Vec3(0, 0, 0)
    
        if inputState.isSet('forward'): force.setY( 1.0)
        if inputState.isSet('reverse'): force.setY(-1.0)
        if inputState.isSet('left'):    force.setX(1.0)
        if inputState.isSet('right'):   force.setX( -1.0)
                
        force *= 20.0
        rel= self.ship.NP.getRelativeVector(render,force)
        rel[0] *= -1
        
        self.ship.btNode.setLinearVelocity(rel)
        return Task.cont 

I checked in a small modification to the character controller code. The walk velocity should be as expected now, that is the same velocity which has been set using setLinearVelocity. At least as long as sane parameters are used. It also reduces the velocity fluctuation significantly.

I get best results with these parameters:

self.world.doPhysics(dt, 2, 1./240.)

(framerate is clipped to 60FPS). Indeterminism becomes stronger if max_substeps * stepsize >= dt, which is not the case in the above example.

The next snapshot build should pick up the modifications.

Great, i just saw commit, i will try it soon :slight_smile:
Thank you very much for all your hard work!!

Anyway to set relative torque? I need it for rotating a space plane.

btRigidBody.setAngularVelocity (Vec3 const velocity)

Code similar to one in my post above may be needed to convert wanted hpr to vector in bullet space.

Not good at vector math. Could you give an example?

Sorry, i am not very good at vector math, but maybe i can help you to call right panda functions if you describe me exactly what you want to achieve.

The problem right now is that if I pitch say 90*, then change my heading, my heading is changed globally, ignoring the 90* pitch, and messing up the steering.

Relative to what?

body.applyTorque()

Relative to its current rotation.

Think of how a plane rotates:

If I point the plane straight up, then roll it, it will roll around the z axes. If I fly straight it rolls around the y axes.

If I point straight up and try rolling with Bullet, it still rolls around the y axes.[/img]

Look into NodePath.getRelativeVector(), i think that is what you are looking for.