kripken / box2d.js

Port of Box2D to JavaScript using Emscripten
1.33k stars 196 forks source link

Issue with PostSolve and b2ContactImpulse #67

Open JustLoren opened 9 years ago

JustLoren commented 9 years ago

It appears that the b2ContactImpulse class is not implemented in the IDL bindings. It suffers from the same problem that the Shape's "verticies" do - the binding to an array. How would I go about implementing a workaround like Shape's "GetVertexCount" and "GetVertex" but for the b2ContactImpulse normals?

It's important as I cannot discern another way to diagnose how forceful the contact was.

ruskul commented 9 years ago

Are you sure PostSolve is even being called? It seems to me that presolve and postsolve are never called or if they are I have no way of knowing what function is called by the listener...

listener.BeginContact and listener.EndContact both get called but not .PreSolve(contactptr, oldManinfoldPtr) and PostSolve(contactPtr, impulse)

JustLoren commented 9 years ago

They are definitely being called - I just verified it in my app.

    var listener = new Box2D.JSContactListener();
    listener.BeginContact = function (contactPtr) {
        if (gameEngine.BeginContactOverride) {
            var contact = Box2D.wrapPointer(contactPtr, b2Contact);
            gameEngine.BeginContactOverride(contact);
        }
    }

    // Empty implementations for unused methods.
    listener.EndContact = function (contactPtr) {
        if (gameEngine.EndContactOverride) {
            var contact = Box2D.wrapPointer(contactPtr, b2Contact);
            gameEngine.EndContactOverride(contact);
        }
    };
    listener.PreSolve = function (contactPtr, manifoldPtr) {            
        if (gameEngine.PreSolve) {
            var contact = Box2D.wrapPointer(contactPtr, b2Contact);
            var manifold = Box2D.wrapPointer(manifoldPtr, b2Manifold);

            gameEngine.PreSolve(contact, manifold);
        }
    };
    listener.PostSolve = function (contactPtr, contactImpulsePtr) {            
        if (gameEngine.PostSolve) {
            var contact = Box2D.wrapPointer(contactPtr, b2Contact);
            var contactImpulse = Box2D.wrapPointer(contactImpulsePtr, b2ContactImpulse);

            gameEngine.PostSolve(contact, contactImpulse);
        }
    };

    this.World.SetContactListener(listener);
ruskul commented 9 years ago

Well, dang it, for whatever reason postSolve and PreSolve are not working in my game. The physics engine won't even call them and I couldn't find bindings for them. It works fine when I call it using box2d web but not ams.js ... Sorry I'm no help.

flimshaw commented 9 years ago

Also seeing the same behavior here. Can't seem to pull any data out of the impulse being returned by postsolve. Events are definitely getting called for me, but the impulse var is just a number, can't seem to use it to cast or return a pointer or anything.

@JustLoren, did you ever find a workaround?

JustLoren commented 9 years ago

@flimshaw, I'm sorry, but I moved towards a different solution and cannot recall how I worked around the issue. I believe I did by storing their velocities in PreContact, then checking their new velocities in PostContact. Using that, I could determine how hard each body was impacted by the change.