dde icon indicating copy to clipboard operation
dde copied to clipboard

SimObj is_dynamic vibrates excessively.

Open JamesNewton opened this issue 5 months ago • 7 comments

Make a stack of objects all set to be dynamic, and watch them vibrate against each other and eventually fall over.

It turns out that through a happy accident I found a solution to this: Turning on dynamic mode by turning off kinematic mode without changing anything else. e.g.

var my_obj = SimObj.make_object3d({name: "my_object3d", parent: "scene", geometry: "Box",
    scale: [0.2, 0.2, 0.2], position: [0.0, 0.3, 0.1], orientation: [0.0, 0.0, 0.0],
    material: "MeshNormal", color: [1, 1, 1],
    wireframe: false, is_dynamic: false, mass: 1
})
my_obj.userData.physObj.kinematic = false

This gives you an object that is dynamic, but doesn't vibrate excessively.

After looking about a bit in the code, it appears that this routine https://github.com/cfry/dde/blob/dde4/src/simulator/physicsObject.js#L757 is setting the mass of the object to ZERO! Which, I'm pretty sure, is what makes it shake. Given some mass, they settle down. I'm not sure about the other flags:

  • .setActivationState
  • .setCollisionFlags

As those don't seem to be required, but maybe they make the difference?

More experimentation is needed. E.g. replacing the code for

  • PhysicsObject.makeKinematic() and
  • ‎PhysicsObject.makeDynamic() with version which don't change the mass.

JamesNewton avatar Jun 17 '25 05:06 JamesNewton

Should try: (edit, obviously, we want to change makeDynamic, not makeKinematic, and look for other differences there. MakeKinematic is the one that sets the mass to zero, and that is perfectly correct. makeDynamic is the one that needs to set mass, and it does. I had them reversed in my head.)

PhysicsObject.makeDynamic = function()
    {
        //this.rigid_body.setActivationState( PhysicsObject.MotionState.ACTIVE );
        //this.rigid_body.setCollisionFlags( 0 );

        // Set the mass of the object back to what it was before
        this.colShape.calculateLocalInertia( this.mass, this.localInertia );
        this.rigid_body.setMassProps(this.mass, this.localInertia);

        this.rigid_body.setLinearVelocity( this.zeroVec)
        this.rigid_body.setAngularVelocity( this.zeroVec);
        this.rigid_body.updateInertiaTensor();

        this.kinematic = false;
    }

e.g. don't change the "ActivationState" and "CollisionFlag" settings, which are the only difference other than the mass setting and the kinematic setting, but this does NOT appear to help.

Moreover I noticed in my code above where the stack didn't fall over when it was first made, that I was setting dynamic to false initially. When you do that, the stack doesn't fall because it's not dynamic, even with the kinematic flag set to false, because the mass is set to zero. (or I think that's it).

So in the long run, I didn't find a solution, I just delayed the onset of the problem.

The next possible solution I can see is to actively set an object to kinematic or dynamic as you grab it or release it. But that seems like a horrible hack.

The real bug is in the physics engine as far as I can see.

JamesNewton avatar Jun 17 '25 05:06 JamesNewton

It's possible the answer is here: https://n5ro.github.io/aframe-physics-system/AmmoDriver.html#activation-states with a settings for linearSleepingThreshold and angularSleepingThreshold which allows the object to be "deactivated" while still being a working dynamic object.

JamesNewton avatar Jun 20 '25 05:06 JamesNewton

Wow. Lot of info on that page. Most of the time an object is "inactive"/static so why bother to compute all these "if it moved, this would happen" when its not going to move. Sleeping. Nice.

In the real world, this "computation" kinda happens for free or you could say "incredible always on, extremely complex instantaneous interaction". Every atom is its own complex compute engine. The parallelism is stupendous. its almost the philosophy of physical reality. Cheaper to have reality than to simulate.

That page admits lousy doc. At least the admission is good. Now if we only had a decent programming lang .... You are an information archaeologist for finding this.

On Fri, Jun 20, 2025 at 1:21 AM JamesNewton @.***> wrote:

JamesNewton left a comment (cfry/dde#111) https://github.com/cfry/dde/issues/111#issuecomment-2989828762

It's possible the answer is here:

https://n5ro.github.io/aframe-physics-system/AmmoDriver.html#activation-states with a settings for linearSleepingThreshold and angularSleepingThreshold which allows the object to be "deactivated" while still being a working dynamic object.

— Reply to this email directly, view it on GitHub https://github.com/cfry/dde/issues/111#issuecomment-2989828762, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJBG7LJLEX4YUTI5TTWBVL3EOK5XAVCNFSM6AAAAAB7PC3HLKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDSOBZHAZDQNZWGI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

cfry avatar Jun 20 '25 14:06 cfry

Argh. https://n5ro.github.io/aframe-physics-system is a completely different physics engine that simply has an interface with ammo.js.

It has been suggested that these settings might help, but so far I see no difference with them:

  o.userData.physObj.rigid_body.setActivationState(1) //alows sleeping
  o.userData.physObj.rigid_body.setSleepingThresholds(3,4) //linear 0.8, angular 1.0
  o.userData.physObj.rigid_body.setFriction(0.9) //0.8 increase
  o.userData.physObj.rigid_body.setRestitution(0.01) //0.1 decrease
  o.userData.physObj.rigid_body.setDamping(0.4, 0.4); //0.1 linearDamping, 0.1 angularDamping
  o.userData.physObj.rigid_body.forceActivationState(4)

FYI, the actual source code for THREE.JS is: https://github.com/mrdoob/three.js

https://threejs.org/docs/ very slim docs

JamesNewton avatar Jun 21 '25 05:06 JamesNewton

Ahh, I was confused by seeing A Frame on the doc you sent but now it makes more sense, I did look at AFRAME before using what I did. I didn't realize AFrame was a wrapper to ammo. Maybe that would have been a better route.

On Sat, Jun 21, 2025 at 1:45 AM JamesNewton @.***> wrote:

JamesNewton left a comment (cfry/dde#111) https://github.com/cfry/dde/issues/111#issuecomment-2993349165

Argh. https://n5ro.github.io/aframe-physics-system is a completely different physics engine that simply has an interface with ammo.js.

It has been suggested that these settings might help, but so far I see no difference with them:

o.userData.physObj.rigid_body.setActivationState(1) //alows sleeping o.userData.physObj.rigid_body.setSleepingThresholds(3,4) //linear 0.8, angular 1.0 o.userData.physObj.rigid_body.setFriction(0.9) //0.8 increase o.userData.physObj.rigid_body.setRestitution(0.01) //0.1 decrease o.userData.physObj.rigid_body.setDamping(0.4, 0.4); //0.1 linearDamping, 0.1 angularDamping o.userData.physObj.rigid_body.forceActivationState(4)

— Reply to this email directly, view it on GitHub https://github.com/cfry/dde/issues/111#issuecomment-2993349165, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJBG7LHW3XDHWJLTQZYACL3ETWNTAVCNFSM6AAAAAB7PC3HLKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDSOJTGM2DSMJWGU . You are receiving this because you commented.Message ID: @.***>

cfry avatar Jun 21 '25 20:06 cfry

Further confusion, errors, and stupidity, I'm sure. Sigh.

I've attempted to add the following lines

                    debugger
                    if (this.last) {
                    	if ((this.last.p.x - p.x) < 0.0001) p.x = this.last.p.x 
                    	if ((this.last.p.y - p.y) < 0.0001) p.y = this.last.p.y
                    	if ((this.last.p.z - p.z) < 0.0001) p.z = this.last.p.z
                    } else this.last = {p:p, q:q}
                    this.last.p = p
                    this.last.q = q

after the line: https://github.com/cfry/dde/blob/dde4/src/simulator/physicsObject.js#L633 by copying out the entire update routine and replacing it in the editor with globalThis.PhysicsObject.update = function() { with the updated code following but that doesn't seem to be having any effect. Even with the Inspect window open, the debugger has no effect, and the source code in the bundle.js file IS still in effect.

I need to be able to run DDE4 from the source code.

JamesNewton avatar Jul 07 '25 04:07 JamesNewton

After launching DDE4, try redefining globalThis.PhysicsObject

then put breakpoints on your new code and verify that it is being called.

On Mon, Jul 7, 2025 at 12:32 AM JamesNewton @.***> wrote:

JamesNewton left a comment (cfry/dde#111) https://github.com/cfry/dde/issues/111#issuecomment-3043444842

Further confusion, errors, and stupidity, I'm sure. Sigh.

I've attempted to add the following lines

                debugger
                if (this.last) {
                	if ((this.last.p.x - p.x) < 0.0001) p.x = this.last.p.x
                	if ((this.last.p.y - p.y) < 0.0001) p.y = this.last.p.y
                	if ((this.last.p.z - p.z) < 0.0001) p.z = this.last.p.z
                } else this.last = {p:p, q:q}
                this.last.p = p
                this.last.q = q

after the line: https://github.com/cfry/dde/blob/dde4/src/simulator/physicsObject.js#L633 by copying out the entire update routine and replacing it in the editor with globalThis.PhysicsObject.update = function() { with the updated code following but that doesn't seem to be having any effect. Even with the Inspect window open, the debugger has no effect, and the source code in the bundle.js file IS still in effect.

I need to be able to run DDE4 from the source code.

— Reply to this email directly, view it on GitHub https://github.com/cfry/dde/issues/111#issuecomment-3043444842, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJBG7M5TCOW6CY3D3WPD7T3HHZ6TAVCNFSM6AAAAAB7PC3HLKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTANBTGQ2DIOBUGI . You are receiving this because you commented.Message ID: @.***>

cfry avatar Jul 07 '25 14:07 cfry