ammo.js icon indicating copy to clipboard operation
ammo.js copied to clipboard

No Ammo.Runtime.addFunction or Ammo.addFunction

Open MackeyK24 opened this issue 6 years ago • 9 comments

Is there some setting i need to to build Ammo.js with so i get the Ammo.Runtime.addFunction or Ammo.addFunction.

How the heck is everybody using code like:

var fp = Ammo.Runtime.addFunction(callback);

when i put ammo.js on the web page... Ammo.Runtime.addFunction is not defined.

Please help...

MackeyK24 avatar May 20 '19 13:05 MackeyK24

Man... I dont know if this codebase or its instructions are PRODUCTION READY

After almost 2 Weeks of just play with EVERY FREAKING EMCC SWITCH i can find. I think i finally figured it out... But Jesus Christ... With the instructions listed (that dont work completely)...

That took freaking forever

RECAP... These instructions are MISSING SOMETHING VERY IMPORTANT:

Hey everyone. I just wanted to share a pretty solid solution I have. I can't send a pull request, because you need to make a small change in the Bullet code. This info assumes you have a working build environment, and can recompile Ammo.js from the Bullet sources.

In Bullet, in the file btDiscreteDynamicsWorld.h add

void setContactAddedCallback(unsigned long callbackFunction) { gContactAddedCallback = (ContactAddedCallback)callbackFunction; } void setContactProcessedCallback(unsigned long callbackFunction) { gContactProcessedCallback = (ContactProcessedCallback)callbackFunction; } void setContactDestroyedCallback(unsigned long callbackFunction) { gContactDestroyedCallback = (ContactDestroyedCallback)callbackFunction; } In Ammo, in the ammo.idl file add

interface btDiscreteDynamicsWorld { void setContactAddedCallback(long funcpointer); void setContactProcessedCallback(long funcpointer); void setContactDestroyedCallback(long funcpointer); ... } In make.py, add -s RESERVED_FUNCTION_POINTERS=20 to the array emcc_args. In my project, that's on line 29, but might have changed since I forked.

Go ahead and build Ammo.

Finally, there are a few hoops to jump through in the JS. Note that you'll have to manually cast the incoming pointers to the proper type. I've made an example here for gContactProcessedCallback, and you can probably figure out the others from the Bullet docs.

function collisionCallbackFunc( cp,colObj0,colObj1) { colObj0 = Ammo.wrapPointer(colObj0, Ammo.btRigidBody); colObj1 = Ammo.wrapPointer(colObj1, Ammo.btRigidBody); cp = Ammo.wrapPointer(cp, Ammo.btManifoldPoint); //trigger your events. }

var collisionCallbackPointer = Ammo.Runtime.addFunction( collisionCallbackFunc); var dynamicsWorld = new Ammo.btDiscreteDynamicsWorld(...); dynamicsWorld.setContactProcessedCallback(collisionCallbackPointer); Finally, don't forget to set CF_CUSTOM_MATERIAL_CALLBACK on all bodies. We have hard coded this like so, wherever we set the flags

this.body.setCollisionFlags(this.collisionFlags | CF_CUSTOM_MATERIAL_CALLBACK); FYI the value of CF_CUSTOM_MATERIAL_CALLBACK is 8.

This solution is working great at Virtulous. Before, the only way to get consistent collision notifications was to test the manifolds after each simulation step. If there were more than a single substep, you could end up missing contacts that were created then destroyed within a single step. So, we had to choose between physics accuracy and getting the callbacks.

Missing Settings

Update make.py

EMCC_ARGS: emcc_args += '-s RESERVED_FUNCTION_POINTERS=20'.split(' ') emcc_args += '-s EXTRA_EXPORTED_RUNTIME_METHODS=["addFunction"]'.split(' ')

Or else you WONT have a Ammo.addFunction

Note: Not Ammo.Runtime.addFunction

PLEASE FIX DOCUMENTATION/INSTRUCTIONS so the next guy wont speed weeks trying to figure out WTF

MackeyK24 avatar May 20 '19 14:05 MackeyK24

Thanks @MackeyK24, yeah, the docs and build instructions here are out of date. Can you please open a PR to update make.py?

kripken avatar May 20 '19 16:05 kripken

Yo @kripken ... Which part of make.py ???

1... Add Default Function Pointers = 20 - ????

emcc_args += '-s RESERVED_FUNCTION_POINTERS=20'.split(' ')

2... Add Default Exported Runtime Method = ["addFunction"] - ???

emcc_args += '-s EXTRA_EXPORTED_RUNTIME_METHODS=["addFunction"]'.split(' ')

Which ones do you want to PR the make.py. Number 1 or Number2 or Both - ???

Also What about DEFAULT support for Contact Callbacks

Should i make PR for files:

ammo.idl

interface btDiscreteDynamicsWorld {
   void setContactAddedCallback(long funcpointer);
   void setContactProcessedCallback(long funcpointer);
   void setContactDestroyedCallback(long funcpointer);
}

btDiscreteDynamicsWorld.h

void setContactAddedCallback(unsigned long callbackFunction) {
   gContactAddedCallback = (ContactAddedCallback)callbackFunction;
}
void setContactProcessedCallback(unsigned long callbackFunction) {
   gContactProcessedCallback = (ContactProcessedCallback)callbackFunction;
}
void setContactDestroyedCallback(unsigned long callbackFunction) {
   gContactDestroyedCallback = (ContactDestroyedCallback)callbackFunction;
}

What do you think about those changes ???

MackeyK24 avatar May 20 '19 21:05 MackeyK24

Hmm, thanks, yeah - I'm not sure where to add that in make.py. I'll find some time later today to look into implementing that myself.

For the IDL change, yes, pleae open a PR with that.

I'm not sure why chanes to a .h file would be needed though? But if so please explain.

kripken avatar May 20 '19 21:05 kripken

Also, where do you see documentation that refers to Ammo.addFunction or Ammo.Runtime.addFunction? We should update those, but I don't see any in this repo?

kripken avatar May 20 '19 21:05 kripken

Yeah the contact callbacks need the part to handle casting the raw function pointers and the functions that the ammo.idl uses:

ammo.idl needs this fix:

interface btDiscreteDynamicsWorld {
   void setContactAddedCallback(long funcpointer);
   void setContactProcessedCallback(long funcpointer);
   void setContactDestroyedCallback(long funcpointer);
}

and of course the actual class btDiscreteDynamicsWorld.h where those function will live:

void setContactAddedCallback(unsigned long callbackFunction) {
   gContactAddedCallback = (ContactAddedCallback)callbackFunction;
}
void setContactProcessedCallback(unsigned long callbackFunction) {
   gContactProcessedCallback = (ContactProcessedCallback)callbackFunction;
}
void setContactDestroyedCallback(unsigned long callbackFunction) {
   gContactDestroyedCallback = (ContactDestroyedCallback)callbackFunction;
}

JavaScript Example Usage:

function collisionCallbackFunc( cp,colObj0,colObj1)
{
            colObj0 = Ammo.wrapPointer(colObj0, Ammo.btRigidBody);
            colObj1 = Ammo.wrapPointer(colObj1, Ammo.btRigidBody);
            cp = Ammo.wrapPointer(cp, Ammo.btManifoldPoint);
            //trigger your events. 
}

var collisionCallbackPointer = Ammo.addFunction(collisionCallbackFunc);
var dynamicsWorld = new Ammo.btDiscreteDynamicsWorld(...);
dynamicsWorld.setContactProcessedCallback(collisionCallbackPointer);

NOTE: These changes spawn from the post: https://github.com/kripken/ammo.js/issues/82#issuecomment-283164428

MackeyK24 avatar May 20 '19 21:05 MackeyK24

I think it may be possible to set gContactAddedCallback with a getter/setter as well. But I don't remember the details offhand.

kripken avatar May 21 '19 18:05 kripken

See https://github.com/kripken/ammo.js/pull/252 for adding addFunction support.

kripken avatar May 21 '19 18:05 kripken

What about PR https://github.com/kripken/ammo.js/pull/251

MackeyK24 avatar May 21 '19 22:05 MackeyK24