mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-06 07:53:24 +02:00
149 lines
4.6 KiB
JavaScript
149 lines
4.6 KiB
JavaScript
"use strict";
|
|
//
|
|
// androidControls.js
|
|
//
|
|
// Created by keeshii on September 26th, 2023.
|
|
// Copyright 2022-2023 Overte e.V.
|
|
//
|
|
// This script read touch screen events and triggers mouse events.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
(function () {
|
|
|
|
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|
var DISPATCHER_TOUCH_PROPERTIES = ["id", "position", "rotation", "dimensions", "registrationPoint"];
|
|
|
|
var TAP_DELAY = 300;
|
|
|
|
function AndroidControls() {
|
|
this.onTouchStartFn = null;
|
|
this.onTouchEndFn = null;
|
|
this.touchStartTime = 0;
|
|
}
|
|
|
|
AndroidControls.prototype.intersectsOverlay = function (intersection) {
|
|
if (intersection && intersection.intersects && intersection.overlayID) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
AndroidControls.prototype.intersectsEntity = function (intersection) {
|
|
if (intersection && intersection.intersects && intersection.entityID) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
AndroidControls.prototype.findRayIntersection = function (pickRay) {
|
|
// Check 3D overlays and entities. Argument is an object with origin and direction.
|
|
var overlayRayIntersection = Overlays.findRayIntersection(pickRay);
|
|
var entityRayIntersection = Entities.findRayIntersection(pickRay, true);
|
|
var isOverlayInters = this.intersectsOverlay(overlayRayIntersection);
|
|
var isEntityInters = this.intersectsEntity(entityRayIntersection);
|
|
|
|
if (isOverlayInters && (!isEntityInters || overlayRayIntersection.distance < entityRayIntersection.distance)) {
|
|
return {type: 'overlay', obj: overlayRayIntersection};
|
|
} else if (isEntityInters) {
|
|
return {type: 'entity', obj: entityRayIntersection};
|
|
}
|
|
return false;
|
|
};
|
|
|
|
AndroidControls.prototype.createEventProperties = function (entityId, info, eventType) {
|
|
var pointerEvent = {
|
|
type: eventType,
|
|
id: 1,
|
|
pos2D: {x: 0, y: 0},
|
|
pos3D: info.obj.intersection,
|
|
normal: info.obj.surfaceNormal,
|
|
direction: info.obj.direction,
|
|
button: "Primary",
|
|
isPrimaryButton: true,
|
|
isLeftButton: true,
|
|
isPrimaryHeld: eventType === 'Press',
|
|
isSecondaryHeld: false,
|
|
isTertiaryHeld: false,
|
|
keyboardModifiers: 0
|
|
};
|
|
|
|
var properties = Entities.getEntityProperties(entityId, DISPATCHER_TOUCH_PROPERTIES);
|
|
if (properties.id === entityId) {
|
|
pointerEvent.pos2D = info.type === "entity"
|
|
? projectOntoEntityXYPlane(entityId, info.obj.intersection, properties)
|
|
: projectOntoOverlayXYPlane(entityId, info.obj.intersection, properties);
|
|
}
|
|
|
|
return pointerEvent;
|
|
};
|
|
|
|
AndroidControls.prototype.triggerClick = function (event) {
|
|
var info = this.findRayIntersection(Camera.computePickRay(event.x, event.y));
|
|
|
|
if (!info) {
|
|
return;
|
|
}
|
|
|
|
var entityId = info.type === "entity" ? info.obj.entityID : info.obj.overlayID;
|
|
var pressEvent = this.createEventProperties(entityId, info, 'Press');
|
|
var releaseEvent = this.createEventProperties(entityId, info, 'Release');
|
|
|
|
Entities.sendMousePressOnEntity(entityId, pressEvent);
|
|
Entities.sendClickDownOnEntity(entityId, pressEvent);
|
|
|
|
Script.setTimeout(function () {
|
|
Entities.sendMouseReleaseOnEntity(entityId, releaseEvent);
|
|
Entities.sendClickReleaseOnEntity(entityId, releaseEvent);
|
|
}, 75);
|
|
};
|
|
|
|
AndroidControls.prototype.onTouchStart = function (_event) {
|
|
this.touchStartTime = Date.now();
|
|
};
|
|
|
|
AndroidControls.prototype.onTouchEnd = function (event) {
|
|
var now = Date.now();
|
|
if (now - this.touchStartTime < TAP_DELAY) {
|
|
this.triggerClick(event);
|
|
}
|
|
this.touchStartTime = 0;
|
|
};
|
|
|
|
AndroidControls.prototype.init = function () {
|
|
var self = this;
|
|
this.onTouchStartFn = function (ev) {
|
|
self.onTouchStart(ev);
|
|
};
|
|
this.onTouchEndFn = function (ev) {
|
|
self.onTouchEnd(ev);
|
|
};
|
|
|
|
Controller.touchBeginEvent.connect(this.onTouchStartFn);
|
|
Controller.touchEndEvent.connect(this.onTouchEndFn);
|
|
};
|
|
|
|
AndroidControls.prototype.ending = function () {
|
|
if (this.onTouchStartFn) {
|
|
Controller.touchBeginEvent.disconnect(this.onTouchStartFn);
|
|
}
|
|
if (this.onTouchEndFn) {
|
|
Controller.touchEndEvent.disconnect(this.onTouchEndFn);
|
|
}
|
|
this.touchStartTime = 0;
|
|
this.onTouchStartFn = null;
|
|
this.onTouchEndFn = null;
|
|
};
|
|
|
|
var androidControls = new AndroidControls();
|
|
|
|
Script.scriptEnding.connect(function () {
|
|
androidControls.ending();
|
|
});
|
|
androidControls.init();
|
|
|
|
module.exports = androidControls;
|
|
}());
|