Jump to content


Richard C

Recommended Posts

Help please for VirtualJoysticksCamera. I can't find an answer in documentation for the following questions:

1.   I do not need the rightJoystickCamera just the left one - can I disable the right one?

2.   I do not want the camera speed to be too fast. I know I can set the speed of the camera but can I set a maximum speed and I would ideally like to be able to ease-in the speed to the maximum I set.

3.   The 2D rings that are used to depict the joystick need to be in a fixed position - on top of an actual joystick mesh - if I set the initial position how do I ensure that subsequent mouse clicks anywhere else on the screen will be ignored? 

4    Finally, I would like to limit the distance moved by the inner ring to not exceed the boundary of the out ring - simulating the limitation of movement of an actual joystick. So    :-Capture3.JPG




Not      :-Capture4.JPG

   Thanks for your help

Richard C

Link to comment
Share on other sites

Hi RC!  Hey, do you like "hacking"?  :)

Take a look at this ugly thing:  http://www.babylonjs-playground.com/#2J6AXA#0

In line 25, we create a BJS virtual joystick.  For some reason, its rings do not work (for me), but perhaps we don't care.  :)

When a virtualJoystick (vj) is activated, an extra HTML <canvas> element is appended to <body>. The rings are drawn... using Context2D "fill" graphics (similar to SVG).  That is why the "vj canvas" is added to the document.body.  Again, we don't care.  :)  BUT... a vj canvas covers the entire screen. IF it gets stuck ON... (possibly because missing scene.dispose {destroy vjCanvas})... then you cannot type in the playground editor anymore.  The vj canvas is blocking the editor window.

Sooooo... this playground... turns ON the virtual joystick, which adds the vjcanvas to the document... and lets you play with the VJ.... for 20 seconds.  After 20 seconds, it kills the vjcanvas.  You can "watch" the vjcanvas be added/removed.... by using your browser's dev tool - document inspector.

Back to our main story.  We create the vj in line 25, then "sniff the vjcanvas" in lines 30-31, and then we "override" two powerful functions of the vj... 

_onPointerUp (lines 37-40) ... and
_onPointerMove (lines 42-86)

These are called custom functions.  Overriding default functions on BJS systems... is very very fun.

All that crap aside... the important part...  lines 76-78.  this._deltaJoystickVector is the important "value" of the virtual joystick.  I just wired this._deltaJoystickVector  onto a box rotation... for fun.  You could use this._deltaJoystickVector value... to do ANYTHING YOU WISH!  (yay!).  Think about the drag-and-drop playground demo:)  That red sphere... looks similar to the joystick knob on a Wico "red ball" joystick, correct?  Hmmm.  ;)

Do you think you could mix drag'n'drop demo, with vj._deltaJoystickVector?  Then mix-in some red sphere positioning/limits, and you have operational "red sphere" joystick!  Yay. 

No rings, but you don't care.  You have red sphere, now.  He is better than rings.  :) 

Understand?  I hope so.  You have power.  Enough power to make your own virtual joystick (graphics part). 

Play with lines 76-78.  Disconnect from box.rotation, and try connecting-to camera.position or .rotation (with this.deltaJoystickVector value). 

Have some fun.  Blow something up.  heh. 

When you get your "drag on red ball" joystick working, you can MAYBE kill vjcanvas immediately and forever (in your project) because... you don't need rings.  You are using red sphere and friends.  No need for vjcanvas at all.  (I think).  Also notice that the drag-and-drop demo NEEDS a "ground" underneath dragged items.  SO your virtual joystick graphics might need a small "ground plane" somewhere on it.  It CAN be invisible, though.

I hope this helps.  There are "other ways", if you don't want to "hack".

Link to comment
Share on other sites

Hey Wingy

Thanks so much for your considered reply. I understand some of the workings of joystick better and especially the notion of 'rings on a 2D canvas'. I'm not sure my javascript knowledge is good enough to delve too far into the world of 'hacking'. So perhaps a more simple work around should be found.

Your explanation seems focus on Joystick rather than JoysticksCamera - do the same principals apply to both?

If not, then the first 4 questions still apply any help with these answers would be very gratefully received. You may recall this image from an earlier post. Capture1.JPG

You can see that there is a mesh representing a joystick, which of course is 'moveable' but the 2 rings of the 2D canvas would make it more obvious to the user what to do to manoeuvre the scene ie take the submarine on a journey around the coral reef. Up and down movement is by filling/blowing air to/ from ballast tanks in the front and rear of the sub which is what the orange valves are for - so the joystick is for forward/back/side movement. Hence I do not need the rightJoystick Camera.

The subs actual speed is a max of 4.5 knots, thus the reason for needing to limit the speed at which the camera moves.

Again, as ever, thanks for your help.

Richard C


Link to comment
Share on other sites

My pleasure, RC!  In my opinion, you don't need the VJ camera.  It is your choice, of course.

If I were you, I would "find" the mesh that is the joystick handle... and set its pivotMatrix/pivotPoint... down low.  (perhaps where the stick meets the rubber).

Then make it pickable and draggable... but with limits.  The pointer will change to a finger... when the user mouses-over the joystick.  If the user drags on the joystick, it's rotation changes... but you limit it... maybe to 10 degrees maximum rotation.  The amount and direction of the rotation... is your left/right/fore/aft throttle setting.

You see, you are not using the joystick to move a camera, so why not use a standard freeCamera or universalCamera?  The VJCamera (its VJ's) were designed to move/operate that camera.  You actually need a virtual joystick by itself... for moving the views in your window planes, right?  A standard freeCamera would still allow the user to look-around in the submarine cockpit.

YOUR VJ is only for moving the submarine itself.


Here is a little demo... using only a portion of the drag-and-drop demo.  I badly-coded some redSphere positioning code in lines 90-98.  It lets the redSphere move approx 10 units forward/backwards/left/right.  I also added a do-nothing actionManager to redSphere... in lines 32-33 (to make a pointer activate when mouseOver the redSphere)

Normally, the redSphere is at x=0, z=0.  After you drag it (some)... redSphere.position.z contains your submarine forward/backward throttle setting... +9 to -9, right?  AND...  redSphere.position.x contains your left/right translation throttle setting... +9 to -9, yes?  A simple joystick controller... made by RC! 

You can keep using the standard freeCamera... and you don't have to deal-with extra canvas added to <body>, and you can use MESH to indicate things.  AND... all of our new Canvas2D system (which doesn't use the extra added canvas element)... is still available to you.  It is a very powerful 2D graphics system.

In a way, I am trying to "steer" you away-from using standard VJ's or the VJ camera (which is just a standard camera with two VJ's added.... for controlling that camera.)  The VJ's, and VJ canvas... are about to get a re-coding from our friend and hero @davrous.  The new system will ALSO use the new Canvas2D system and not use the extra canvas element method.  SO... this is why I try to get you to use standard mesh... possibly with a freeCamera with touch inputs active... but avoiding "the rings".  The rings are old school and are being "abolished" soon... as best I know. 

Maybe others will have better ideas or better answers for your questions. 

Sorry about talking so much on your thread... but I wanted to tell you some things (about the future of VJ's/rings) before you "move forward" with customizing the VJ Camera. 

Did you look at the VJ source code?  Sensitivity/speed are likely easily set, but keeping inner-ring from moving too far.... might be more of a challenge.

Always keep in mind that the vjCanvas covers the entire screen, including any HTML you have surrounding the renderCanvas.  It can block clicks on HTML things.  :)  You can always escape a blocking... by opening browser tools, document inspector... highlight and delete LAST canvas in the <BODY> of the document.  It has no id or class.  Party on!

Link to comment
Share on other sites

Thanks Wingy

I need time to take all that in and start experimenting. Will keep you posted.

In the meantime one other question if I may, the dashboard and all the instruments are imported all as separate meshes - mainly to make material allocation easier ie as few multi-materials as possible (Gryff's recommendation). They are all appended from Blender (not loaded). How do I group them into one moveable mesh so the submarine as a whole is moving - controlled of course by the joystick as you suggest.

There will be a second mesh appended from Blender which will the under water scene the sub will explore. What you see in the previous screenshot is a only skybox.

Thanks again

Richard C

Link to comment
Share on other sites

RC got his answer in another thread.  For others' benefit - here is that answer.  Party on.

RC... I have a quick question for you.  Do you want your joystick to automatically return to center... after user has finished (digital-switches joystick).  Or would you like user to be able to "set it" to... for example... 40% reverse thrust and 10% left thrust... and have the joystick stay set (analog-pots joystick)?  Any thoughts?  (thx)

I might try a "better joystick" as a fun experiment.  Maybe.  :)

Link to comment
Share on other sites

Hey Wingy

The actual joysticks in the subs are spring loaded and therefore return to centre when released. 

The next task having worked out how to 'rotate' the joystick based on the advice in the 'other thread' is for the whole mesh to move in the direction that is indicated by the joystick position, ie not just move left/right or back/fore but also all angles of the circle. I am assuming the logic is for the mes(es) to translate in the same direction being set by the joystick position by comparing a starting point vector and the current vector. How to do this is my next learning curve so ANY help you can give is going to be very very gratefully received.

Thanks as ever


Link to comment
Share on other sites

Yes!!!  Well thought.  We have been working with redSphere.position, in the drag-and-drop examples.  After you/we convert the sphere... into a stick... we will use stick.rotation (if it is ok with you).  Stick.rotation will work great... after we move its pivot point lower (down near the rubber base, at the bottom of the stick.) 

Likely, we don't need to work with vectors at all... or very little.  When the stick is not pushed, its rotation.x will be 0, and its rotation.z will be 0.  When the user drags the stick, no matter which direction, stick.rotation.x and stick.rotation.z will NOT = 0 anymore, right?  They will have small negative or positive values.  We don't even need to do any subtracting.  The values in stick.rotation.x and stick.rotation.z... will be the actual throttle settings for the sub.

In the renderLoop, we could do something like...  submarine.x += stick.rotation.x/sensitivitySetting;   ...and submarine.z += stick.rotation.z/sensitivitySetting;  Simple, eh?  If stick.rotation.x == 0 ... or stick.rotation.z == 0... we will be adding (+=) 0 to the sub position, so no movement.  If stickrot x or z is a negative number... we will be adding (+=) negative numbers... so the sub will move backwards (-z) or left (-x).  If positive numbers, sub will move forward (+z) or right (+x).  Easy, huh?  Well, sorta.  The drag-and-drop stuff has quite a bit of code to it, but that is mostly pointer event-processing crap.

One more question.  Let's pretend user wants to move sub ONLY to the left.  Can the user go slow-left and fast-left... depending upon how far the user moved the joystick to the left?

Generally, if the joystick has switches... joystick-left means sub moves left at one fixed speed.  User cannot change left-move speed without using another controller for throttle.

But if joystick has potentiometers/encoders, user can control left-move speed... with the amount of joystick left-move distance.  This is the way it will work... with the method I described above.  Small amount of left joystick = slowly move sub left.  Large amount of left joystick = quickly move sub left.

Variable throttle/move-speed with joystick?  (encoders/pots)   Or fixed throttle? (on/off switches)

I like variable throttle per amount of joystick movement, actually.  :)  More fun.

We will also need a "dead zone".  If user wants to move sub ONLY left, it will be difficult to keep sub from moving backward/forward a small amount. The dead zone simply says "IF user did not move (rotate) stick more than .02 radians of distance, ignore it."  This will allow the user to move left... without accidentally moving forward or backward.

Thoughts?  I think we are almost ready to make "joystick playground test version 2"  Everyone can participate!  :)  Talk soon.

Possibly interesting side-note:  The safety systems used in manned vehicles like these... are ridiculously expensive.  This is why smaller robot vehicles with lots of cameras... are being used more and more often.  These cost savings... is why an un-manned Russian "supply vehicle" is used to bring supplies to the International Space Station.  Cheaper.  Safer.  Pilots sit in their living room, in a comfy chair, using the joysticks and watching the camera feeds on their big-screen TVs.  :)  But SOME pilots STILL want to travel under the ocean or into space... to get away-from their annoying families.  heh.

Link to comment
Share on other sites

Here's a new joystick, with a little green simulated sub.


- Line 42 is where I moved the "bat" pivot point... to the bottom.
- X and Z submarine throttles are declared in lines 45-46.
- Line 83 is where we spring the bat to center... on button-up.  No xspeed or z-speed (throttles) are zero-out here, but perhaps it SHOULD be (stop sub on pointerIUp).
- Joystick bat rotation happens in lines 103-104.
- A likely-badly-coded "range limiter" in lines 106-110.
- Lines 112-113 "transfer" bat rotation... to sub throttles.  Notice how they are reversed?  Weird, eh?
- Lines 121-125 is the dreaded renderLoop.  Here we continuously apply current xspeed and zspeed... to sub.position.  Off we go!

No dead-zone is coded, yet. 

Notice how the sub moves faster when joystick is pulled HARD, and slower when pulled lightly?   So, this joystick is a direction-setter, AND a throttle controller.  Workin' almost okay, huh?  :)

I was thinking more.  If you make the soon-invisible "ground" mesh REALLY BIG... you can use this same "drag-to-rotate" method... to rotate the ballast valve levers, too.  Coooooool.

And the rings or something similar... ARE still available (without using a VJcam/VJCanvas).  We/you would use the new Canvas2D system.  It rocks.  HUD displays, digital readouts on dashboards, labeling buttons, sprite animations, it can do it all.  But, it is powerful, and so it has lots of settings.  Scary at first.  :)  Cya later.

Link to comment
Share on other sites

Wingy - your summary of the effect of moving the joystick on the overall movement of the sub is absolutely correct.


The sub is a simple design and concept. It is effectively a motorised diving bell - but rather than taking just one head it takes 3 people - the qualified pilot and two passengers. You can see that entry into the sub is via the opening under the tail. All three sit in a bubble of air which is constantly refreshed throughout the dive of course. The lower half of the body is in water the upper half in the bubble. The pressure of the air bubble must always equal the pressure of the water thus, just like scuba diving, the people need to equalise (pop their ears) as the sub descends. Given the pressure inside and out is equal, the body is fibreglass not 3" steel plate found in deep water submersibles.

The horizontal propellers move the sub back/forth/side. Flooding/blowing ballast in the nose and tail allows the sub to descend / ascend but as the golden safety rule must be to always maintain slight  positive buoyancy the vertical thrusters are used to exert downward pressure as the sub wants to always rise due to it's positive buoyancy. The vertical thrusters can be operated manually by the pilot not via the joystick by a separate toggle switch but for the main are they are computer controlled keeping the sub at a depth set by the pilot.  

Safety wise - the sub has dual systems, spare air supply etc but the overall safety that prevents the sub from an uncontrolled descent (sinking is such a bad word in the world of submarines) is maintaining positive buoyancy. We also try to always operate in water no more than 12m depth. Depending on air use, the sub can stay submerged for approximately 50-60 mins.

The maximum speed is 4.5 knots and while the motor speed is variable, joystick operation in reality tend to be fully forward/back etc. So to answer your question regarding left slow/fast the answer is yes but as the max is only 4.5 knots then the effect is unnoticeable.  No warp factor 10 here regrettably.

I hope this gives an insight into what needs to be achieved and I as evr look forward to whatever 'tuppence worth' any one wants to throw in!!

Link to comment
Share on other sites

Wingy. I downloaded the code and all works well via the editor I am using (Brackets in my case) so the compilation error is perhaps a PG thing.

I have added a couple of lines to stop the sub in the pointerUp event but need to work on bringing the sub to a gentle stop rather than just stopping abruptly, which of course copies real life. I think we can ignore the effects of current for this purpose but of course in real life the pilot has to be constantly aware of the effects of current and making minor adjustments as necessary. Crashing into the precious reef is frowned upon by the Aussie Marine Parks Authority and the penalties if caught doing so are high. 

I also look forward to playing with 2D as you suggest - another steep and somewhat daunting learning curve for me to master.

Link to comment
Share on other sites

Cool, thanks for all the great insight!  Excellent!  A worthwhile diatribe.  :)

I get no error.  hmm.  Sometimes it is wise to clear your browser cache (unconditional reload).  Old versions of the framework need to be cleaned out of browser cache.  Try that, see if it helps.  No promises.  Which browser(s) are you driving on what platform? 


scene.beforeRender = () => {

Nobody knows what that thing is. heh.  It is some kind of magic gemstone or something.  :)

It is shortcut for doing...

scene.beforeRender = function() {

I just started using it recently.  I don't know which version of ecma-script/js first allowed it.  It sure is funny-looking, huh?

Let's see... taper-off to a stop.  How the heck do we do that.  hmm.  (Wingy thinks)  (That usually causes the issue to get worse)  :)

Link to comment
Share on other sites

*nod* The global flag (for use in renderLoop) is wise, I think.  Essentially...  in the render loop...

         if (stickNotPushed) { check for residual speed, and if found, reduce that speed ONE small step }

The same system could be used for returning the stick to center... in a SLIGHTLY more-gradual way.

I think stick-to-center should happen MUCH faster than sub-to-stop, though.  I think you will agree.  :)

Deadzone... hmmm... if diff.x > minimumStickPush { do the move }    ...    else { ignore }  ??

Not sure. You can probably figure that out ok.  I think you have this thing pretty well mastered.

I hope you aren't disappointed with leaving behind VjCam and it's rings.  You have a more robust and personalized joystick system, now (imho).  It is quite possible to "leave behind" the ground plane, and its getGroundPosition(), too.  Possibly study classic browser-based canvas drag-and-drop.  http://konvajs.github.io/docs/drag_and_drop/Drag_and_Drop.html

You need the "difference" values from pointer-down to pointer-up, and you no longer need the ground or getGroundPosition().  Mix the canvas drag-and-drop tutorial (the url above)... with your submarine throttle values, right?  Then... perhaps... say goodbye to the ground and getGroundPosition().  Instead, you can use pickingRay.pickInfo or actionManagers... to determine where (on the renderCanvas) a drag started, and how much change since last frame. 

You would be leaving behind some of the things in the playground drag'n'drop demo... and creating your own canvas drag-listener... somewhat lighter weight than our d'n'd demo.   Not sure what can be done there.  Maybe I will try a ground-less joystick, soon.  Maybe you can try one, too.  :)  Perhaps, the ground must stay.

2-4 more days of studying drag'n'drop, and you will be an expert, I suspect.  :)   I'll be around.  Ping me as needed.


Link to comment
Share on other sites

That question can wait - I have another one. I thought I would experiment with 'bringing the sub to a slower halt by animation, starting with of course:

var animateSub= new BABYLON.Animation("subAnimation", "position.x", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT,                                                                       BABYLON..ANIMATIONLOOPMODE_CONSTANT);

but we need to move in both x and y vectors. I can't find any reference in docs/tutorial on how to make the property element both position.x and position.y - any clues please?


Link to comment
Share on other sites

Clue given... in the new thread.  But but but but... hmm.  You might run into problems... when the joystick is released for only a hundredth of a second and then pulled to a different direction by the user.  The animation (which is a pre-calculated interpolation... like a pre-calculated change-per-timeline)... might not be finished... when the user asks for something different (pulls the joystick again).  The animation might need time to complete... before another move is allowed.

There's potential trouble on the horizon.  :o  Let's try the other way.


There ya go.  What a nice guy I am, huh?  Added stickInUse global var (at line 81).  Set it to false in onPointerUp (line 85).  Set it to true in onPointerMove (line 97).  Added a rampDown "rate" in line 124.  Added a bunch of badly-coded crap to the renderLoop (lines 130-135).  Stuff.  :)

Are you still getting playground errors?  I hope not.

Is the rampdown method.. better than using animation method?  ;)  I think so. 

The sub might be doing a tiny amount of moving-around, even when it appears to be stopped.  Probably an insignificant amount. 

Wiser coders than I... can probably write that renderloop code much better.  Hopefully, they will join us and contribute their wisdom.  Party on.

PS: I see/saw no private message.  hmm.  Darn.  I'll keep looking around for it.  Perhaps my dog ate it.  :o

Link to comment
Share on other sites

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.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...