Stop Sliding down Slopes (SSS)

Hi!

For my game, I would like to have “stairs.” aka: stairs in model with a sloped hitbox. The max slope degree I would like is 45 degrees, or 0.5 radians. HERE is a playground (here is your repro @Deltakosh) mouse locks to look use the arrow keys to move. go forward to the edge of the plane to find a box at a 45 degree angle. if you go on it, even if you aren’t holding any keys, you will slide down. This is a result of the camera._NeedMoveForGravity = true; at playground line 33.

Is there any way to not have the “player” slide down WITHOUT removing line 33?

Thanks for any help,
the slip-n-slide guy

Hi Givo,

This is a hack more than anything else, and so it may not work well for your case, but can you see if this does what you’re looking for?

https://playground.babylonjs.com/#U8MEB0#33

The only thing I changed was, on line 62, to set the camera’s ellipsoid to be very, very thin. The reasoning behind that is that the sliding experienced is caused by “deflection” away from the surface underneath, which was exacerbated by the spherical ellipsoid you were using before. By making the ellipsoid very thin, we can cause the camera to only “touch the ground” at a point almost directly beneath the camera, meaning that the resulting force applied to the camera has little if any horizontal component. You can control how strongly this hack’s effect is applied by tweaking the thinness of the ellipsoid.

If this doesn’t work, you might consider switching away from this feature to a more robust physics engine, where you’ll be able to do more sophisticated things like kinematics and friction. Might not be necessary for your case, though, depending on what exactly you’re wanting to do. :slight_smile:

1 Like

Thanks for the idea! using a physics engine isn’t that much of an option because you can’t have physics on the camera. I posted a thread where I wanted to push around a box and the only solution was to parent a box with physics to the camera, so the camera moves and the box goes with it.

Making the camera’s ellipsoid very thin isn’t that much of an option because I’m making and FPS. a demo(that is constantly being updated, and therefore may break) can be found at giv0.gitlab.io/fpsg. FPSG stands for First Person Shooter Game.

Here are the Controls:
WASD is move.
C toggles crouch.
SHIFT to run.
RIGHT CLICK to aim.
SPACE to jump.(WIP, not implemented yet)
F to toggle free cam.(my favorite implementation. I have an easter egg in the demo. Try to find it!)

Thanks for the answer!

Givo

Okay. If you’re creating a first-person shooter, then I would definitely recommend taking another look at using a physics engine. Having the camera attached to something with a PhysicsImposter (“collider” in Unity’s terms) is a very common way to handle this use case, and it gives you a lot of control over your system’s features going forward (world and projectile collisions, reaction to explosions, etc.).

Demo looks really cool, by the way; keep up the good work!

Hi guys. I did some tests a little while ago… gruesome.

https://playground.babylonjs.com/#U8MEB0#31

I have a hijacked _FreeCamera.collideWithWorld at lines 3-30. If is NOT default. Activate line 21, and de-activate line 22… to make it “stock” (default).

Lines 68-90 is also a function that has been “injected” into that camera, which overrides the default.

It is still functionally stock/default, but might have some console.logs and test lines inside it.

Line 92 checks BABYLON.Engine.CollisionsEpsilon …a very important global property that can be described-as “the amount of tendency to ‘scrub-off’ when colliding at an angle other-than polar or equatorial”. :slight_smile:

In other terms, push camera against box. Keep pushing… while turning the camera. BABYLON.Engine.CollisionsEpsilon can adjust the angle of camera-turn needed… to make camera start sliding/scrubbing-along wall surface.

It seems like a pertinent setting for this issue. No joy found.

In fact, all my “deep tests” so far… found no success. Might be over my head. :slight_smile:

Long ramp on this playground. :slight_smile: Hack-away, as wanted. Wear your safety goggles.

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!

Givo

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:https://forum.babylonjs.com/t/physics-dont-work-with-the-collisions-demo/1409.

Thanks for the idea, though.

Givo

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.

Caption: WHEEEEEEEEEEEEEEEEEEEEEEEEEEEE!
WHEEE

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!

Givo

If you’d like a little “taste” of “driving a box via physics” … here: https://www.babylonjs-playground.com/#PBVEM#304 (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?

https://www.babylonjs-playground.com/#IFN77Q

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!

Givo

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.

http://urbanproductions.com/wingy/babylon/misc/info01.jpg
(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.

https://www.babylonjs-playground.com/#CIFSQS#4

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

https://www.babylonjs-playground.com/#IFN77Q#13

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.

3 Likes