Stop Sliding down Slopes (SSS)

If it is over yours than it is definitely over mine!:wink: I try to modify it to suit my needs. Thanks for the help!


After looking at your post(again) you suggested I use another physics engine. For some reason, the camera (apparently) has it’s own, So you can’t. I’m not the best at explaining this, but here is a previous post of mine and it might help explain it better:

Thanks for the idea, though.


I’m starting to think that freecams need a surfaceTiltDetector system. It constantly updates the direction and magnitude of tilt of the surface beneath the collider/ellipsoid. (FOUR never-pitch-changing picking-rays… aimed-down and parented to camera… one front, one back, one left, one right?) Dunno. Heavy stuff. Sort of like a tilt detector using a gob of Mercury in a bowl that is lined-with electrical contacts. :slight_smile:

This would give us a value to work-with… and we can toggle camera.applyGravity based-upon the tiltDirection magnitude (how steep of a tilt). NOT camera tilt/pitch, though. Only the tilt of the surface below the ellipsoid… and only if activated (it’s optional).

hmm. Old forum search for ‘sliding’ returns many hits. One thread that was titled nicely/apropos… ended with a question. Uh oh. :slight_smile:

We need some physics “ice” fun, right now… I feel. :slight_smile: Hit any key.

Okay, I think we might be using the same words to mean different things. :upside_down_face: In @Wingnut’s answer on the thread you linked to, he has a few Playgrounds which show examples of something pretty close to what I’m describing – a physics object that owns the camera, not the other way around – functioning. In the case of one, there’s a box that flies around with the camera and allows it to knock aside other boxes.

What I’m describing is similar to that, but just a little different: instead of having the player controlling the camera and having a physics box follow it around, I’m describing having the player control a physics box (or ellipsoid) and having the camera follow that around (or, more accurately, be parented under it). In short, you may want to consider moving away from the camera’s built-in control systems altogether and switching to a physics-centric approach from the top.

Bear in mind, this would be a pretty fundamental change and would require quite a bit of work (you’d need to implement your own mouse and keyboard control scheme since you’d no longer be using the built-in ones), so it’s probably not worth tackling unless you really are going to need a physics system. On the other hand, attacking it from that direction would give you more direct influence over the controls and would unlock the full potential of the physics system, which otherwise might be a little tricky to reconcile with the camera’s built-in behaviors. Again, though, it would be a fairly heavy-weight change of approach, so it may not be worth it. :smile:

1 Like

Moving away from the built in physicswould be a chore, but parenting the camera to a physics object might give me a solution.

Ok Wingnut, who can add stuff to Babylon.js. after seeing @syntheticmagus’s unity screenshot in one of his posts, I was like, “we need to have that in Babylon.js.” I agree that this engine needs something like that but I don’t know who could make it happen.


1 Like

YOU could make it happen. You’re a BabylonJS pro these days… climbing the learning curve with a jet-powered bulldozer. :slight_smile: Doin’ good!

Early tests. I know as much about Rays… as I do about making Dingleberry Pie. But I can borrow one of the demos from the docs… and make a mess of it. I’m good-at making messes! :slight_smile: Don’t ask me what those “I68” and “I54” numbers in the docs… are all about.

But, I heard a rumor that rays are SLOW… if used wrong, and that they have the ability to measure distance to the SURFACE of another mesh (as opposed to the distance to the ORIGIN of another mesh).

So, I built 4 lazerRays hovering over a ground plane. I am shooting beams downward from all 4, with an extra beam shooting diagonally for some unknown reason.

In lines 82-96 (the render loop)… I am firing the lazers at a fairly slow rate. Pitchew, pitchew, ubitchu… and watching console for changes in “distance”. In lines 94/95, I am slowly tilting the ground. But I see few/no changes in distance at the console. It seems to love being 2.5.

Its a hat… for players to wear… to help them stay level-headed. ar ar ar!

Once we get this working, Givo… we will likely NOT parent this to the camera. Instead, we will need to keep the 4 parented-to-a-gizmo lazerRays… VERY level… yet hovering above camera. It would be something in the render loop like… quadLazer.position = camera.position.clone().add(new BABYLON.Vector3(0, 2, 0)) … always keeping it 2 units above camera. (the clone() section might not be needed). QuadLazer can be invisible and so can its beams.

Help welcome from all, of course. There’s some ray gods (god rays?) around here. Let’s hope they come out of the closet and help us find a pot of gold (golden pot?). :slight_smile:

Those lazers might do the trick, and I’ve been thinking. Ever since @syntheticmagus said

I’ve been thinking of ways to try that idea. Over the next couple of days I’ll try it out, and see if it works.

Thanks for all of this help!


If you’d like a little “taste” of “driving a box via physics” … here: (sidebar buttons can be ‘held’… for velocity-accumulating)

Not everything is working (mostly auto-pilot problems). This uses ALL mesh.physicsImpostor.applyImpulse() thrust-methods, but I wrote it before I learned about setLinearVelocity() and setAngularVelocity() … two handy ways to translate or rotate a physics-active mesh.

When a physics box is floating in mid-air like that, there’s no friction. So we use a couple properties called angularDamping and linearDamping (they are both used in the above playground, sometimes). craft.handle.physicsImpostor.physicsBody.linearDamping = .01;

Those are the “brakes”.

Speaking of hovering in mid-air… WILL IT? Or should you let the physics box scrub/slide on the ground (ice) with camera parented atop? (a possible problem for bumpy terrain) An area of study might be camera.inputs… the thing that attaches the mouse and keyboard… to a freeCamera and others.

Decisions decisions. FreeCams don’t normally have “roll” abilities (z-rot)… but once your camera is super-glued to a physics-active box… it THEN can roll. But mostly, you’ll be yawing and pitching… airplane terms. And remember, as always, the physics ‘gizmo’ box can be made invisible, and we can turn-off the thruster ports/particle-jets, too. They are just for looks. :slight_smile:

Want to see setAngularVelocity and angularDamping… in action? I knew ya did.

Check-out lines 1740 & 1741. First, activate 1741 and run. This waits 3 secs, and then sets an angularVelocity (spin) of 1… “around” the Y axis of the box. Any value works… -12.73 or 4.538 or similar.

The DEFAULT rigidBody (physicsbody) angularDamping for CannonJS… is .01. As you can see, the rotating box DOES gently slow-down its spin. Now let’s activate line 1740 and run again. Keep line 1741 active, too.

Lots more drag/braking, eh? yep.

If you’re curious, this is the underbelly for a 3D version of a Commodore 64 game called Space Taxi (THAT craft can be flown with CONTROL-numpad and SHIFTED-numpad arrow keys - including + and - numpad keys). The craft has an invisible physics-active box between the pilot/copilot seats. Truth. craft.handle.

I may never get it done, but it sure is fun to dev. SKAP stands for “station-keeping auto-pilot” and there is one for rotation and one for translation (similar to space shuttle/ISS). When no station-keeping is active, the vehicle is in a state called “free drift”. “Home” and “Orient” are also types of auto-pilot. All SKAP are currently under heavy tests and debug (over-shoot of auto-pilot targets… because Wingnut is not a space engineer or even close) :slight_smile:

erot = Euler rotation (craft.handle.rotation).
qrot = Quaternion rotation (craft.handle.rotationQuaternion) (ALWAYS used by physics engine ‘bodies’)

Ok, now, just imagine how to control linear and angular velocities, and damping… as if you were driving a camera (but you’re really driving a box with a (universal) cam glued-atop). Fun times ahead.

I don’t think I know @syntheticmagus (Justin) very well. I don’t remember him from the old forum… but… he is one sharp BJS pilot. Not many people have the “imagineering” flexibility to dream-up a camera that is gizmo’d by a physics object. A fine typist and teacher, too. I’m glad he is hanging-out with us. He’s speaking correct and wise words… right down the line. (thx synny!)

Givo… are you ready to put this thrust-able physics box… on one of your ramps? Friction and mass are the secrets. Steep angles… friction won’t hold us. Gentle angles… we’ll stop… but there may be some skidding before stopping, depending upon mass, and upon momentum when we hit the ramp. FUN! Too much friction with too much momentum… and we will tumble head-over-heels down the ramp… but we might have a fix for THAT, too. Or, you might want to leave it in your game, because it’s so “real-life-like”. :slight_smile: Face-plant! Purina Gravel-Chow! Ground kiss. Ramp lick. heh. Need more thrust power? Lines 18 and 23 adjust those (in PG #304). You probably need value increase in line 23, for thrusting UP a ramp. :wink:

Right now I’m working on the movement, and I’m wondering if there is a way to detect velocity in a certain direction. Any way to do that?

Here is what I’ve been working on. WASD to move. Space to jump. Having the camera being parented to a physics object makes jumping easier. I have a small sphere parented to the bottom of the big one, so you can’t jump in midair. Every frame I set the sphere’s x, y, and z rotation to 0 so the sphere on the bottom doesn’t move. maybe I could have leaning be a thing. The only thing that is missing is the fact that the camera isn’t parented. (done on purpose for testing) and you can go as fast as you want.

I just need to figure out how to find the velocity of the sphere so I can reduce the impulses.

Feel free to mess up the code!


Hi G. Essentially, linearVelocity IS a direction with magnitude, I think. Besides summing to be a single direction, it also contains the amount of x-velocity, and y-velocity, and z-velocity, yes?

How to USE IT as a direction (like to aim an arrow)? I have no idea. But others are nearby to help, perhaps. I’m pretty busy in real life at the moment… but soon will have more time.

Perhaps you need a vector3 that tells direction… even when player is sitting still and there’s NO linear velocity. Perhaps you want to thrust out-of the player’s butt, no matter which way they have turned, right? And it is difficult to calculate the “butt-thrust direction” when player is all rotated weird, huh? Yep, been there. Just in-case that is true…

@deltakosh to the rescue. Look at the 304 p-box playground… lines 133-138. That’s what you need, or something real similar.

Now scroll up a few lines to 114-121 transPositiveZ function. Translate positive Z. That… is a fart (impulse) toward negative z, which would move our player positive z (local space to box).

Look at line 117.

var forcevec = this.doTransformPerFlyerQuat(new BABYLON.Vector3(0, 0, this.transforce));

transforce is a you-set power level. Main thing is… x and y values in that vec3… are 0. ONLY z has a magnitude.

When forcevec returns from doTransformPerFlyerQuat()… it is holding the correct direction for impulsing the box… localSpace z-ward. See line 129…

this.flyer.applyImpulse(forcevec, cntptloc); There’s our “adjusted” forcevec being used for an impulse. It could be used for a setLinearVelocity(), too.

cntptloc is “contact point location” as you likely know. Almost everyone just uses box.getAbsolutePosition() in that param (box center/origin/pivot-point).

If you used box.getAbsolutePosition().add(new BABYLON.Vector3(0, -1, 0)) … that would lower the contact point a bit… possibly making the box do a little “wheelie” when it was impulsed. :slight_smile:

If you study 304 carefully, you’ll see that I do TWO impulses to spin the box… from two opposing sides of the box… and both using opposite “offsets”. Up in line 18… the master “turn force” is called this.offset. It is the AMOUNT of position offset-from-center that the two impulses use (their cntptloc). It can be ANY value, even if much more magnitude than thrusted mesh size. (Contact points can be positioned WAY OUT in space, a LONG ways from box center). Big “leverage” for teeter-totter fulcrum-fun. :slight_smile:

Besides offset amounts, you can, of course, increase/decrease the magnitude of the forcevec. It might be wise to learn how to scale a vector3, because scaling your forcevec is the same as a power setting. Scale greater than factor 1, and power increases. Scale less than factor 1, and power reduces. Scaling NEVER likes negative numbers and unpredictable results could occur.
(a little diagram of dual-impulse rotation)

The setAngularVelocity() func eliminates the need for dual impulsing to rotate. I need to update my flyer.

Ok that’s plenty for this one.

Good luck! Things are looking good.

I finally got the “quadLazers” working. See console… to see the distance samplings.

By constantly positioning (never rotating) this device… above a gravity-active freeCamera… we SHOULD be able to constantly know… what mesh-angle… our freeCam ellipsoid is always sitting-upon.

If you remember my previous post, I was getting unchanging 2.5 distance ALL THE TIME, from all 4 rayzer beams.

Well dummy me… I forgot to set the red BOXES for the rayzers… isPickable = false. The rayzers were measuring the distance to the bottom of their red boxes, because the rays are shooting-from red box centers.

So, now we see good distance numbers at console, as the ground plane tilts. I guess the next step would be to convert the distance values from the 4 rayzers… to a single angle in degrees.

If anyone would like to install that feature for us (for me), that would be fine.

The end objective… selective ramp-sliding from gravity-active freeCams.

If (currentAngle < 30 & !camera.isNaving) { camera.applyGravity = false }

Something like that. We want gravity to turn-ON again… IF user moves cam position.

It might be difficult to test whether the user moved the cam, or some momentary ramp-sliding moved it. It might take some careful tweaking to activate/control this “smart sliding” system.

It might be wiser… to shoot only ONE rayzer downward and get the pickedMesh. Then use ITS .rotation or .rotationQuaternion… to derive a degrees-of-rotation (a slope-angle). That would require 75% less rays, which means we could perf-afford a much faster distance-sampling rate.

Help/ideas welcome. Thanks!

Wow, impressive!

I’ve been working on the “new engine,” but I’ve encountered a bug! I’ll post it in the “bugs” section but I’ll explain it here too.

The bug is, well, multiple things that I think are not right.

  1. HERE I have the simple physics scene, the default one with the ball and plane. press space to make the ball come at the camera. The problem is that the ball doesn’t keep coming towards the camera. It keeps applying the impulse at the same direction every time, which WAS towards the camera, even if it is past the camera.

  2. the sphere’s rotation is NOT updating. HERE is the “new engine” I have 2 spheres on the big sphere, one in front and one to the side. at first, it works, with WASD moving in the correct directions. use the arrow keys to turn left and right. The direction is AGAIN staying as it was at first. if you put a console.log(sphere.rotation) in the RegisterbeforeRender function, the rotation will stay the same!

I’m gonna keep on working on this new engine, as it makes jump SO much easier!

Anyway, do you know of anyone who can fix these “bugs?”

1 Like

I put it in the bugs category and @sebavan is getting @trevordev to help fix it.

You’re doing fine. doTransformPerFlyerQuat() is still to come. Aww heck, I’ll make a PG with it installed. I renamed it to transformForce(). It’s only needed for translations (linear), not for rotations (angular).

All sorts of changes… but first step… how does it “feel” to you?

Q/E to turn. I wanted the arrow keys to stay un-assigned, so we still get full control of our camera turning IF you want it (player can turn head without turning body). You can disable its keys… later, as wanted… but… stick-with Q/E as your turn keys… for now. Better, while learning.

No onKeyUps anymore. In lines 67/68, I set the emergency brakes for both strafe and turn. It brings things to a stop QUICKLY, but not instantly. Cranking them both to .99 will REALLY increase braking, and likely cause the need for more impulse power.

Oh, did I remove all the impulsing, and convert to setLinearVelocity and setAngularVelocity? Ohh, sorry, but you’ll thank me later. :slight_smile:

I turned OFF jump, for now. I un-parented the camera. Let’s learn to drive the sphere before we attach cameras to it. :slight_smile:

I turned off the “auxilliary spheres” because… although a fine idea… the transformForce() function takes care of that FOR us. Notice that… no matter HOW you turn, the WASD keys still do the right thing.

No flags… (strafe, left, forward, etc). Your renderLoop is now empty, and running fast.

It’s sure to have some problems, because Wingnut touched it, which means it has a chance for disease. heh. I wish I could hold-down the W key WHILE tapping Q & E keys… but I haven’t learned how to do that yet. But… that would be nice nav. Hold W continuously… while occasionally tapping Q or E.

Ok, look it over… tell me what you think. Because of the “get velocities” wrapped inside the “set velocities”… you can repeatedly tap WASDQE, or hold them down… and the speeds keep increasing. I love that part. :slight_smile:

Thoughts? Do you disapprove-of converting from impulse… to setting linear/angular velocities?

No more lowered contact points to cause “wheelies”… because setLinearVelocity() and setAngularVelocity() don’t use contact points. But maybe they use pivotPoints. hmm. :wink:

Remember what I told you about physics engines LOVING .rotationQuaternion and pretty much ignoring .rotation. When physics is active on a mesh, the physics “body” (rigidBody) is the boss… and whatever its “quaternion” wants… the mesh must follow. But you CAN “go native” (go deep) and force-around the mesh.physicsImpostor.physicsBody.quaternion … seen here in the CannonJS API for it’s rigid body.

And remember that friction parameter… on sphereImpostors… does almost nothing. Not enough surface contact on bottom of sphere. Thus, we use damping. IF you used a boxImpostor on your sphere (allowed)… then friction would start working again… and keep you from sliding down gentle ramps.


Hey, that’s pretty good. I’ll use booleans to trigger the movement within the registerbeforerender function. There is a reason for that. It’s like this: every computer has different settings for repeat delay and speed. If they were different then the game would play differently on a different machine. With booleans, set true on keydown and false on keyup, the RBR function has the if-else question pertaining to the booleans, allowing for the movement to feel the same on different computers. I hope that was clear enough.:wink:

I’m still learning, and hopefully I can get this implemented and uploaded to the site.

I’ve been thinking about starting a weekly blog about the game, and maybe make a youtube series. Ya never know.:blush:

Thanks for all of this help, Wingnut. I’ll add you in the credits.:wink:

1 Like

Yeah, that’s cool.

Umm… I would use two functions… one for rotate(eitherDirection, power)… and one for translate(direction, power). Inside those functions… put the setLinearVelocity and setAngularVelocity crap that I added.

Make a universal turner and a universal mover. :slight_smile: Then call them after checking which flags. Nice and clean… two powerful easily-reusable functions.

1 Like

Thanks for all of the help! I should have the update done by the weekend!:blush:

1 Like

My pleasure.

There’s a version with the two “universal funcs” installed (lines 105-119). Look how clean the onKeyDown handler is. Yum!

Good luck!

Leave me something to do!

Yeah, it’s SO CLEAN!:hugs::hugs::hugs:

1 Like