Key and Mouse Events


#1

During the test of my own script, I have seen that with different key and mouse events are happened odd things, which I haven’t had programmed in my own script. So I have looked in other script, to see, which key and mouse events already are used. Well many scripts use already key and mouse events and they may overlap one the other. It would be helpfully, to have list about the events, wich are used already from the core program and different scripts.

Here some examples:
cameraExample.js

function mouseMoveEvent(event) {
print(“mouseMoveEvent event.x,y=” + event.x + ", " + event.y);
var pickRay = Camera.computePickRay(event.x, event.y);
print(“called Camera.computePickRay()”);
print(“computePickRay origin=” + pickRay.origin.x + ", " + pickRay.origin.y + ", " + pickRay.origin.z);
print(“computePickRay direction=” + pickRay.direction.x + ", " + pickRay.direction.y + ", " + pickRay.direction.z);
}

function keyPressEvent(event)

if (joysticksCaptured) {
Controller.releaseJoystick(THRUST_CONTROLLER);
Controller.releaseJoystick(VIEW_CONTROLLER);
joysticksCaptured = false;
}

if (event.text == "1") {
    Camera.mode = "first person";
}

if (event.text == "2") {
    Camera.mode = "mirror";
}

if (event.text == "3") {
    Camera.mode = "third person";
}

if (event.text == "4") {
    Camera.mode = "independent";
    joysticksCaptured = true;
    Controller.captureJoystick(THRUST_CONTROLLER);
    Controller.captureJoystick(VIEW_CONTROLLER);
    position = { x: MyAvatar.position.x, y: MyAvatar.position.y + 1, z: MyAvatar.position.z };
}

controllerExample.js

function printKeyEvent(eventName, event) {
print(eventName);
print(" event.key=" + event.key);
print(" event.text=" + event.text);
print(" event.isShifted=" + event.isShifted);
print(" event.isControl=" + event.isControl);
print(" event.isMeta=" + event.isMeta);
print(" event.isAlt=" + event.isAlt);
print(" event.isKeypad=" + event.isKeypad);
}
function keyPressEvent(event) {
printKeyEvent(“keyPressEvent”, event);

if (event.text == "A") {
    print("the A key was pressed");
}
if (event.text == " ") {
    print("the <space> key was pressed");
}

}

function keyReleaseEvent(event) {
printKeyEvent(“keyReleaseEvent”, event);

if (event.text == "A") {
    print("the A key was released");
}
if (event.text == " ") {
    print("the <space> key was pressed");
}

}

grab.js
function keyReleaseEvent(event) {
if (event.text === “SHIFT”) {
moveUpDown = false;
}
if (event.text === “SPACE”) {
shouldRotate = false;
}
}

function keyPressEvent(event) {
if (event.text === “SHIFT”) {
moveUpDown = true;
}
if (event.text === “SPACE”) {
shouldRotate = true;
}
}

inspect.js

function keyPressEvent(event) {
var changed = false;

if (event.text == "ALT") {
    alt = true;
    changed = true;
}
if (event.text == "CONTROL") {
    control = true;
    changed = true;
}
if (event.text == "SHIFT") {
    shift = true;
    changed = true;
}

if (changed) {
    handleModes();
}

}

function keyReleaseEvent(event) {
var changed = false;

if (event.text == "ALT") {
    alt = false;
    changed = true;
}
if (event.text == "CONTROL") {
    control = false;
    changed = true;
}
if (event.text == "SHIFT") {
    shift = false;
    changed = true;
}

if (changed) {
    handleModes();
}

}
function mousePressEvent(event) {
if (alt && !isActive) {
mouseLastX = event.x;
mouseLastY = event.y;

    // Compute trajectories related values
    var pickRay = Camera.computePickRay(mouseLastX, mouseLastY);
    var modelIntersection = Entities.findRayIntersection(pickRay);
    
    position = Camera.getPosition();
    
    var avatarTarget = MyAvatar.getTargetAvatarPosition();
    
    
    var distance = -1;
    var string;
    
    if (modelIntersection.intersects && modelIntersection.accurate) {
        distance = modelIntersection.distance;
        center = modelIntersection.properties.position;
        string = "Inspecting model";
    }
    
    if ((distance == -1 || Vec3.length(Vec3.subtract(avatarTarget, position)) < distance) &&
        (avatarTarget.x != 0 || avatarTarget.y != 0 || avatarTarget.z != 0)) {
        distance = Vec3.length(Vec3.subtract(avatarTarget, position));
        center  = avatarTarget;
        string = "Inspecting avatar";
    }
    
    if (distance == -1) {
        return;
    }
    
    vector = Vec3.subtract(position, center);
    radius = Vec3.length(vector);
    azimuth = Math.atan2(vector.z, vector.x);
    altitude = Math.asin(vector.y / Vec3.length(vector));
    
    print(string);
    isActive = true;
}

}

function mouseReleaseEvent(event) {
if (isActive) {
isActive = false;
}
}

function mouseMoveEvent(event) {
if (isActive && mode != noMode) {
if (mode == radialMode) {
handleRadialMode(event.x - mouseLastX, event.y - mouseLastY);
}
if (mode == orbitMode) {
handleOrbitMode(event.x - mouseLastX, event.y - mouseLastY);
}
if (mode == panningMode) {
handlePanMode(event.x - mouseLastX, event.y - mouseLastY);
}

    mouseLastX = event.x;
    mouseLastY = event.y;
}

}


#2

In inspect.js are used alt, shift and control, to change the camera modes. So key combinations with alt, shift, and ctrl always will collide with it and can’t be used from other scripts.

function handleModes() {
var newMode = (mode == noMode) ? noMode : detachedMode;
if (alt) {
if (control) {
if (shift) {
newMode = panningMode;
} else {
newMode = orbitMode;
}
} else {
newMode = radialMode;
}
}


#3

Yeah, the scripting API documentation is very lack luster currently, most of it ive had to dig through the source code for the scripting interfaces under libraries/script-engine/src/

I havent tried all of these, but from what I can gather is that: AbstractControllerScriptingInterface (AKA Controller) contains the following events

keyPressEvent(const KeyEvent& event);
keyReleaseEvent(const KeyEvent& event);

actionStartEvent(const HFActionEvent& event);
actionEndEvent(const HFActionEvent& event);

backStartEvent();
backEndEvent();

mouseMoveEvent(const MouseEvent& event, unsigned int deviceID = 0);
mousePressEvent(const MouseEvent& event, unsigned int deviceID = 0);
mouseReleaseEvent(const MouseEvent& event, unsigned int deviceID = 0);

touchBeginEvent(const TouchEvent& event);
touchEndEvent(const TouchEvent& event);
touchUpdateEvent(const TouchEvent& event);

wheelEvent(const WheelEvent& event);

The Controller.<event>.connect(<function>) is defined in a way that when a keyPressEvent is triggered, all the functions added via .connect(<function>) will trigger throughout all the scripts connected for that event to the user…

Printing out the KeyEvent yields the following: using JSON.Stringify

{“key”:70,“text”:“f”,“isShifted”:false,“isMeta”:false,“isControl”:false,“isAlt”:false,“isKeypad”:false,“isAutoRepeat”:true}"

isAutoRepeat appears to be the “Hold Value”. Since this seems to be the same as in the KeyEvent source file, I can assume MouseEvent and HFActionEvent and TouchEvent have similar values to their sources.

In anycase, Id avoid using too many boolean values, and instead bundle every boolean into a bitwise integer. that way you can keep it compact.

Hopefully that helps.


#4

Thank Menithal, the main problem I see in the using of alt, shift and control already from scripts, which are loaded by default and control the camera or avatar moving. This dos mean, that they always will be activated, also if a other script dos work with a key combinations how alt+shift+… We will have here different controllers and all need some key events.
So it is really necessary, that we carefully look, which keys are used in which way.


#5

Here are more problems with key events:
https://alphas.highfidelity.io/t/escape-please-use-it-as-escape-key-and-not-to-open-the-lobby/6030/3
https://alphas.highfidelity.io/t/still-floating-off-into-space-every-time-i-take-a-snapshot/6003

We really need a list of used key events and change them where it is necessary.


#6

My floating off into space on snapshot (and a number of other events) is something new, @Summertime. My best performance was during the first week or so that I was here; I never experienced any problems during that time. I was so impressed! Things have been downhill for me every upgrade since 2158. Not sure if this timeline makes any difference in the analysis.


#7

I have this floating after snapshot already since I’m here. Than more actions we get, than more key and mouse events are active. I don’t know, if there somebody has an overview.


#8

Id actually like to see first person so that you do not have to hold the right mouse button down to look around / interact. Generally this method is good for Rifting or when editing something (its akin to a 3D suite navigation), but its not very intuitive for looking around when just hopping on if doing simple interactions. Complex interactions (grab translate, etc) should then require holding a control modifier. (ill probably be making this sorta script later)

This is more natural compared to how looking around games work today. Then holding Alt or Control allows you to use the mouse as you do now to then do more fine control interactions.

But again its really hard to document what will be used for what, especially after we begin to have more scripts for UI for various things: and as of the moment everything is bound to change still.

Generally as a rule of thumb, Ctrl or Alt or Shift (or combinations) should be reserved to modify camera actions (releasing camera, using the mouse, etc) or hotkeys combos. While WASD or Arrows keys or numpad are used for movements. Other keys are open to be used by anything.


#9

@Menithal, I think alt, ctrl and shift alone shouldn’t do something. Because they would be activated through every combination. In my gamepad I can use different combinations of alt, ctrl and shift with letters. I think other game controllers gives the same possibilities, so that we would have many possibilities of combinations.


#10

No they, the modifier keys ofcourse shouldn’t do anything by them selves (althought there are exceptions, such as fps controls), which is why i did say hotkey combos or camera controls: camera controls would still require you to have input from a mouse:

For example:

If mouse is bound to camera in first person (instead of constantly detached):

Long Explanation:

Holding Alt would release the mouse so that it would work like it does now so that you can click on anything, instead of constantly holding down the right mouse button to look around, it would be reverse, but with the alt button held to release the mouse. It would still be a combination of alt + move the mouse + click on intractable object / or hold / grab etc. Because right click and left click isnt going to work in that format.

Generally this would be the same as it works in SL when in first person mode.

Ofcourse since these can -all- be done anyway right now, you can always just disable / enable the script you want to use: The end user will still have a choice of what they actually want to use. There should however be someway to warn the end user that the key is in use / or throw and error that X script is using key: which maybe difficult.


#11

I understand you Menithal, only inspect.js, which is loaded by default, dos change the camera modes only through clicking alt, shift or ctrl.


#12

And here one more problem with the alt key. I try to bring them here all together, to get an overview:
https://alphas.highfidelity.io/t/a-few-new-problems/6055