Jump to content

The Continuing CannonJS HeightmapImpostor Story


Recommended Posts

Hi kids!

   Admiral Deltakosh recently adjusted some code to get our CannonJS heightMap impostors working somewhat better. (still avoid non-square terrains)

BUT (there's always a but)... check this out [PG test #45].  Wait for all the movement to stop.  Are all the boxes sitting on their edges? 

Impostor-meshShape rotational-sync issue?  Me thinks so.

Also, I think I see muddy ground (mesh slightly sinking into terrain).  We will know more... once the rotation issue is solved. 

I mentioned it in this recent discussion (scroll to bottom), but DK has been pretty busy, so we should try to puppy-chow these issues (try to solve without expert help).

But... the rotation issue started recently - possibly caused by recent activity in heightmapImpostor or boundingBox code. 

@Deltakosh, I will ask blunt.  Did your recent heightmapImpostor fix... somehow affect boxImpostor rotations?

Do you/anyone see boxes in #45 demo... resting/sleeping on their edges? 

Any thoughts/ideas?  Should I be in bugs?  Should I have continued talking in the github comments?

(I fixed a bad link to pg #45 in github comments) 

I never know how to report stuff.  :)   Over 60% of my reports... end with finding a Wingnut mistake. 

Link to comment
Share on other sites

Thx, that's good news!

I THINK I understand the bad box rotations.

Check this out... [link demo #47]

Lookin' good, huh?  Boxes laying flat, no significant mud (no slighty-sinking mesh), YAY!

And the #45 demo?  Boxes (mostly) laying on edges, right?

Got good eyes?  What's the difference between #45 (broken) and #47 (working)?

It is the ORDER of these two lines:

ground.physicsImpostor = new BABYLON.PhysicsImpostor(ground, BABYLON.PhysicsImpostor.HeightmapImpostor, { mass: 0, restitution: 0.1 }, scene);

Keep them in THIS order... for maximum goodness.  Reverse the order, and it will cause a Wingnut to go insane (and make boxImpostor rotations upon CannonJS heightmapImpostors... become wonky).  :D  Whooda thunkit?


Next issue... WHY does #47 run in slow-motion often/always? 

Change URL to #31, and IT should run much faster.  Then change URL to #47 again, and IT will run faster, too.  What the heck?

At least, that's how it looks to me.  Anyone else?


Heads-up:  The NEXT issue will be... Why can't we do rectangular heightMapImpostors?  Only square terrains work, currently.  This is a much larger "issue" than previous ones.  :o  (Wingy hears his dog whining in the other room.)

Link to comment
Share on other sites

Trust @Wingnut to find an amazing sequence of commands that drive a physics engine crazy :)

Hello friend!

A lot have changed, and I need to follow up on changes in the physics engine to fully answer that.

It seems like the flat shading changes the vertex data in a way that is not compatible with cannon's heightmap (or better yet - with the way we implemented the mesh-to-heightmap conversion). I will need to look deeper into it and understand why. I believe it is a problem with the way I implemented the heightmap functionality, for two reasons - one - this implementation is way too complex to be bug free. and two - http://www.babylonjs-playground.com/#1RKZXB#49 , it works wonderfully (but yet slowly) with a mesh impostor (and spheres. no cubes allowed, sadly).

The reason it works the other way around is that it is using the original heightmap to create the physics body. afterwards you can change the vertex data of the mesh and it won't really matter.


About the slowness - that's an interesting thing. Again, I need to follow up on changes made to the engine, but it seems like the step functionality was changed a bit. in playground #31 there is an implementation of the entire physics engine, which overwrites Babylon's implementation. Afterwards, going to a different playground will not reload the page but only the playground, which means - the implementation from #31 is still active. Makes sense?

Again - seems weird to me, but I can't tell before checking the entire process.


To your last question (or better yet - saving you the trouble of writing another post after giving us a heads up - this is cannon's limitation. Heightmap are so quick and wonderful because of theway they are implemented. Since it is an impostor, you can do whatever you want with it (turn it, rotate it, throw it in the air, convert it to little cubs and smash it, you know - anything). But it will stay a perfect square. I remember trying to avoid this limitation to no avail. But that was a year ago or so. I might be smarter now. While looking at the heightmap implementation, I will check cannon (non-existing) documentation to see if something pops up.

Link to comment
Share on other sites

[Wingy hugs Raanan].  Good to see you!  Excellent thinking on all issues, too, thx.  I don't think anyone will complain about lack of rectangle terrain, but perhaps we could output a warning if someone tries a rectangle.


The fast/slow issue... let's call that the 4731 issue.  (PG #47 speeds up after visiting #31)  :)  I was hoping to have more info about that, by now, but I got slow.

Likely not related but.. remember when we discovered that Oimo physics ran MUCH faster when we removed the 'new' in...

scene.enablePhysics(new BABYLON.Vector3(0, -9.8, 0), new BABYLON.OimoJSPlugin());  ?  That was back in 2.5 and perhaps even earlier, and we never discovered why.

Or perhaps I forgot WHY.  :)  Anyway, I am wondering if this issue, and 4731... are related.

I'll do some step watching/testing in the morning... and try to help.


Deltakosh made one minor change to a line of code (code that is likely yours):  https://github.com/BabylonJS/Babylon.js/blob/master/src/Physics/Plugins/babylon.cannonJSPlugin.ts#L375

(this concerns heightmapImpostors ONLY, as you already know) :) We/He changed boundingBox.center to boundingBox.centerWorld  (a naming thing only, we thought).  That change... fixed the "physics in only one quadrant of heightMap" issue.  That is the issue that I cancelled the PR-for.  I was trying a kludge-fix, and that was not the problem. 

The problem was that ANOTHER PR... had accidentally made a change to bb.center.  Your code just needed update to bb.centerWorld.  (I hope I explained that sanely).  I'm just glad things are working better and better.

According to recent polls, the CannonJS heightmapImpostor is the #1 most-loved impostor of all.  It is important for many many games.  A great feature!

Personal:  I hear (from insider sources) that you have embarked on a large undertaking, @RaananW .  I hope that is going as well as hoped-for.  Feel free to tell us a few words about it.  Use Wingnut Chronicles, if you wish.  thx.  ;)

Link to comment
Share on other sites

ooookay... regarding 4731 issue - Why are some heightMaps slow, and why are some fast?

Wingnut tests in Firefox ONLY.  Verify/report, as wanted.  Do complete PG reload between tests.

After a miserable process-of-elimination, may I present playground #61 (fast) and playground #62 (slow)

The difference?  Lines 3-5. 

-- The slow version (#62) uses default BJS .executeStep().

-- The fast version (#61) uses SAME .executeStep() code, brought into playground scope.

Weird!  Fascinating.  We are hot-on-the-trail of THIS little anomaly!  :)

Remember, complete reload when moving from 61 to 62.  If 62 is fast, then you didn't do a complete reload since previous-viewing of 61.

Comments welcome, always.  We'll now call this 'the 6162 issue'.  :)

Link to comment
Share on other sites

Weird. I've done quite a bit of testing heightmaps with Cannon. And one thing that happened every time, was the physics body falling through the heightmap, either at the very beginning or at least shortly after the first contact. Keep in mind that this problem was with the raycastVehicle, and only while running the sim on Node. I just stole your matrix from 61, and applied it to one of my older test projects, and oddly enough, I haven't had a fall-through yet, neither on Node or Babylon. although, according to some posts on SO and issues on GH, it might happen eventually. It would be damn awesome not having to create manual static bodies to form the ground, if I could instead be using a heightmap. Hmm. Maybe it's the denser geometry and significantly more faces? I'll have to test this. This is of course my own issue, not entirely related to this. But still :P

I still have issues aligning the Cannon heightmap to the meshes created with Babylon. I feel like I'm blindly trying to solve a puzzle. Weirdness is going on.



Link to comment
Share on other sites

You're a friggin' physics GOD, Rags!  Geez!  Some of that is probably Raanan's code, too, but still.  Phew.  Marry me, will ya?  :D

Yeah, you're just a few units of Y... out of kilter.  No problems... 5 minute tweak.  heh.

Fall-thru. That's haunted us forever, now.  I know one thing for sure, though.  You aren't NEAR as physics-blind as I am.  A person like you COULD actually know WHY something suddenly started working, if it ever does.  :) 

Me, I just wipe the sweat off my forehead and say "Whew, I'm sure glad THAT is behind us." and I don't ask questions about why/how.

But yeah, definitely, tell EVERYTHING that you learn.  Use Wingnut Chronicles anytime, for anything... please.  Talk away, we can use the knowledge.

Link to comment
Share on other sites

I did shamelessly steal the code from the heightmapImpostor :P

I think I'll create a very simple and basic grid of 20x20 polygons in 3Ds Max, align it, and then see if I can make some small bumps to figure out the effect.

I prefer an actual model for more precision in map making.

Link to comment
Share on other sites

Haven't tested on Node yet, but so far my 3Ds Max model is working. 20/20 segments. 400/400 size. No scaling done in Babylon.

And positioning just got a whole of a lot easier.

I believe I read that you found the impostor to be positioned in the corner of the mesh used to create the shape. I can confirm this.

body.position.x = -275.46000480651855;
body.position.z = 275.46000480651855;

275.46000480651855 being the extentSize of the boundingBox. Maybe the impostor system takes care of this itself?

Link to comment
Share on other sites

A bit more weirdness.

When creating a heightfield based on an actual heightmap, like the example above, the height is a bit off based on the boundingBox. This doesn't happen when using a model.


This example runs pretty well, and the elevations seem spot on and don't interfere with the vehicle like a model does.

When I change faces or vertices of a model, even the Slightest change in height brings the vehicle to a full stop.

Link to comment
Share on other sites


I found out that my main issue was due to my own restitution and contact settings.

I made a heightmap out of a model, and it seems to run pretty well:



But if I make the ground either > 500/500 or < 500/500 it behaves strange. :P

I'll do a Node test shortly, to see if this also works server-side.


Edit: So far, so good.

Link to comment
Share on other sites

Yeah, nice.  I switched activeCamera to camera.  That followCamera was being pretty annoying... lots of unnecessary movements.  Thrust point is a little Y-axis-low on the car... lifts the front wheels during accel (difficult to turn during accel).

When things are just right, we can get some pretty nice jumps off-of that center terrain ridge.  The crowds in the stands love it... got good applause.  :)  Joie Chitwood would have been proud.  :) 

Let's see... 10 cars, all driven by JS drivers... hmm.  A little ice, a little mud, lots of jumps and drop-outs... long BAHA-like track that the drivers TRY to follow.  Cool.  Seems like a nice system to do betting-over...  for shots of whiskey.  Yay! 

Saturday Night Racing... 7PM - under the lights... Raggar's Raceway - 2 miles east of Babylville... on Hwy 69.  Sponsored by Meshwhacker Motorsports Inc.  heh.

I am SO SO off-topic.  :)

Ok Wingnut, get out of whimsy mode and back into issues management - try to get some work done.  Thanks for the demo, research, and reports, R.  Well done!

Link to comment
Share on other sites

  • 2 weeks later...

Okay, back to the 6162 issue.  PG #61 vs. PG #62.

On 6/10/2017 at 0:28 AM, Wingnut said:

After a miserable process-of-elimination, may I present playground #61 (fast) and playground #62 (slow)

I can't let this thread die.  This issue needs "wrangling", so I will bump it.  Why is #61 fast and the #62 slow?  (Wingy watches his step:) (lines 2-6)  hmm.  Thx for any help, gang.

Link to comment
Share on other sites

  • 2 weeks later...

@Wingnut I took a look at both #61 and #62 and do not see a difference in performance on my end?  when you say slow and fast I'm thinking fps drops or a visual difference in the way the impostors react, but for all intensive purposes on my client there is no difference.

**EDIT whoa... I lied, this is weird I read the above comment about how you needed to reload fully and I was able to reproduce the error.

^_^ I'm gonna mull this over when I get a chance.

Link to comment
Share on other sites

Yep.  Visual difference... impostor speeds.  Put BABYLON.CannonJSPlugin.prototype.executeStep() into playground code... scene goes fast.  If not... it goes slow.  Weird.  Thank you for help... very kind of you.

People working on comparisons... might need to paste THIS line into renderLoop of #62.

console.log(scene.getPhysicsEngine().getPhysicsPlugin()._fixedTimeStep, scene.getPhysicsEngine().getPhysicsPlugin()._useDeltaForWorldStep);

It returns 0.016666666666666666 true no matter if lines 3-5 are active in playground, or disabled.  hmm.

Link to comment
Share on other sites

weird, the plot thickens!


babylon.js:15 Uncaught TypeError: Cannot read property 'getCaps' of null at new t (babylon.js:15) at r.setVerticesData (babylon.js:12) at t._applyTo (babylon.js:14) at t.applyToMesh (babylon.js:14) at Function.t.CreateBox (babylon.js:24) at Function.r.CreateBox (babylon.js:12) at spawnBox (eval at compileAndRun (index.js:350), <anonymous>:29:32) at eval (eval at compileAndRun (index.js:350), <anonymous>:37:28)

I redid the structure to make it a little easier to read and debug, every once and a while I get this error above which is odd because it seems to work even with it.

BUT anyways back to the original problem...

Why don't we add a bool to the constructor of the so like : new BABYLON.CannonJSPlugin(true, 100, true); that triggers the 

BABYLON.CannonJSPlugin.prototype.executeStep = function (delta, impostors) {
 this.world.step(this._fixedTimeStep, this._useDeltaForWorldStep ? delta * 1000 : 0, 3);

statement automatically if the user wants it.

so the new constructor would have one more argument which we could default to true for now until this is fixed, could be a band-aid for now.

This is really kinda crazy.

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...