Richard C Posted December 5, 2017 Share Posted December 5, 2017 Still on my submarine project .............................. I need to use easing to make diving through water more realistic. Dive commences with a slow start easing to a constant descent/ascent rate. This is acheived with the formula used on each renderloop (the equivalent of EaseIn) : incrementer += 0.01; diveRate += Math.pow(1, incrementer); submarine.position.y -= parseFloat(diveRate / 2500); This works fine. However I'm struggling to acheive the equivalent EaseOut formula to apply to the vessel before it "hits" the sea bed on the descent or "bursts" through the water at the surface on ascent. Easing using Babylon animation or the likes of Greensock is not an option as the user needs to interact with other 'features' whilst the dive is underway. I realise this is a 'maths' problem' not a babylon issue but if some one has an answer or could point me to a good tutorial I would appreciate it thanks as ever Richard C Quote Link to comment Share on other sites More sharing options...
Wingnut Posted December 5, 2017 Share Posted December 5, 2017 Hi RC! Good to see you again. Your joystick taper-to-stop should give you a speed taper-off "method", but perhaps not the best, when adapted for ascents/descents. RC, can I ask a couple of questions? Does your sub allow "power" ascents/descents? Is any forward, reverse, or side-slewing thrust allowed... WHILE an ascent/descent is happening? (thx) You know me, RC. I'm a big fan of invisible mesh "sensors" around the outside of the sub. Keep in mind that you can parent invisible mesh to the sub... which are not even touching the sub's mesh at all. (stand-off parenting) (leaning towards child-neglect) heh The upper sensor might have a "Did sensor suddenly quit intersecting with the water?" Or perhaps better... "Did sensor get above a certain height?" Bottom sensor might be "Did I suddenly intersect with sea floor or items ON the sea floor?" The distance that you "offset" (stand-off) these sensors from their parent sub... determines the amount of throttle taper-off distance/time before impact or before surface porpoising. A fun thing to do would be to install all 6 invisible "sensing spheres" on all submarine axes, and put 6 lights on the dashboard. If any of the sensors reports an "close-proximity" or "all-stop" condition, its red light turns ON. Inside the renderLoop, the six sensors are continuously "polled" to see if any of them has a no-go condition. Keep in mind that the sensor diameter, and distance from sub... are "sensitivity" adjustments. You might even find that 3-5 invisible spheres stacked in a (inverted) snowman shape... might be wise. If the "farthest" sensor triggers intersect, start taper off. If 2nd farthest sensor triggers, heavier taper-off. If near-to-sub sensor triggers, panic braking. Perhaps you could use a sphere inside-of sphere inside-of sphere config, too. If outer sphere intersects... green light on dashboard starts blinking. Middle sphere, flashing yellow. Inner sphere... flashing red. If you want to avoid the "snowman stack-o-sensors", then your sensors could reposition themselves closer to the sub... after intersects. For example, by default, pretend belly sensor protrudes 20 feet from bottom of sub. If it intersects sea floor, start the dive-speed reduction, and pull-in sensor sphere to 10 feet protrusion from sub belly. If THAT intersects seafloor, get more serious with braking, and pull sensor into 5 feet from sub. If IT intersects seafloor, emergency dive-stop. I don't know if this is a wise idea, but it IS an idea. By surrounding the sub with sonar-like sensors, you can maintain a submarine "state". That "state" is a boss for the throttles. For example, if the nose sensor has a red light, the forward throttle does not work at all... only the other 5 axes. If you have a red light on the fore and aft sensor, you better go straight up or down. If you have red lights on all 6 (or more) sensors, then a whale has swallowed your submarine. Stay tuned for other ideas, and likely BETTER ones. Quote Link to comment Share on other sites More sharing options...
Richard C Posted December 5, 2017 Author Share Posted December 5, 2017 Hi Wingnut Yes in real-life the sub does allow for powered ascent/descent by use of vertical thrusters BUT these are not used to 'go faster' but to control ascent rate in the main - the sub always has positive bouyancy and without pilot intervention, would float to the surface. Reducing water pressure as the sub ascends causes air to expand which in turn creates even more bouyancy and the sub 'rushes' to the surface way beyond safe diving limits. As a point of interest - we actually allowed the sub to actually do that. The pilot got out of the sub at 15m and just let it ascend of in own accord. The sub actually left the water completely at the surface - a Red October moment for sure . The 900kg sub shot above the water by some 300cm. If that were allowed to happen in real life the passengers would be the whale fodder cos they would be dead as a result of extreme decompression sickness - the lungs could literally blow out of the body. So the vertical thrusters are used to control the rate of descent. For the same reason. they are used to maintain a fixed depth whilst moving horizontally when submerged. The purpose for the ease-in / easeout functions are two fold : 1. mimick what the pilot strives to do to make a slow start and gradually move to operating speed 2. to mimick the effect of the water / currents As I said earlier - the EaseIn formula works well - I just need the negative of it and I can't wrap my head round the solution Regarding sensors etc - I am raycasting to get the waterdepth in every render loop so know what depth the sub is at both from the surface and the seabed. The EaseOut function starts at a 1.5m from surface or bottom. Cheers Richard Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted December 5, 2017 Share Posted December 5, 2017 Thx. Let's see... these are bottomless air-bubble subs, right? SO if batteries fail, sub starts crash-surfacing, occupants are left on the sea-floor with no more air-bubble, so they drown. Sub accidentally rises into the launch-barge, and it sinks, and the sub is crushed, along with the drowned people, when the sunken launch-barge pins everything to the sea bed. NICE! err... no. Think about this. You're always applying a braking value of 20 - depth-to-something. So, when sub is at 30 meters distanceToSeabed, you apply braking force of Math.abs(20 - distanceToSeabed). 20 - 30 = 0 braking. When sub is 15 meters from grounded, braking is 20-15 = 5 units of braking. etc etc. Units of braking == reduction of down-thrust. So... this 20-whatever=VALUE... is the amount-of-reduction of down-thrust throttle setting. 20 is an arbitrary "testing range" number, of course. Adjust as needed. Would that work? *shrug* Let's see... the ascent. hmm. Is sea level set to 0? If so, same type of formula. Increase of down-thrust needs to happen, as sub nears surface. Sub depth == sub.position.y. Let's say sub depth = 30. abs(20 - 30) = 0. No increase in downward thrust. Now pretend sub is at depth 15. 20-15 = 5 units of increased down-thrust. *shrug* thoughts? Quote Link to comment Share on other sites More sharing options...
brianzinn Posted December 5, 2017 Share Posted December 5, 2017 43 minutes ago, Richard C said: I just need the negative of it EasingMode - BABYLON.EasingFunction.EASINGMODE_EASEOUT : Interpolation follows 100% interpolation minus the output of the formula associated with the easing function. Sorry if you read this doc already on Easing functions, but it's good: http://doc.babylonjs.com/babylon101/animations So, I think you need to go from "constant descent/ascent" rate and current rate to get next rate - not just incrementing. If you look at the interpolation values they all have start/end. Even a simple lerp (which you kinda want the opposite) for vertical position is: const lerpAmount = 0.1; const start = mesh.position.y; const end = mesh.position.y + distanceToAchieveConstantRate; const newY = (start + (end - start) * lerpAmount); mesh.position.y = newY; Quote Link to comment Share on other sites More sharing options...
Richard C Posted December 5, 2017 Author Share Posted December 5, 2017 brianzinn and Wingnut Thanks both - playing with both - I'll let you know Cheers Quote Link to comment Share on other sites More sharing options...
brianzinn Posted December 5, 2017 Share Posted December 5, 2017 OK, was just thinking as well that you would need to put those in your game loop. For a really smooth animation I think you would use engine.getDeltaTime() for time passed since last frame, but you can use 'scene.onXXXRenderObservable', too:https://www.babylonjs-playground.com/#Q81PBV#2 It's just a quick demo that uses lerp to move the dialog above the sphere without BABYLON.Animations. I think you could detect a collision with surface or bottom. edit: read it was a submarine Wingnut 1 Quote Link to comment Share on other sites More sharing options...
Richard C Posted December 7, 2017 Author Share Posted December 7, 2017 brianzinn - your suggested solution set me off on the right road and I now have the sub doing what I need. Many thanks to you and Wingnut R Wingnut and brianzinn 2 Quote Link to comment Share on other sites More sharing options...
brianzinn Posted December 7, 2017 Share Posted December 7, 2017 Nice you got that working. Post your solution, if you think it would help others. Cheers. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.