The Wingnut Chronicles


Not at all, aFalcon, you have never offended me, not even a little. And you speak just fine, and thanks for the kind words about TWC. Very nice of you!

The problem is… I’m not very smart. Almost everyone around here… knows more about 3d, math, and JS… than I do. And when I do learn something, I forget it quite often/quickly.

But, I have a darned good time… hanging-out with you pro developers. It’s a very enjoyable part of my life, and ya’ll are high-valued acquaintances. You guys all amaze me, and I’m honored to be included in the community.

The direction (angle) thing you brought-up… in an earlier post… sort of blew my mind. Immediately I got axes and direction vectors all confused and blurry. :smiley:

Jerome’s rollercoaster is really not a good place to study severe direction changes, because he built that rollercoaster out of “pieces” of various formulas… paths mixed with beziers mixed with who knows what else. His path is much more complicated than the one we are playing-with, here.

Thanks for all the input about paths and banking that you just gave us. Excellent. We need all the input we can get. We want to make Path3d as versatile as possible, and learn when and where to use it.

I really like our rotationFromAxis() function. It allows us full control of the car… IF we learn to bend the normals EXACTLY how we want them bent. :slight_smile: That allows us to have a “dumb vehicle”… where the car isn’t needing to do much calculating as it travels. When we get many train-cars or MeshWriter fonts traveling the path… dumb-cars will have better performance and unlimited-cars-scale-ability.

And yes, I, too, ran into “the difference” between a flat path, and a rolling-hills path. At first, I saw no hope, but then I found other people’s tests… and got excited! I am real impressed and happy with what we have done here, so far. I would prefer NOT to use physics… but instead… grow a path3d that has variable banking built-in… BECAUSE of the way we built the path3D.

I’m WAY BEHIND on the learning curve3d, but… again, I’m having one helluva good time, playing with tech that I really love, which has great self-satisfaction and self-gratification. A guy couldn’t ask for more. It’s the best hobby in the world.


Lol, you respond faster than I can edit out grammar mistakes. :grin:

Cool! rotationFromAxis() :squirrel:

Same… and will help. :slight_smile:


Yeah, RotationFromAxis() has “the formula” that we have been examining… PG #71 line 140. We have been playing with the ORDER of its three params.

Notice the white normals are bisecting the rider’s head.

Change line 140 to RotationFromAxis(normals[i], binormals[i], tangents[i]); …and now the green binormals are hitting our rider in the head.

Three params… exactly what it takes to define an axis. hmm. :slight_smile:


he is a terminator


INTERESTING: two types of “BANK PHYSICS” - for a roll around a corner.

1 for car and 2 for surfer.

  1. the physics of the car (around a turn) - rolls outward rotation (+ offset)

  2. the physics of the surfer (around a turn) - rolls inward rotation (- offset)

Will soon experiment with ways to apply with RotationFromAxis.

Sorry for tangent.


Nuh-uh. :slight_smile: Both have the same forces. Tilted surfboard turn == tilted speedway turn.

If ya think about it too long, ya run the risk of second-guessing yourself. :slight_smile: Easy to do.

Anyone know what the heck @nasimiasl is talking about? Who is he talking-to, about what? Did a joke pass over-my-head? :slight_smile:


he is talking about you i think.

Because you always reply/get the playground out faster than anybody else.

You are like a robit.

Dare i say…

A terminator


you are right, wasn’t talking about force. Just surprised roll direction can be different direction for different objects, and thought it worth sharing. Since my task is opposite(as usual). I see you ran into something similar before. Yes like a motorcycle is different than car!(below). I’ll try both: roll-in and roll-out. But I’ll study up on binormals and RotationFromAxis() first. Thx.


Well, you were talking about roll-rotation… based on physics.

Yeah, you can manually-roll any object, any way you wish. But… given a flat turn to the right, the surfer will try to go straight… possibly leaving the surfboard to the left during the turn (inertia/momentum). He/She will tumble ass-over-tea-kettle… +z. (or fly thru the air with possibly NO significant rotation)

The car does the same, or the driver of the car. The car will roll +z, or the driver will be ejected out-of the driver’s side window (left - for USA cars).

In a clockwise centrifuge, any object will try to tumble +z and try to exit to the outside. :slight_smile: No chance of tumbling -z and moving toward the center.

Motorcycles (and surfers) lean in the direction of the turn… to prevent tumble toward “the outside”. :slight_smile:

Am I wrong? Physics-wise, the vehicle-type does not matter for natural roll direction (if the pivot-point == center of gravity/mass). At least I THINK that is true. I could be wrong. Party on.


Hi again. :slight_smile: Really, we just need to study the _compute function. I don’t know how closely you have been following-along. In PG’s #69/#71, @JohnK created a modified _compute() in lines 2-39… that fixes the mis-aligned normals that happened at the path start-end intersection. That func still has one problem… it ignores the optional “firstNormal” parameter in a Path3D constructor. I’m hoping our little team can find that issue and recover it.

The #71 playground car - its roll rotation is essentially dictated/ordered… by the white normals (no joystick or keyboard allowed… all robot-controlled).

Sooooo… hmm… for THIS application (robot-grown path3d’s), we might be able to adjust the compute() function… to add some tilt to its normals… based upon the X/Z relationship of CURRENT pathpoint (cpp)… to NEXT pathpoint (npp). In effect, we want to measure the X and Z difference between cpp and npp, and use that factor in normals computations. Previous path-point (ppp) might get involved, too.

There is NO axis at the path-point when _compute() runs. IT… derives/calcs the axis of cpp. At that point (ar ar)… it has the ability to attempt realistic, but still robot-created and “fixed-value”… banking (simulated).

For a 500-pt path like pg #71, lines 27-38 of _compute() runs 500 times before the scene’s first render… creating an axis for each point.

If your interests are with player-controlled banking, then robot-faked banking is not going to be very interesting for you. Really, hacking on _compute() is the main target for this project, right now.

Want a synopsis? I knew ya did. :slight_smile:

Line 5: Probably a lie. I think the code following it ONLY deals with FIRST tangent, and not last. But, first/last values COULD be identical. Unlikely, though, unless the first/last points are over-layed, position-wise. (2 points in one place)

Lines 10-20: This section is all “init” code… trying to prepare the FIRST point/normal/axis. This is likely the area where optional firstNormal parameter is being over-ridden or somehow ignored.

Lines 21-33: Uber-hot! Lines 29/32/33… that’s where we would add simu-banking… to influence the normals into tilting… in a banking-like way (with adjustable intensity and likely a reverseBanking boolean option, too).

In #71 PG, change line 97 Path3d constructor to:
var path3d = new BABYLON.Path3D(points, BABYLON.Vector3.Down());

No change in scene seen. BABYLON.Vector3.Down() (and 5 similar statics ie. Left()) is being ignored/over-ridden. Likely an issue in line 12, a line modified by @JohnK. John also modified lines 33/34, I think. HOPEFULLY, those lines are ok, and we can modify line 12 area… without re-introducing the start-end problem.

These grown paths we do here… are fire-and-forget. They are grown in a certain way, and dynamic on-the-fly (ar ar) adjusting of the path/normals… is likely implausible, as it will require growing a new 500-pt path.

As for BInormals, they are created in lines 34-37. They are simply derived from the Cross of the normal, but they are highly important because they provide one “radial” (yaw) of the 3 needed for our rotationFromAxis() “motor”.

curTang is probably the direction of the path, similar-to or identical-to… car.rotation Forward() / Back(). Wiki - tangent.

Ok, now you know MY “train” of thought on this project. I’m an exciting storyteller, eh? :smiley: (snore)

White normals, brown abnormals, emBANKments… there’s a distasteful border-wall joke around here SOMEWHERE. heh


afalcon lookin…

binormal is a cross of the normal, got it. Looking at Epsilon… 0.001. Source code gr8!

After following the experiment through - the modification of the compute function is remarkable.

Many things learned above. See you mentioned a boolean switch on banking direction.

Excited to attempt non-math implementation of curve this week - and understanding normals better is big help.

You are correct - the robot curves are not applicable to implementation, it is a custom curve. Apparently, all the normals will be UP. So a curve in xz plane.

Any way to EDIT normals on a curve? (set them all to UP?)
We have the curve and yep - normals all over!
I suppose it is in the normal array?
Sounds fun. Cant wait.
I’ll shareback whatever …


Ok, just about to start pulling levers and twisting knobs…

NOTE: here was the non-math LookAt solution (on a flat plane: y stubbed at 0):

      /*----------------Animation Loop---------------------------*/
        var i=0;
        var lastPathPoint = {};
        var pathTargetSphere =  BABYLON.MeshBuilder.CreateSphere('', { diameter: 1.5 }, nx.scene);
        pathTargetSphere.position.y = 0;

        nx.scene.registerBeforeRender(function() {

                    lastPathPoint = pathTargetSphere.position;
                    character.position.x = lastPathPoint.x;
                    character.position.z = lastPathPoint.z;   

               pathTargetSphere.position.x = points[i].x;
               pathTargetSphere.position.z = points[i].z;   
               character.lookAt(pathTargetSphere.position)  // <-- proof of concept.
             // theta = Math.acos(BABYLON.Vector3.Dot(normals[i],normals[i+1]));
             // var dir = BABYLON.Vector3.Cross(normals[i],normals[i+1]).y;
             // var dir = dir/Math.abs(dir);
             // character.rotate(BABYLON.Axis.Y, (dir * theta), BABYLON.Space.WORLD);
             // character.rotate(BABYLON.Axis.Y, dir, BABYLON.Space.WORLD);
             // character.rotate(BABYLON.Axis.Y, theta, BABYLON.Space.WORLD);

                i = (i + 1) % (n-1); //path point picker restarts at 0 along path.

     /*----------------End Animation Loop---------------------------*/ 

It was a solution to the rounding error mentioned in the docs, for the car after a long period of time.

It was also used later for enemy movements (with JK’s help) around an infinity path.

I’ll try a few things …

  1. all curve normals up.

  2. control of speed - on a path with fewer points? (or not) (interpolate from point to point?)

  3. banking … (offset on curve?)

  4. condensing the 3 arrays into 1 array of objects with meta data for each point (and reducing points).

Anything can happen!


Hiya bird! :slight_smile:

  1. For MY use, they must be “up”… ROLL-WISE-ONLY. A “pure up” will kill the pitch of the car for non-flat paths.

  2. Could be done. Starting to lean-towards Jerome’s rollercoaster. Interpolation is actually frame-points between the path-points, which is adding more points… so you are possibly self-defeating, and you will also have a difficult time maintaining consistent path-speed, if that is sought. I need to study animations around bezier curves… to speak intelligently about that. Are keyframe-points more compressed (closer together) around tight turns, as compared to straighter-stretches? hmm. Do animation speeds around corners… slow-down because of that?

  3. Not really an offset on “curve”, at least not the curve array. Curve array is positions, and we don’t want those to change (unless we plot a new path3d). We only want to roll the rotation of the car. There MAY BE certain applications where the car would positionally “side-slide” away-from the path track, or maybe jump above the path-track, but I have no need for that, yet. :slight_smile: My goal is trains and roller-coasters, so far. Many cars, consistently spaced, no matter the speed of the first car. Think sentences… where the distance between letters is adjustable, and so is the gap between words. Once the sentence-train is traveling the path, the letter and word spacing must remain consistent/locked.

  4. Yeah, that is similar to the “smart-path” idea of long-ago… where each point contains information about what the car should do AT THAT POINT. (in a way, that’s what we are already doing.) Your idea would still require “growing” all the metaData in every point, and/or robot doing the animation interpolations. But yep, certainly a possibility. I still have much work to do on this more-standard method… before I wander-off into “intelligent paths/points”. Research at-will, of course. (thx!)

Your #1 would help my cause… the most. Normals that are all UP roll-wise, is definitely something that I need to do with _compute() before any tilted-normals banking experiments can start. But the UP normals cannot be UP… PITCH-wise, or else the car will not aim up/down hills. Thanks for any help/contributions on that.

I would REALLY like to get the Path3d 2nd parameter firstNormal working correctly FIRST, as that will affect SO MANY other things. Party on!


You are right.

Converting path points to interpolations would change speed if points are not evenly spaced.

It is a good problem. I see our contexts differ.

I have a Bizarre World design-requirement which is nice, because if result does not match reality… that is ok - as long as it looks cool!

Strict earthly physics not a design limitation, device performance is.
So, if speed increases around corners - it might look cool. (or not). Need to see it to know.
As you know.

CONCEPT: POINT-TO-POINT POSITION INTERPOLATION in BJS syntax would be really cool to see. Surely there are good examples.

Bizarro uses jquery.animate( { x, y, z} ); Remains major difference. Then apply position on frame. Making each length governed by TIME not distance. Attempting fewer points - flipping them into an interpolation engine, as metadata. Hope to shareback. We try different things.

Bird admires babylon.animate, p2p (point to point) animation, because syntax boggles brain. So it is a big difference in context.

Another GOAL: is smooth camera animations, with exact position precision and speed.
POINT: we need a buttery-smooth boomCam? :grin:
So that is why.

Perhaps path points can achieve that goal. Love: ppp, cpp, and npp (btw :black_heart:).
Sometimes “Principle of BOTH”. Considering both. Revisiting “smart-path” as “SmartPath”. And adds a different sauce. Didn’t know, smart-path was already a thing?!? Cool! We will see what happens.

Cool - “roll-wise UP and pitch-wise UP are different!”
Bizarro: we separated pitch out with a puppet mechanism (pitchRig) to solving with LookAt.
DESCRIPTION: two rays. 1) downRay 2) forwardRay Then TRICK: offset target UP 4) LookAt target.
Original TEST was BOAT SOLUTION, image above added the vertical offset. Which might help you. Honored to share on request.

Train car down ray might help you. And maybe LookAt connectors? Or Bones?

Disclaimer, story script calls for a bizarro train in future episodes. If we ever get there, please dont be surprised, we work from a previously written script. SIMILARITIES ARE COINCIDENTAL. Considering train cars. WE PROBABLY AVOID TRAIN CARS LIKE ROLLER-COASTER. For you - MAYBE USE BONES in BLENDER, then import? Like the BODY OF A SNAKE! Blender might be good for train.

Probably your context is different, but happy to share concepts if they help you. Even while bizarro and different: PitchRig: using 2 Ray offset LookAt, RollRig: using SmartPath, Train connections using Bones.

Another FOCUS: is performance. Probably wrong, worth a test.

  • is more points slower than few points?
  • can we interpolate evenly across multiple point sets?
  • can SmartPath metaobject seed things like “weight” and “roll”?
  • is that all faster, lighter, smoother?
  • OR are there SURPRISES (undoubtedly)?

Attempting “SmartPaths” to shareback for: review, alteration, and improvement (here).

  1. point position as metadata number, on object set - which runs through animation engine.
  2. attaching camera.parent as “BoomCam1”. With the ability to control cameras precisely.
  3. then “SmartCam1” - with “camZones” with “zoneAlarms”. Fun!

Yes, Bizarro solutions, but happy to shareback to help . Or to be improved - is better! If not, trying different things. :slight_smile:

Path3D second parameter seems like a good addition. : )

UPDATE: done editing!


Haha… yep, ub bizarro, for sure. Fun thinkings, though… I was “with you” for the whole read. Fun!

Keep in mind… that lookAt sucks for trains. 100-car train, all following a SINGLE roll-only lookAt target… causes all train cars to do that same lookAt/banking. Not right. In true train-land… the front of the train may be well into the banked corner, while the back of the train… still on the flat-lands… not yet arrived at the turn.

Yes, it would take 100 separate lookAt targets moving up/down an invisible pole in the middle of the circular path… each with their own private altitude. Gruesome. I must stay on current target… growing fake-banking into the compute(). All other dreaming allowed and encouraged, of course.

In parts of your post… you like to say “slower” and “faster”… but you don’t specify which phase… growing the path, or driving many mesh along-it. :slight_smile: We probably don’t care how long it takes to grow a path.

Motoring a MeshWriter-fonts (3d fonts) train-of-text… displaying the latest CNN headlines… speed/perf might be important, there. :slight_smile: Drive-perf, not grow-perf. :slight_smile:

Bones. hehe. Using bones to actually DRAG the cars behind the locomotive, and using bone-length for spaces between words and characters on the text-train. Good idea… maybe. The train is one long “spine”. heh. I kind-of like that idea.

Bone-binding to the lookAt target? Ok for single vehicle. Fun!

Ever ponder… that we could fly an object around in-space… smoothly… using precisely-positioned and often-overlapping “gravity wells”? You know… precisely-positioned/aimed vacuum cleaner hoses in space… sucking a mesh around. heh.

Hey, if the railroads can move from path to path, so can we (I fig). :slight_smile:


Yep, favor bones on second thought - for 100 train cars.

Wow - super tough physics - since all behave differently on ROLL and PITCH but same on SPEED.

What is the most performant way? Fun puzzle you make. : )

Current target - makes sense… I’ll explore Bizarro… no worries. :slight_smile:

CORRECTION: interpolation from path to path would need to interpolate at same rate to any distant ppp. Not TIME. So, internal governor on actual movement amounts. Will work that in.



WARNING: this may help or distract (ignore if it distracts) - also is uses jQuery interpolate non-math so BIZARRO.

        var i=0;
        var cpp = {};
        var npp = {};
        var animatePath = false;
        var advancePoint = true;
        var pathTargetSphere =  BABYLON.MeshBuilder.CreateSphere('', { diameter: 1.5 }, nx.scene);
        nx.scene.registerBeforeRender(function() {
          if(!car|| !car.position){return}
          if(advancePoint){  //trigger next path point
            cpp = pathPoints[i];
            car.position.x = cpp.x;
            car.position.z = cpp.z;
            car.position.y =0;
            i = (i + 1) % (n); //next path point picker restarts at 0 along path.
            npp = pathPoints[i];
            pathTargetSphere.position = npp;
            advancePoint = false;
            animatePath = true;
          } else if (animatePath) { //INTERPOLATE-MOVEMENT-FROM POINT-TO-POINT-.
            animatePath = false; //one time trigger;
            $({cppx:cpp.x,cppz:cpp.z}).animate({cppx:npp.x,cppz:npp.z}, {duration:5000,
              step: function(now) {
                car.position.x = this.cppx;
                car.position.z = this.cppz;
              }, complete:function(){ advancePoint = true; } 

DESCRIPTION: separates SPEED of car from number of POINTS on path. So path points can be anything, and speed can vary.

PERFORMANCE: not a noticeable difference

PROBLEM: Governed by TIME is a SPEED problem for different DISTANCES, solved by adding magnitude to SmartPath. Also easing. Still y = 0;

SMARTPATH (pathMeta):

        var obj = {};
        var pathMeta = [];
        var pathPoints = [];
        for (var i = 0; i < n + 1; i++) {
          var pos = new BABYLON.Vector3((r + (r/5)*Math.sin(8*i*Math.PI/n))* Math.sin(2*i*Math.PI/n), 0, (r + (r/10)*Math.sin(6*i*Math.PI/n)) * Math.cos(2*i*Math.PI/n)) 
          obj = {pos:pos,weight:0,rollDirection:0,magnitude:0};

DESCRIPTION: allows metadata to be placed on PATH to affect RUNTIME.

CONFIRMED: Found a tiny (off by 1) BUG… (contributed to the glitch!!!)
i = (i + 1) % (n-1); //skips the last path point
i = (i + 1) % (n); //includes the last path point

I see it was found and fixed in the solution…


No playgrounds? Bizarro.


Lol. yeah.

Sometimes I wonder if the bizarro version of earth wouldn’t be less discouraging.

Since it is supposed to be opposite, and society seems to trend closer to disapex, than enapex.

You want a playground of the BOAT-Pitch-Rig?

Would be willing to refactor that out… if it helps.

Otherwise, I have issues with PGs (they break)


Simple box… fine with me. The simpler PG, the better. PG’s are such good teaching/collaboration aids, that I can easily overlook disliked things. I like to offer everyone… easy participation and thorough explanations.

But that’s just me… Chief Lamer of the Lamer Support Foundation. :slight_smile: And let’s not forget about the kids. There’s 8 year olds nearby… learning… future superstars of BJS.