Adjust the direction slider value to be the new 0

Hello Community,

Description:
I am using Babylon 4.2.0 because I have a large app and no time yet to upgrade to the new version.
I have shapes and a direction slider. when the direction slider value change, the rotation.y of the shape change. the minimum of the direction slider is -pill and the maximum is +pill initially

my desired behaviour is to keep the cursor on the slider in the middle on the ‘onPointerUpObservable’ . so when I change the direction of the shape A let’s say I want the new value to be the new Zero.

besides, when changing the shape (I Mean when I choose another shape because I have many shapes in the scene) let’s say shape B I should reset the directionValue to the rotation value of shape B keeping the cursor in the middle.

Code Snippet :
1- CreateDirectionSlider = (header) => {
let sessionInstance = this.state.scene_data?.slug;
var directionslider = new GUI.ImageBasedSlider();
directionslider.hoverCursor = “pointer”;
directionslider.horizontalAlignment = GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
directionslider.minimum = -3.14;
directionslider.maximum = 3.14;
directionslider.color = “white”;
directionslider.height = “12px”;
directionslider.width = “200px”;
directionslider.paddingLeft = 5;
directionslider.rotation = 3.14;
directionslider.value = 0; // Initial value

directionslider.backgroundImage = new GUI.Image("back", sliderValueBarIcon);
directionslider.valueBarImage = new GUI.Image("value", lineImage);
directionslider.thumbImage = new GUI.Image("thumb", sliderThumbIcon);


directionslider.onPointerUpObservable.add(() => {
  // here I want to update the direction value to make the new angle as the new 0 of the cursor
});

2 - editClickedMesh = (mesh) => {
mesh.actionManager = new BABYLON.ActionManager(thisscene);

var showShapeEditPanel = (meshEvent) => {
  //here I want to reset the directionValue to be the value of the    selected shape with keeping the cursor in the middle
};

mesh.actionManager.registerAction(
  new BABYLON.ExecuteCodeAction(
    BABYLON.ActionManager.OnPickDownTrigger,
    showShapeEditPanel
  )
);

};

Any Help will be appreciated as I tried many solutions but there is always a bug.

Hello and welcome to the Babylon community,

A Playground reproduction will help us help you :slight_smile:

Hi and welcome to the community,

I can see two things here. First thing is you could use steps (slider.step). Where the slider would have a limited number of steps (say 36) and where slider.step on initial would always be set to slider.maximum/2 which will make it show in the middle. This might make it a bit easier and may be more comprehensive in the code. But is just a suggestion.
The other and important thing is that you will need to recalculate the slider value, slider minimum and slider maximum for each mesh that has a different initial input. It’s the only way to show the slider in the middle when the value is ‘initial’. Say your mesh B is rotated 45° (Math.PI/4) and this is your initial value for mesh B. Then this value becomes your new slider.value for the initial. Now you have to calculate that the min and max do not start from 0 (say -Math.PI for the minimum and Math.PI for the maximum) but start from this new initial of Math.PI/4 (which in turns == (Math.PI/4 -Math.PI) for the minimum and (Math.PI/4 +Math.PI) for the maximum value. This way the slider with a value set at Math.PI/4 will show in the middle and you will still be able to make half a revolution of this mesh in both direction.

And then if this is a bit confusing, as said above by our gui-guru :grin: a playground would come in handy for us to demonstrate this.
Meanwhile, have a great day :sunglasses:

1 Like

Exactly what I was trying to implement.
But it happens that if I click on shape A and modify its direction, the cursor automatically returns to the middle which is the right behaviour. Afterwards, if I click on shape B, which triggers also the equation to adjust the slider according to B’s rotation (before rotating B , just click on the shape to make it the selected shape), without any specific reason or regular pattern shape B also changes its direction.
I will try to provide a playground as soon as possible maybe you can understand my problem

I see. Yes, the PG will certainly help getting this understanding. I can have a look at it tomorrow morning if it’s ready.

1 Like

Description :
Actually, I am working on this using my React app and socket But I tried to make the example as clear as I can.
Instruction:
you have to click on the shape to be able to change its rotation.
Link:

PS: Problem: try to change the direction of the first box then click on box B, then change B and click on A. The error should appear after some sequences

Thank you in advance

it looks like the problem is a closure with stale state (on your anonymous functions). In React you there is a hook useRef that has a current property.
Playground boxes with direction | Babylon.js Playground (babylonjs.com)

Hi,
As said above the issue is with your react function. Thanks BTW @brianzinn for taking care of that :pray: :hugs:
I also quickly checked through your PG on the BJS side, uncommented the lines making for the logic in BJS updating the state of slider on mesh pick and, yes, obviously all works fine on this end. :relieved:
So I hope you’ll be able to fix it now with the input given above. Else, let us know.
Have a great day :sunglasses:

Edit: Forgot to mention but I believe you know that and was just for test. You should use Math.PI instead of your value of 3.14, else you will never make it to 180°. Else you can convert to radians before hand.

As for the above, I will gladly let @brianzinn reply. Point is (sadly) I don’t really make react so I’m not the best at giving the correct explanation (and solution). I think he’s referring to the state of the selected mesh. If you don’t know where to look for it, best is to wait for him to reply. I’m sorry for the delay.

Regrettably, I’m having trouble comprehending the problem at hand. I acknowledge that the error seems evident in @brianzinn’s example, but I would greatly appreciate it if you could provide me with further clarification or offer any suggestions or suspicions you may have.

@mawa Just a quick question because I am afraid that you didn’t get what’s my error because without uncommenting the code the error appears

Please review this video screenshot and check the behaviour of the box on the left in the last seconds
And on a side note before adding this equation this wasn’t happening

Thank You. @brianzinn any explanation will be highly appreciated :slight_smile:

Sry for the misunderstanding.
I wasn’t speaking about these lines of code but just the ones you commented in your PG on lines 132 to 135.
I thought this was the behavior you wanted, isn’t it?

@mawa
I want the cursor to remain in the middle, so I include the equation (-Math.PI + rotationValue for the minimum and MATH.PI + rotationValue for the maximum) when changing the rotation of a shape or selecting a shape to rotate.

However, I noticed an issue in the last second of my video where the box on the left changes its direction when I select it. This problem occurs when I change the angle of a shape and then decide to select another shape, causing the selected shape to change its direction before I even move it.

I’m unsure if you can visualize the issue I’m describing, but when I remove the equations and abandon the idea of keeping the cursor in the middle, everything functions correctly.

Ok,
I have some news for you. I looked back at you PG and made a couple of findings.
Here I created a simplified version PG for testing:

The first thing I found abnormal in your initial PG is that your method actually creates 2 adt and 2 gui controls and containers (2 edit panels and more importantly 2 sliders). Obviously, this shouldn’t be.

Now, to what I believe is the point for the behavior you expose. Where in some cases, the mesh changed rotation and/or the slider did/does not return to the middle.

I managed to eliminate the first issue. Meshes do not visually change rotation anymore.
In this PG, try select a mesh, rotate it then pick the other mesh, rotate it. Return to the first, rotate it AND… everything eventually looks fine.

However, click on the mesh, rotate it to a negative value. Click on the other mesh rotate it to a positive value. Next click again on the first mesh, eventually the value changes. The mesh is still visually orientated correctly but peformed half a revolution. And when this happens, for some reason, the slider does also not display in the middle.

I’m not sure if this is strictly a Maths problem (I’m crap with maths :face_with_hand_over_mouth:) or if there’s also another issue where the slider would eventually not redraw?! :thinking: :dizzy_face:

At this point, I’d like to submit the above PG to my gui-angel :angel: cc @carolhmj

Edit: with this version PG below with a wrap texture on the cube, it is visually clear(er) that the box actually performs half a revolution. So, there definitely is (has to be) an error in Maths

I may be not fully grasping the requirements here but it seems like you just need to keep the slider minimum and maximum fixed instead of changing it every time you select a mesh? Playground boxes with direction | Babylon.js Playground (babylonjs.com)

The requirement is that (for some reason) onPointerUp or on mesh.pick the slider returns to the middle, while the current value of the selected mesh is kept and the new range of the slider goes from this selected mesh rotation to a minimum of this.mesh.rotation -Math.PI to a maximum range of this.mesh.rotation +Math.PI. Don’t ask me why. But that seems to be the requirement and something is just going very wrong here.

Ok, the problem here is not maths, it’s the slider. Whenever the maximum is reset, it also sets the value, which fires the onValueChangedObservable

Removing the callback before resetting the maximum and adding it again after seems to solve the problem: Playground boxes with direction | Babylon.js Playground (babylonjs.com)

2 Likes

@mawa Thank you for providing the explanation of my requirements.
Actually, the slider has a mid-value of 0, a minimum of -Math.PI, and a maximum of Math.PI. The user can move 90 degrees to the right and 90 degrees to the left from the mid-value. I have been asked to ensure that when the slider is picked up, the cursor remains in the middle (acting like 0), so that the user can move the shape 90 degrees to the left and right from the new chosen value. Additionally, when selecting a new character, I need to visually keep the cursor in the middle.
@carolhmj this a more detailed explanation. Thank you for your help

OMG, I wouldn’t have thought of that. With my level of Maths, I always have the feeling that it must be me doing something wrong :face_with_hand_over_mouth: :grinning:
Thanks a lot for looking into this. I knew you would be the one person to ask for it :superhero:
Have a good one :sunglasses:

1 Like

Well, I guess you have your answer now (and so do I :smiley:)
However, even with my maths skills, if you really want to move it just 90° then min and max should be Math.PI/2… Just sayin :grin:

1 Like

@carolhmj Thank you for your response!
After implementing your method, I found it to be flawless. However, when I performed a refresh (without being able to replicate it in the playground, as I only wanted to refresh the scene), I noticed that selecting a shape resulted in the directionSlider value becoming NaN. Despite having the following lines of code

console.log(
          "SELECTEDDD MESHHH",
          selectedMesh.rotation.y,
          selectedMesh.rotation.y - Math.PI,
          selectedMesh.rotation.y + Math.PI
        );
 directionSlider.onValueChangedObservable.removeCallback(valueChangedCb);
        directionSlider.minimum = selectedMesh.rotation.y - Math.PI;
        directionSlider.maximum = selectedMesh.rotation.y + Math.PI;
        directionSlider.value = selectedMesh.rotation.y;
        directionSlider.onValueChangedObservable.add(valueChangedCb);
        console.log(directionSlider.value, "Here I checked the value is  NAN and the cursor of the slider is invisible , although the selectedMesh.rotation.y is not NaN in the first console");