I’m just looking at
src/Cameras/Inputs/freeCameraMouseInput.ts and thinking about a similar interface for it.
We could make the defaults match the current implementation so existing users would not see any change. UnitTests would confirm this is the case.
I’d like to see the mouse capable of controlling the following camera properties:
- Position in scene.
- Position relative to camera.
- Position relative to ground plane. (Like Google maps in 3D mode. Mouse drag moves camera over ground without adjusting angle.)
- Camera angle.
I’d also like these properties to be affected dependent on whether a particular mouse button was pressed.
Eg: Left button drag moves the position relative to ground plane, Right button drag changes camera angle.
Bonus points for allowing different keyboard modifier keys to give the mouse different behaviors.
What would the interface look like for that?
I’m 2nd guessing the way i’ve done it for
mousewheel as there are just too many combinations to be practical with the mouse: 2 axis of moment, 8 button combinations (with 3 mouse buttons), ~4 camera properties to modify.
We need something that can take arbitrary input properties and map them to an arbitrary action.
Maybe something like this to have click and drag the Y axis on the mouse move the camera up and down the scene?
camera.inputs.attached["mouse"].setMoveAction([MOUSE_PROPERTY.AXIS_Y, MOUSE_PROPERTY.BUTTON_0], CAMERA_PROPERTY.MOVE_SCENE_Z);
In the underlying implementation, the collection of properties could be a bitmap that includes many mouse buttons, keyboard modifiers, etc. A bitmap would allow a simple
switch statement to pick the required action cheaply.
It’s not really in the same style as other Babylon components though.
Let’s try again:
camera.inputs.attached["mouse"].action[MOUSE_AXIS.Y][MODIFIER.BUTTON_0] = CAMERA_PROPERTY.MOVE_SCENE_Z;
This scheme would be a little annoying if we want to support more than one modifier; Either the user needs to understand bitwise operators (which isn’t really a thing i’d expect frontend folks to be thinking about often) or we’d need an Enum with a value for each combination of modifiers.
I don’t like it.
Let’s try again:
So in the last example if we were willing to have a big Enum with many, many values we might as well have many, many variables. And so we are back at something similar to my mousewheel implementation:
camera.inputs.attached["mousewheel"].mouseYButton0 = CAMERA_PROPERTY.MOVE_SCENE_Z;.
We’d need a full map of variables to assign properties to. eg:
I still don’t particularly like it.
Maybe i’m approaching this wrong.
Instead attaching camera properties to mouse action, attach the mouse action to the camera property.
camera.inputs.attached["mouse"].moveSceneZ.mouseAxis = MOUSE_AXIS.Y;
camera.inputs.attached["mouse"].moveSceneZ.modifiers = [MODIFIER.BUTTON_0];
I originally (when i was thinking about mousewheel) discounted this approach as it complicates verifying there isn’t more than one thing being controlled by a single input. You end up with a lot of getters and setters in the implementation.
I think it might be worth it though.
If i didn’t have to match existing style, I think my first example is what i’d choose.
Any Babylon devs care to comment on what the rules are on UI?
Anyone get this far?