Jump to content

Oimo JS Joint Axis Help


Recommended Posts

I've been working in Oimo to make realistic rag doll models and noticed that making accurate axis limitations that are unique per axis doesn't seem to exist. The closest thing I see to creating this limitation is to generate a hinge joint, which spans a single limit motor across each axis. 

An example use case would be to create a hip joint to a leg that consists of a [ -30, 30 ] degree of movement on the Y axis to allow for leg twisting, and a [ 135, -45 ] degree of movement on the X axis to allow for forward and backwards movement for walking / running.

I made an attempt to modify Oimo to accommodate for this, but ran into issues with how the limit motors interacted causing extremely unrealistic / sporadic movement.

Question being, does anyone know how to do this with Oimo JS as is? Additionally, does anyone have a custom fork of Oimo JS that includes a custom joint that could handle these types of limitations.

Example Oimo Hinge-Joint Call in this project:

let myJoint = myWorld.add( {
      axe1:myJointParams.axis, // Axis, Scales Min/Max
      pos1:myJointParams.pointA.toArray( ), // Position Relative
      pos2:myJointParams.pointB.toArray( ),
      min:myJointParams.min, // Bottom of Rotation [DEG]
      max:myJointParams.max, // Top of Rotation [DEG]
      spring:[100,0.3] // Spring Force
    } );


Link to comment
Share on other sites

Hiya IT... welcome to the forum.  Whelp... although I am a "klutz" at physics, I sometimes make an "introductory" testing playground for new forum users.  So, here we go...


Clicking on screen... sends a little impulsing at part2 (the red box)... just for tipping over "the Z-hinged stack" and watching how everything acts.

Annoying crap:
1.  Had to remove the new directive in line 83.  new BABYLON.OimoJSPlugin().  Oimo runs much faster without it... nobody was ever able to tell me why, nor have I been able to learn why.
2.  I have brutally tortured min, max, and spring native parameters for Joint1.  NONE of them seem to work.  But, I dunno what they are for.  Min/max are BARELY documented.  Spring... not at all.  These are native parameters, and as-such, not really part of BJS.  But don't ya wish there were some Oimo docs around?
3.  Could Oimo run any slower?  My goodness.  I hijacked-in the Oimo executeStep function in lines 1-30, and disabled both beforeStep and afterStep... to see if I could find any lost speed.  Nope.
4.  Although collisions set TRUE on joint1, green tower (part 1) and red box (part2) never collide.  They freely overlap.  Part3 and part1 collide.  Part4 and part1 collide.  But those last two aren't pertinent, because the collisions parameter is talking ONLY about the mesh attached to each end of THAT joint.  So, main point, part2 suppose to collide with part1, and failing.

Oh well.  At least we have a testing playground to be discouraged-with, now.  Sure, I have Grand Theft Auto running in another window... but it's all idled-down, because otherwise, my CPU fan would be whizzing at double-speed.  :)  I've seen Oimo run at twice these speeds... even on bad days.  Something is wrong somewhere.  It could certainly be my programming. 

These physics engines are going to be the death of us all, with RaananW being the first to fall over dead.  :(  He's hauling a pretty heavy load... being our primary physics plugin custodian.  And, the floor is moving beneath his feet... ie. the new transformNode - that could easily affect the physics engines/plugins.

Wingnut is kind of sad over repeated physics engines issues.  I need to work harder to try to help RaananW, somehow.  ANYway... stay positive, we got a playground and we got geniuses in all directions.  Let's go hackin'.  If anyone can get spring, min, and max proven to work and show us how-so (by editing and saving more of these playgrounds)... that would be a great start.  Sorry if I inserted programming mistakes.  Party on!

PS:  Line 194  -  limit: [-10, 10]... just a goofy Wingnut test.  Change it back to min and max again.  Limit is probably for MOTORS and not for hinge joints.  :)

Link to comment
Share on other sites

Thank you @Wingnut for the demo. After reviewing the playground demo, I went ahead and threw in more joints to accommodate for the variations in axis. Divided the hip joints into smaller segments, etc. This does add approximately 4 additional joints to the model, and 4 additional bones. Not sure how this will impact performance when multiple models begin being generated. I will need to generate model disposal sometime soon that will handle this. See attached video for the [ possibly ] final prototype for the humanoid skeleton model.


Link to comment
Share on other sites

I went touring...  http://lo-th.github.io/Oimo.js/examples/test_ragdoll.html

See how close-together his body-parts are?  There's no min/max activity happening there at all.  That demo uses the "collisions" between ajoined mesh... to restrict the angle of the hinges.

Okay, this means war.  Time to get out my old "derived-from-source" badly-formated Oimo API page...  http://urbanproductions.com/wingy/babylon/misc/j2h02.htm

Load that mess into a browser window... and do in-doc search for "A hinge joint allows only for relative rotation of rigid bodies along the axis"

After some painful reading, you'll discover that Oimo hinge joints have NO min, max, or "spring" native parameters.  With Oimo hinges, it's all about "LimitMotors".

Scroll up a few lines... the LimitMotor class is right there.  Notice it has a lowerLimit, upperLimit, and a [frequency, dampingRatio].  (I think those are the parameter names of the spring [8. 0.2] crap seen in my demo.)

SO... we now know the CORRECT native parameter names to use for creating a "LimitMotor" to be added to the hingeJoint.  BJS OimoPlugin appears to have some handy methods.

AND, there's a class named MotorEnabledJoint!  We better do a playground search for that, eh?

Yuh, I think we have this Oimo "stubborness" under control, or near.  We OWN it!  Oimo hinges need a little different handling... but... now we know... now we conquer.  Well, someone else conquers... I only watch and giggle.  :)

Link to comment
Share on other sites

Ooooh, https://www.babylonjs-playground.com/#SFELK#82

Look at lines 181-191 there... a motor enabled slider... with limit and max and min and spring.  Hmm...and its an oimo world.  Maybe there's hope.  :)


MUCH more impulse power needed to move red box, now.  (click on screen).

SOMETHING happened when I switched all three joints to motorEnabled.  I think stuff is active!  That doesn't mean I know how to set the knobs, but.. I think the knobs are working.

(Wingnut mistakes in original demo... sorry).  Motors for joint2/3 not yet activated... lines 223/224 adjust.

Limit parameter is probably for motor. I think it is limit: [force, maxForce]

Teach us everything everyone learns, okay everyone?  (thx)

Just between us gals, I think RaananW (author of current plugins) "massages" those nativeParams a bit... in the background... within the Oimo plugin.  Even though there is no actual min/max nativeParams on an oimo joint... he allows them on motorEnabledJoints.  He converts min and max and spring... into the actual format needed... for use in REAL Oimo nativeParams.  He's just that kind of guy... shooting for "standardized" as much as possible.

Link to comment
Share on other sites


The reason the stable seems "faster" is due to the world scale parameter. It was set correctly between stable and the current latest branch. This is why Oimo worlds used to be huge (check the car demo's ground size - 4000) and now they can stay small. It simply looks slower, but imagine a 100 meter wide car falling 40 meters in real life - it will probably look the same as what we see here :)

I am trying to find a demo i can work with. Is there any playground link that is a start of what you are trying to achieve?

Link to comment
Share on other sites

Hey @Wingnut,

The Demo has been helpful in regards to making my skeleton model more accurate. I have recently discovered that I've been mis-using the hinge joint, realizing it limits the angle strictly to the single axis specified, not open-ended per axis. Example:

axis: [ 1, 1, 1 ], max: 45, min: -45, spring:[ 100, 0.2 ]... This does not create a cone-style movement axis, but instead keeps the angles of axis x, y, and z equal to eachother. So, movement is limited to a single plane. I will keep making adjustments until I reach a working model that fits well with my use-case. Will update this thread if anything else comes up.

Thanks again for all the assistance everyone.

Link to comment
Share on other sites

Hi again IT, good to hear. 

Yeah, the ball-and-socket hinge for the hip... could be a challenge.  In fact, all limb joints have some allowed "z-axis spin".

There IS a ball-and-socket joint in Oimo.  But perhaps more important, there is a hinge2joint/wheeljoint  (same things, I think).

From my crappy Oimo API page...

"A wheel joint allows for relative rotation between two rigid bodies along two axes."

That sounds promising, eh?  It has localAxis1, localAxis2, rotationalLimitMotor1 and rotationalLimitMotor2 settings.  YAY!

A playground search for wheeljoint doesn't explode with returns, so perhaps you'll need to do some serious experiments with it. 

And don't forget Raanan's nice Oimo Car tutorial.  (thx Raanan!)  I KNOW it talks about wheel joints and has a nice picture.

If/When you discover things about Oimo wheel joints, could you show/tell us, here or somewhere?  Thanks!

Link to comment
Share on other sites

Oimo supports more than one constraint on each two pairs of bodies. You can see that in the Hinge Joint constructor - https://github.com/lo-th/Oimo.js/blob/gh-pages/src/constraint/joint/HingeJoint.js#L51 (and line 52). The hinge joint is defining two constraints - one linear and one rotational on all 3 axes. The rotation3 constraint (https://github.com/lo-th/Oimo.js/blob/gh-pages/src/constraint/joint/base/Rotational3Constraint.js) has the limit definitions defined in the first of 3 limiters (the others are limited so that the hinge will work correctly). 

Just to speak about the concept - to create a hip connected to the torso, i would:

1) Create 3 meshes - torso, connector, hip. Connector is invisible and is only there to allow you to defined the joints individually!

1) Connect the connector to the torso using a hinge joint on the y axis (or a ball-and-socket joint which would fit better by name, but oimo's ball-and-socket don't have a limit definition). This will allow the hip to turn around itself.

2) Connect the connector to the hip using another hinge-joint in the x axis (assuming z is depth and the person is looking at me), setting the limiter correctly


Create a ball-and-socket and keep on testing post-solve (the after-physics step callback would be enough) if the rotation is passing the limit and reset the rotation if it does. You can do it directly on the Oimo physics body, or on the babylon mesh which will update the physics engine in the next frame.

In my car tutorial (https://blog.raananweber.com/2016/09/06/webgl-car-physics-using-babylon-js-and-oimo-js/) I would say that the suspension would be your "connector". The mesh can be invisible, and you will need to define the pivots correctly so it would look like the hip is connected to the torso.

I will have the time in the next few days for sure and will try creating a simple lower-body-demo :) 

Link to comment
Share on other sites

Thank you for all the information everyone,

I've built the skeleton in a way that allows for the rag-dolls to move as needed. Attached are three demos. These demos are set to 1 unit => 1 meter, gravity: [0, -1, 0]:

arc-engine-ani-rag shows a translation between animated model and rag-doll model and back. In this case, since no animation is present, it will simply freeze the model.

arc-engine-rag-break shows a random joint break that separates the rag-doll.

arc-engine-ragdoll shows the rag-doll simply falling to the platform.

The use case for these will be for a first-person shooter, sorry I didn't shared this information earlier.




Link to comment
Share on other sites

Thanks everyone,

Will be providing my platform demo here, for people to review, once i complete the skeleton. Still need to add a few things: Model Loading, Animation sets, Sleep/Wake handler, etc. I might also update Oimo to run on a webworker before then as well.

Another question for those who are experienced with web-workers, is it worth, or even possible, to break down oimo into multiple web-workers? This would allow me to scale animation frames depending on each webworker. So, if animations become a tasking process, the animation webworker would lose momentum but the physics would still operate as needed.

Let me know if anyone has any input on this.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...