The Wingnut Chronicles


You PG does not work, because it is not a real PG. Just a dump of your code :slight_smile:

For instance canvas01 does not exist. Same for math.seedrandom…

And you just need to create a createScene function in PG. No need for the renderLoop (the PG takes care of it)


The problem with playgrounds is that they break.

Here is PROOF OF CONCEPT of POINT to POINT interpolation:

  • separates CAR speed from number of PATH POINTS
  • uses jQuery syntax:
$({cppx:cpp.x,cppz:cpp.z}).animate({cppx:npp.x,cppz:npp.z}, {duration:5000,
            step: function(now) {
              carBody.position.x = this.cppx;
              carBody.position.z = this.cppz;
            }, complete:function(){ advancePoint = true; } 
  • awesome that jquery is in Playground (…)
  • love that syntax. business requirement. wish it was in bjs.
  • could fix slerp turns Babylon.js Playground
  • could still ray sense pitch from ground (below)


Here is BOAT PITCH-RIG senses waves and adjustes pitch: (cleaned code/ anm vOffset)


DESCRIPTION: uses 2 raycasts 1) downRay and 2) forwardRay to determine pitch with a vertical offset lookAt. Also ROLL determined by user command. wasd.

It used to have jump(space) and movement fwd (w) , but both broke in translation. Not sure why.

A better EXAMPLE of the random PG issues.
Cleaned them out (partially) because I dont know where to begin to fix regression.

My best guess is moveWithCollision changed?



Dr. Kosh, TLDR;

Animators need playgrounds that never regress. :grin:

WORKFLOW: > Need local frozen version for months of animation compilation. > Cant animate forward if fixing backward. > Last years experiments (possibly) incompatible with Progressive PG. > Frozen PGs by version (someday) awesome! This is why ~ issues with PGs. Sorry.



:bird: <still-probably=user-error> :sunglasses:


They do not as long as you use standard features (nothing starting with _)

I spend a LOT of energy to keep everything backward compatible (And unfortunately sometimes I fail) so PG should work


Understand. Thanks. Sorry. :grin:

If ever possible, Freeze PGs aok by me.


Regarding freezing pg bjs version, would it not be relatively easy to add, just by relying on something like jsdelivr, where you can explicitly set a version from github tags or commit.

I for example use:
DebugLayer.InspectorURL =
so that the inspector doesn’t break when using a slightly older version of babylonjs (which seems to happen relatively frequently).

You can in fact load an old version yourself in the pg (albeit somewhat clumsily):


Good info, guys!

Nothing new in #75 except… I brought-in _compute()'s partner… _normalVector(). So now we have (almost) ALL the portions of the “normals growing system”… in the playground… ready for easy demented experimenting. :slight_smile:

For those who are lost/new, the _compute and _normalVector funcs at the top of this playground… have been “borrowed” from the BJS core Path3d system. By pasting them at the top of a playground as we have done, we tell the scene to use OUR functions (for forming our Path3d), and NOT the default/core functions. Easy experimenting… without accidentally breaking anything important in BJS core-code. Onward we go…

Also note that my Path3d has a v3.Down() as its optional firstNormal parameter… in line 139. Adjust or remove, as wanted, of course. Change to Forward() or Backward() to see that it IS being honored… just… not well-honored/used, yet. Most important for me/us, are likely Up(), Down(), Left(), Right().

Other than that, no mods. I’m using @JohnK’s modified _compute(), and an un-modified _normalVector(). One of John’s mods… involves line 34 of _compute(). The ORIGINAL line 34… only sent TWO params to _normalVector(). I think John added the optional 3rd parameter.

I see a few “twitches” out there, during the animation. There are a few bad welds and bent radials. Not sure why, yet. I’m getting ready to start some power-hacking. Lines 186-188 MIGHT be causing one of the twitch-spots.

Bringing _normalVector() function into the playground… MIGHT have changed the Path3d. Perhaps do some experiments with disabling it, or comparing PG#75 path to PG#71 path. Not sure WHY hijacking-in _normalVector() would matter, unless I borrowed it from the wrong BJS version or something.

Current objective: Fix bad welds and bent radials. Seek all normals being DOWN, roll-wise-only (z). (Because I set v3.Down() as firstNormal). Car should not roll/bank left or right (yet)… but CAN/MUST “pitch” (x) up/down hills (like it does currently). Party on!


hello, _normalVector()

cool overrides... Following the Cross's through... > Need to read up on !WithinEpisilon, and CrossToRef
Nice! Changed parameters! (no tangents?) Of course, tangents ('I'll stop). :sunglasses: > projection?.
Up(), Down(), Left(), Right() +1.:RED_heart:
It is pitching!?! Very cool. :star2:
Hello, DownVector! There it is... where'd it go? Didn't find the pitching. :grin:. > Need to Read up on: 3DPath(params).
And emoticons broken? It's only me. :gr8:
Apparently comparing [Rollercoasters Now!] ( > Need to read up on Refs: addToRef, subtractToRef, scaleToRef... Note to self.
Cool experiment...:slight-smile:


Perhaps read-up on making BBCode links, too. :smiley: Possibly a “Proofreading your post” night class? hehe. Sorry.

Btw, it was just a post. I hope I didn’t imply that anything needed to be studied or burned-into memory.

Yep, car currently pitches fine. I haven’t studied the diff between 2-param and 3-param _normalVector() calls, yet. In fact, I haven’t done anything at all.

Oh wait, I turned-on viewing of tangents (blue) and Wingy-created arctangents (red).

Other than being darned pretty, and perhaps showing a few more “oddities”, it doesn’t accomplish anything. :slight_smile: I should probably reduce the points a bit… maybe see something new. Tangents are definitely the path DIRECTION at each path-point, though. Same as car.rotation.Forward(), I suppose.

Most interesting things: Line 173 show-tangents needs a 30-length show-line. Line 179 show-arctangents needs a 1-length show-line. Weird.

I might be building the arctangents wrongly… in line 177… killing their magnitudes or something.


More roller-coaster fun. Well not so much a roller-coaster at the moment just a track with roll. I wanted to examine just the roll effect of going round a curve, so as yet no height changes.

As usual I like to start simply. We are building a railway consisting of a single line of rails. Each rail has a fixed length and all rails are the same height above the ground. A car moves along the rail balanced along a central fixing. For a straight railway people in the car remain vertical. For a curve made of the rails the people in the car lean towards the center of the curve.

Building a closed loop with the rails will produce a regular polygon. The more rails the larger the radius of the circle around it and the smaller the angles between the rails.

The larger the radius the less the curvature of the circle and the less the people will lean. Curvature is in fact 1/radius. At any position along the railway we will need to know its curvature to determine the amount of lean needed at that point.

My first attempts still produce wild variations in normals and binormals

So current attempts smooth these out.


The baseCompute function takes the generated points, an angle, and a damping factor.
The tangents and curvature at all points are calculated. The cross products of successive tangents are used to determine if the curve is inwards or outwards. When there is little difference in the x or z components of successive tangents they are in a straight line so curvature is zero. The amount of lean, theta, is calculated from the curvature found * angle * damping.
The larger the angle used the more the lean, the larger the damping the less the lean.

Angles and tangents are stored.

The angles are then smoothed using a moving average in the function smooth. This takes two parameters the array to be smoothed and the width of the smoothing w, which is how far either side of the current value to take averages from. With w = 2, the value at index 6, for example, with become the average of the values at indices, 4, 5, 6, 7, and 8. That is the larger the w the smoother the angles. Of course too large wipes out essential differences.

Once the angles have been smoothed the rollCompute calculates the normals which give the amount the car will lean away from the vertical and then the binormal using the cross product of thee tangent and normal.

Also I found the more points used the wilder the normals at the turns of the curve. So used less points and set the speed using a weight, the greater the weight the slower the car.

You can see that a large number of points with a very large width for the smooth function does not give a smooth ride I am guessing it is something to do with the handling of very small numbers.

Plenty of parameters to play with.


An attempt at adding heights


Excellent work, JK!

:slight_smile: It didn’t stay there long. heh.

I found some more path code… I haven’t examined it at all… just noticed it was different.

Fun stuff, John. I was thinking about “spherical coordinates” and starting with a circle/ring, as you have been thinking. But when a guy starts warping that ring, the distance-between-points has to adjust SOMEHOW… and that’s where stuff gets ugly. I can’t quite wrap my brain around… well… anything.

One part of me says keep the points equi-distance, and another says “tighten them up” on the corners. When points are spaced inconsistently, what do we do with travel speed? sigh.

I think we NEED to allow user-controlled throttle… somehow… somewhere… someday. But… should speed affect banking-amount? Optional? With pre-calculated banking… that would be difficult to do. But with on-the-fly banking calculations done by the car itself and its current speed (real-time)… maybe can-do.

Has anyone tested if a gyroscope works in a physics engine? Anyone know? (sorry, mental wander)

Spherical coordinates. There’s some borrowed code in there… that plots points on the sphere… at some distance from center. Concentricity? Opposite of Eccentricity, right?

NOOOOOO,Wingy. :smiley:

In a later version, someone made it into a Valentine’s Day heart. :slight_smile:

I’m REALLY focused on the issue, eh? (not) I don’t have ANY worthwhile comments/contributions.

John, I think you have created a banking proof-of-concept, at least. Thanks! Fun to watch!


Impressive code John.

Wingnut, cool links. Angular momentum is interesting.

I wonder… Gyroscope - Web APIs | MDN

Thanks for confirming that tangents are on the points.


On the never-ending (circular) path3d subject, here’s another.

This one is quite different. Only 50 points define this retarded path (which is grown in lines 186-196).

RotationFromAxis is disabled, along with ALL the registerBeforeRender area (all old-style car-moving things - disabled)

ALL movement for THIS non-coasting coaster… is done within the onReadyObserver code in lines 282-310. PURE BJS animation. YAY! Positions-animation ONLY, so far. Yaw/Pitch rotation animation might only be tangents away from us.

For this positions animation, I just force the points array into being the keyFrames array. Easy. A little note: points array == path3d._path == path3d._curve.

It’s pretty smooth for being a mere 50 points. The BJS Animation-system interpolator is likely inserting steps between each of our 50 points. I wonder if we can query the Animation’s interpolation… to see how many “steps” it has. I bet it is more than 50. :slight_smile:

I like it. CarBody changed to cone… so it is easier to see if/when the carBody has correct yaw/pitch. (it currently doesn’t)

BJS animation system is doing a good job at positioning our car along the path3d points-path, and we are driver-heads-up (yay!).

Now, we just need pitch and yaw animation. Roll comes later.

NOTE: This PG is using an in-playground DEFAULT _compute() because John’s custom _compute removed path3d.distances. The distances array is mostly unused, but I wanted to see what it looked-like… at console. It is essentially… mile-posts/km-posts… might be useful someday.

Update: PG #84 has both “posdrive” and “rotdrive” animations active. Rotdrive and rotkeyFrames are being derived from tangents… and is not looking healthy. But hey, its only our first step, and we have not yet learned how to avoid ROLL that is on the tangents. We might need yet another animation… floats instead-of vector 3. One for yaw, one for pitch, and none for roll. Three animations total… yaw(float), pitch(float), and position(v3).

Disable line 320 to see that I have set/baked initial cone rotation… so that it aims left-ward with Y-axis up-ward (done in lines 174-176). All that MIGHT need to be removed.


First 3-animation version. Float animations on yaw and pitch, vector3 animation for position. Default _compute still having problems with aligning normals at start/end. Lines 299 & 305 areas… super critical (what values to use for yaw and pitch anims). Still using Down() as firstNormal. Lots of work in lines 177-179… trying to init NEW-STYLE-car’s rotation. Entire scene needs lots of work/thinking, yet.

Time to bring-in the MeshWriter fonts? :slight_smile: (might need extra “RUN” click)

Yikes. Really, I need line 285 to work… animate the “B”. But, it looks like SPS particles are not really ready to be animated. Soooo, I animate the entire meshWriter “master mesh” in line 288, after some prep.

Goofy! It’s just a goofy kind of path-whackin’ day! :slight_smile: Path-Whackers. hehe.