No Ammo.Runtime.addFunction or Ammo.addFunction
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...
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
Thanks @MackeyK24, yeah, the docs and build instructions here are out of date. Can you please open a PR to update make.py?
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 ???
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.
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?
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
I think it may be possible to set gContactAddedCallback with a getter/setter as well. But I don't remember the details offhand.
See https://github.com/kripken/ammo.js/pull/252 for adding addFunction support.
What about PR https://github.com/kripken/ammo.js/pull/251