kripken / ammo.js

Direct port of the Bullet physics engine to JavaScript using Emscripten
Other
4.17k stars 559 forks source link

Next Major Update - Help Required! #60

Open kripken opened 10 years ago

kripken commented 10 years ago

We are close to a new major update. This will bring:

Work is in the webidl branch. The current status is that all tests and the WebGL demo pass. The tests report a 20% speedup.

This is far from complete, however - help is required. The new bindings are generated explicitly, using an IDL file that declares what should be wrapped. This avoids all the horrible hacks with the old bindings generator that tried to be 100% automatic (but a quick look through the bug tracker here shows it was anything but).

The ammo.idl file in the repo has enough detail for all the tests and the WebGL demo, but nothing else. So it is very likely your project will hit a missing function or class somewhere. It's very easy to fix those things, just add to the idl file, rebuild, and send a pull request, see details next

How to Contribute

  1. Try your codebase, see what is missing.
  2. Add to ammo.idl what you need.
  3. Rebuild using python make.py (you must use up to date emscripten, on master or incoming)
  4. Run the test suite to be sure you didn't break anything, python test.py
  5. Optionally, add a test to the test suite.
  6. Make a pull request.

IDL docs are going up on https://github.com/kripken/emscripten/wiki/WebIDL-Binder . While incomplete, you can figure out the important stuff from looking at the already-present stuff in ammo.idl. If something doesn't make sense, feel free to ask.

kripken commented 10 years ago

Oh, regarding smaller builds: you can edit the IDL file for your actual build so it doesn't contain stuff you don't actually use, which is another benefit of the new bindings generator.

lzantal commented 10 years ago

Hi,

I don't see the webidl branch. Is it not up yet?

lo-th commented 10 years ago

demo work for me, but is hard to compile i need all function of ammo for my lab test.

kripken commented 10 years ago

I merged to master now, so no need for using a special branch.

lo-th commented 10 years ago

hi, maybe a great simple library to test with new emscripten http://gamma.cs.unc.edu/RVO2/ new emscripten install are great but i have error on compile

willeastcott commented 10 years ago

Let's say I want to expose:

int getNumManifolds() const;

from btCollisionDispatcher. Will the following suffice in the ammo.idl file?

interface btDispatcher {
};

interface btCollisionDispatcher : btDispatcher {
  void btCollisionDispatcher(btDefaultCollisionConfiguration conf);
  long getNumManifolds();
};

Or do I need to account for the const somehow? The reason I ask is that I have exposed:

interface btCollisionWorld {
  btDispatcher getDispatcher();
};

This function returns a btDispatcher instance, but when I call dispatcher.getNumManifolds, the function is undefined. I'm conscious that getNumManifolds is declared in btCollisionDispatcher, not btDispatcher.

While I'm on the subject, what's the difference between:

interface btCollisionDispatcher : btDispatcher {
};

and

interface btCollisionDispatcher {
};
btCollisionDispatcher implements btDispatcher;

Thanks!

willeastcott commented 10 years ago

Just thinking about it, perhaps it would be good to have a version of ammo.idl that exposes everything and developers can just delete what they don't need instead of add what they do.

kripken commented 10 years ago

You can add [Const] btDispatcher getDispatcher(); if you need it to be const in order for the generated glue code to compile.

I wasn't aware of interface X : Y { syntax being possible, not sure what it does. Perhaps those are identical? I've only tried to write implements as in the second code sample.

I agree we should expose as much as possible, and let people delete what they don't need.

willeastcott commented 10 years ago

So doesn't that declare the return value of const rather than the function being const?

As for the colon syntax, this is in ammo.idl:

interface btDispatcher {
};

interface btCollisionDispatcher : btDispatcher {
  void btCollisionDispatcher(btDefaultCollisionConfiguration conf);
};

That's the only instance of that notation in the whole file and I wasn't sure what made that class special (if anything).

Going back to my original problem, I have:

interface btCollisionWorld {
  btDispatcher getDispatcher();
};

and

interface btDispatcher {
};

interface btCollisionDispatcher : btDispatcher {
  void btCollisionDispatcher(btDefaultCollisionConfiguration conf);
  long getNumManifolds();
};

When I call getDispatcher on the collision world, it returns a btDispatcher object. With the old version of Ammo, I just called dispatcher.getNumManifolds and the call would succeed because the instance was actually a btCollisionDispather. Now the function is undefined. Do I now have to somehow cast the btDispatcher to a btCollisionDispatcher now in my JS? It's probably more likely I've just made a mistake in ammo.idl, but I'm not sure.

kripken commented 10 years ago

I don't think it matters if the function is const? Do you get a compilation error? The glue code we emit should work without const functions, I believe.

I didn't notice I wrote that colon notation, heh - no idea what it does. I fixed it now. Is your problem fixed when you use the "implements" notation as the idl now uses consistently?

willeastcott commented 10 years ago

Oh, sorry, I just noticed that getNumManifolds actually is defined in btDispatcher as pure virtual. Duh, how did I miss that. ;o)

So next problem. I've exposed btVector3::setValue, which takes 3 arguments (x, y and z). However, btVector4 implements btVector3 and overloads setValue with x, y, z and w as arguments.

How do I deal with overloads in a subclass in the IDL file?

willeastcott commented 10 years ago

Just to be clear about what I've done, I have:

interface btVector3 {
  void btVector3();
  void btVector3(float x, float y, float z);
  float x();
  float y();
  float z();
  void setX(float x);
  void setY(float y);
  void setZ(float z);
  void setValue(float x, float y, float z);
  [Operator="*=", Ref] btVector3 op_mul(float x);
};

interface btVector4 {
  void btVector4();
  void btVector4(float x, float y, float z, float w);
  float w();
  void setValue(float x, float y, float z, float w);
};
btVector4 implements btVector3;

And this generates the following error:

Traceback (most recent call last):
  File "/home/will/emscripten/tools/webidl_binder.py", line 33, in <module>
    data = p.finish()
  File "/home/will/emscripten/third_party/WebIDL.py", line 4971, in finish
    production.finish(self.globalScope())
  File "/home/will/emscripten/third_party/WebIDL.py", line 658, in finish
    [additionalMember.location, member.location])
WebIDL.WebIDLError: error: Multiple definitions of setValue on Interface 'btVector4' coming from 'implements' statements, <unknown> line 13:2
  void setValue(float x, float y, float z);
  ^
<unknown> line 21:2
  void setValue(float x, float y, float z, float w);
  ^
Traceback (most recent call last):
  File "make.py", line 80, in <module>
    assert os.path.exists('glue.js')
willeastcott commented 10 years ago

Another question. If I define:

interface btPersistentManifold {
  btCollisionObject getBody0();
  btCollisionObject getBody1();
};

I get the following error:

glue.cpp:316:10: error: cannot initialize return object of type
      'btCollisionObject *' with an rvalue of type 'const btCollisionObject *'
  return self->getBody0();
         ^~~~~~~~~~~~~~~~
glue.cpp:320:10: error: cannot initialize return object of type
      'btCollisionObject *' with an rvalue of type 'const btCollisionObject *'
  return self->getBody1();
         ^~~~~~~~~~~~~~~~
2 errors generated.

How do I specify a const return type?

kripken commented 10 years ago

Ok, a fix for the first issue is on emscripten incoming. WebIDL will now accept a child interface that defines a function with the same name as the parent, overriding it.

For const, you should add [Const] on the function, [Const] type name();

willeastcott commented 10 years ago

Thanks for fixing problem no.1! As for problem no.2, if I change my IDL file to:

interface btPersistentManifold {
  [Const] btCollisionObject getBody0();
  [Const] btCollisionObject getBody1();
};

I get the following error:

WebIDL.WebIDLError: error: Unknown extended attribute Const on method, <unknown> line 144:3
  [Const] btCollisionObject getBody1();

The C++ function signatures are:

const btCollisionObject *   getBody0 () const
const btCollisionObject *   getBody1 () const
kripken commented 10 years ago

Ok, I see, we had support only for attributes, not methods. Fixed now.

kripken commented 10 years ago

Merged a pull from @willeastcott with lots of IDL updates, and pushed a new build with that.

ghost commented 10 years ago

There is an old function on the Rigidbody: setWorldTransform(btTransform worldTrans), but it doesn't exist in the Bullet API. I do see it as a function of the MotionState, but calling it doesn't work the same way as the old Ammo RigidBody function.

I'm wondering if someone created a utility function to do some automagic stuff with the MotionState, and if so, can it be added to the new Rigidbody interface functions, or is there a 'new' way to get the same results as calling the old setWorldTransform on the Rigidbody?

Here's an example of what I mean:


ctx.body.getMotionState().getWorldTransform(ctx.ptrans);
ctx.ptrans.setOrigin(ctx.body.getWorldTransform().getOrigin());
ctx.pquat = ctx.ptrans.getRotation();
ctx.pquat.setValue(ctx.quat.x, ctx.quat.y, ctx.quat.z, ctx.quat.w);
ctx.ptrans.setRotation(ctx.pquat);
// this no longer exists...
ctx.body.setWorldTransform(ctx.ptrans);

ctx.quat is a Quaternion from our engine ctx.ptrans is an Ammo.btTransform ctx.pquat is an Ammo.btQuaternion ctx.body is an Ammo.btRigidbody

It works like a charm with the old gh-pages builds, but it doesn't exist on the master Rigidbody class, and when I went to add it, I was surprised it also doesn't exist on the Bullet API.

kripken commented 10 years ago

Is the problem that bullet removed those functions, or that we don't expose them in our builds now?

On Mon, May 19, 2014 at 8:50 PM, Brett Unzaga notifications@github.comwrote:

What happened to rigidBody.setSleepingThresholds() or rigidBody.setWorldTransform() ? Is there a new or better way to set Rotations or Position now?

— Reply to this email directly or view it on GitHubhttps://github.com/kripken/ammo.js/issues/60#issuecomment-43583910 .

ghost commented 10 years ago

I guess if it is a direct port of Bullet, they must have removed that function from the Rigidbody. Perhaps it is called directly on the MotionState now.

rhulha commented 10 years ago

Looks like setActivationState and btVehicleTuning are missing, I suspect more of the Vehicle stuff to be missing :-(

kripken commented 10 years ago

See the latest pull requests, stuff is being added all the time, and it's easy to add the things you find are missing.

rhulha commented 10 years ago

True and I want to help ! But it is hard to test local changes since I am struggling to get it to compile. See the other ticket.

Brenden-Morales commented 10 years ago

I'm trying to add in the btHeightfieldTerrainShape and I've hit a complete wall. I've put :

interface btHeightfieldTerrainShape{
    };
btHeightfieldTerrainShape implements btConcaveShape;

at the bottom of the ammo.idl file and I'm getting three : "error: unknown type name 'btHeightfieldTerrainShape'" messages. I'm having a real tough time figuring out what I need to do to get this to work.

Edit: Ahhh I generated the doxygen docs for the bullet bundled with ammo and see no reference to it. That's probably the issue.

kripken commented 10 years ago

It looks like btHeightfieldTerrainShape.h is not included by default. I pushed a commit to make it easy to add more includes, and added that include.

Brenden-Morales commented 10 years ago

Cool, I was thinking that I needed to edit that location but I've got zero experience with python. Many thanks!

josephrocca commented 10 years ago

Soft bodies in javascript?! The world won't know how to react

TNing commented 10 years ago

Hi, I want to help to get the btKinematicCharacterController to work. I use a simple WebGL test app based upon https://github.com/bulletphysics/bullet3/blob/master/Demos/CharacterDemo/CharacterDemo.cpp

Most things are working fine, but when I try to declare the function getOverlappingPairCache (used in CharacterDemo/CharacterDemo.cpp:85) in ammo.idl (yes, I know that this function is pure virtual but I do not know how to declare this, sorry for that):

interface btBroadphaseInterface { btOverlappingPairCache getOverlappingPairCache(); };

I run into the following problem: [...] Traceback (most recent call last): File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/emscripten.py", line 1491, in _main(environ=os.environ) File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/emscripten.py", line 1479, in _main temp_files.run_and_clean(lambda: main( File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/tools/tempfiles.py", line 39, in run_and_clean return func() File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/emscripten.py", line 1487, in DEBUG_CACHE=DEBUG_CACHE, File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/emscripten.py", line 1374, in main jcache=jcache, temp_files=temp_files, DEBUG=DEBUG, DEBUG_CACHE=DEBUG_CACHE) File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/emscripten.py", line 861, in emscript_fast cwd=path_from_root('src'), error_limit=300) File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/tools/jsrun.py", line 31, in run_js cwd=cwd) File "/usr/lib/python2.7/subprocess.py", line 710, in init errread, errwrite) File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory Traceback (most recent call last): File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/emcc", line 1230, in final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args) File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/tools/shared.py", line 1464, in emscripten assert os.path.exists(filename + '.o.js'), 'Emscripten failed to generate .js' AssertionError: Emscripten failed to generate .js Traceback (most recent call last): File "make.py", line 119, in temp) File "/home/user/build_temp/build_ammo/emsdk_portable/emscripten/master/tools/shared.py", line 1432, in emcc assert os.path.exists(output_filename), 'emcc could not create output file: ' + output_filename AssertionError: emcc could not create output file: ../../builds/temp.js

Edit: BTW: That error is independend whether you put the getOverlappingPairCache declaration into btBroadphaseInterface declaration or into one of the derived class declarations (or even into all of them) like btDbvtBroadphase, btAxisSweep3

Is there a way to declare that method or should we find a way around it? I'm not sure but I think you need that method for getting the btKinematicCharacterController to work. Am I wrong?

Edit: It was a problem with my building environment and I fixed it. Now everything works fine except the tests:

0 : regression tests basics.js Traceback (most recent call last): File "test.py", line 38, in output = run(fullname) File "test.py", line 21, in run return Popen(JS_ENGINE + ['-e', 'gcparam("maxBytes", 1024_1024_1024); load("' + build + '"); load("' + os.path.join('tests', 'testutils.js') + '")', filename], stdout=PIPE).communicate()[0] TypeError: cannot concatenate 'str' and 'list' objects

kripken commented 10 years ago

Those errors look like an older emscripten version. It should work on incoming, perhaps not on others.

PMPepper commented 10 years ago

Hi, I have come across various missing methods in the current build of ammo.js. I would like to help out, but I'm afraid I don't know anything about C++ or python, so I think adding the bindings and recompiling them myself is beyond me really. The methods that I have found that are missing are:

btRigidBody: -applyCentralForce -applyCentralImpulse

btQuaternion: -setEuler

Also, many of the operators do not appear to have equivlents, such as multiplying a vertor by a transform (I see you mentioned experimental operator support, e.g. op_mul, but this isn't present on a btTransform object).

Is this information helpful? Should I mention any other missing methods I come across?

aswinstha commented 9 years ago

Hi, I wanted to implement btConvexPointCloudShape for my project, is it supported in the current build or should I generate it?

a735561656 commented 8 years ago

Hi,I want to use btCollisionObjectWrapper now,but in ammo.idl ,they are as follows.

[NoDelete] interface btCollisionObjectWrapper { };

So lack of much function.can you give me some help. Please email to me 735561656@ qq.com.Thank you very much!

navigator117 commented 5 years ago

btWorldImporter, btBulletWorldImporter is needed

radman-x commented 5 years ago

Need support for serialize() for all objects in Ammo.IDL:

Should output to binary/typed array. Also, need method to deserialize resulting typed array.

crazyquark commented 5 years ago

Hello, I need btCompoundShape::updateChildTransform() I added it myself to ammo.idl, I built it but the tests don't run, seems like there is an issue with how tests are run. Do you maybe have a docker for building & testing ammo.js?

mast4461 commented 5 years ago

@crazyquark, a virtual machine or container for building and testing ammo.js would be fantastic!

crazyquark commented 5 years ago

@mast4461 it seems there already is one, huh: https://github.com/kripken/ammo.js/blob/master/docker-compose.yml

RaiNova commented 2 years ago

Would anybody be so kind and add the following to ammo.js (via ammo.idl, and then build it, I guess)? Unfortunately, I cannot do it myself:

... or help me build ammo.js myself on Windows - I gave up after 1hr?

kylebakerio commented 2 years ago

I just want to mention--having a link to an issue from 2014 that previews as "we're about to have a major new release!" on the top of the readme makes one immediately wonder if the project is dead when you're new here.... and until 20 days ago, the most recent comment was from 3 years prior.

Seems like the readme should be updated to remove a link to this and to not suggest that something that happened in 2014 is "recent"?

kripken commented 2 years ago

Thanks @kylebakerio , I'll update the readme.

(2014... time flies :fly: )

kylebakerio commented 2 years ago

Thank you so much for managing this project, it's a gem! :)