mirror of
https://github.com/overte-org/overte.git
synced 2025-07-19 02:28:30 +02:00
* mirrors wip * fix view + projection, texture flipping, billboarding * wip portals * wip * fix cpu frustum culling (hacky?) * fix mirrors in deferred * mirrors on models + text * portals use exit as ignoreItem * cleanup * entity tags * wild guess to handle view correction, hide portalExitID in create when mirrorMode != portal * let's try this?? * plz * promising * fix paramsOffset and view flipping * portals shouldn't flip * break when tag found * fix portal view calculation * Revert "Mirrors + Portals" * Revert "Revert "Mirrors + Portals"" * web entity wantsKeyboardFocus property * fix typo * move audio zones to zone entity properties * fix audio zones in create * set dynamic factory * new procecural particle entity type * fix particle intersection * shorten create labels * fix 0 update props case * Ability to smooth model animations * sound entities * fix layered simulate items * fix stereo sound speed * support non-localOnly sound avatar entities * add sound url prompt * support registration point, improve locking * remove keyboardRasied * locking attempt #2 * fix keyboardRasied typo * add default particle props * add unlit property for shapes * Merge branch master into protocol_changes * add ambient light color * fix create issue * fix create issue * add tonemapping props to zones, wip ambient occlusion * wip ambient occlusion * it's working! * remove attachments * fix non-localOnly positional sounds not updating * change AO default to HBAO, remove from create * more graphics options * fix AO setting + effects in mirrors * fix AA in mirrors * alezia's fixes * fix haze in mirrors * add comment for SKYBOX_DISTANCE * new line * model loading priority updates over time, takes into account out of bounds, avatar entities have higher priority, and fsts can specify to wait for wearables to load before rendering * add loadPriority to model entities, working on other avatars waitForWearables * fix build error * try to fix isServer assert * fix stats + waitForWearables * Listen for click instead of release. * Reverted initial commit. Implemented hack to listen for menu click events. * Missed some reverts. * Missed another one. * Prevent duplicate actions. * Added extra needed checks. * Fix without formatting? (#91) * Hopefully fixed formatting. * Things can't be too easy. * Remove google poly * automated entity property serialization * cleanup + automate EntityPropertyFlags * text vertical alignment, use uint8_t for entity property enums, fix text recalculating too often * fix text size * Update interface/resources/controllers/keyboardMouse.json Co-authored-by: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> * fix component mode serialization * Fixed mouse look in selfie mode. * fix text debug assert on invalid or unloaded font * missed some enums * fix ADD_GROUP_PROPERTY_TO_MAP * fix PROP_GRAB_EQUIPPABLE_INDICATOR_URL missing urlPermission * fix KeyLightPropertyGroup legacy properties * fix PolyLineEntityItem::getEntityProperties * comment cmake script * fix copyright * Replaced key value with key text. Added additional comment about the specific delete key used. * weekly promoted place Highlight the first place in the list as the weekly promoted place * Fixed lingering references to `avatarIcon`. Signed-off-by: armored-dragon <publicmail@armoreddragon.com> * Adding icon for "Grab And Equip" section Adding icon for "Grab And Equip" section * Add "Grab And Equip" section Add "Grab And Equip" section for the grabbale and Equipable groups of properties. * Add files via upload * Add tooltips for the "Grab and Equip" properties Add the tooltips for the "Grab and Equip" properties * Text adjustments for grab.equippable Text adjustments for grab.equippable * Make Maturity Filter persisted Make Maturity Filter persisted and with a default value (Teen & Everyone) * Adjust the default value for maturity Adjust the default value for maturity * move "triggerable" under GRAB & EQUIP move "triggerable" under GRAB & EQUIP * Remove hifi-screenshare Cherry picked and updated from Tivoli dd5b6ea6ee5597a06603e16509640e7ed18106bb Co-authored-by: Julian Groß <julian.g@posteo.de> * Insert placeholder to not break protocol yet. * Fix incorrectly resolved merge conflict, left too much code. * Fixes based on review comments on previous PR * Remove code accidentally re-added during a conflict fix * bump protocol * rebuild fonts with full charset (NOT -allglyphs) * Attempt at fixing Windows master branch builds * Change minimum angular velocity to a lower one * Fix Uuid.NULL behavior --------- Signed-off-by: armored-dragon <publicmail@armoreddragon.com> Co-authored-by: HifiExperiments <thingsandstuffblog@gmail.com> Co-authored-by: ksuprynowicz <ksuprynowicz@post.pl> Co-authored-by: Dale Glass <51060919+daleglass@users.noreply.github.com> Co-authored-by: HifiExperiments <53453710+HifiExperiments@users.noreply.github.com> Co-authored-by: Julian Groß <julian.g@posteo.de> Co-authored-by: armored-dragon <publicmail@armoreddragon.com> Co-authored-by: Armored-Dragon <github56254@armoreddragon.com> Co-authored-by: Alezia Kurdis <60075796+AleziaKurdis@users.noreply.github.com> Co-authored-by: Maki <mxmcube@gmail.com> Co-authored-by: Dale Glass <dale@daleglass.net>
251 lines
10 KiB
JavaScript
251 lines
10 KiB
JavaScript
"use strict";
|
|
|
|
// touchEventUtils.js
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
|
|
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
|
enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
|
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, controllerDispatcher.ZERO_VEC,
|
|
HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset
|
|
*/
|
|
|
|
var controllerDispatcher = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
|
|
function touchTargetHasKeyboardFocus(touchTarget) {
|
|
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {
|
|
return Entities.keyboardFocusEntity === touchTarget.entityID;
|
|
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {
|
|
return Overlays.keyboardFocusOverlay === touchTarget.overlayID;
|
|
}
|
|
}
|
|
|
|
function setKeyboardFocusOnTouchTarget(touchTarget) {
|
|
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE &&
|
|
Entities.wantsHandControllerPointerEvents(touchTarget.entityID)) {
|
|
Overlays.keyboardFocusOverlay = Uuid.NONE;
|
|
Entities.keyboardFocusEntity = touchTarget.entityID;
|
|
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {
|
|
Overlays.keyboardFocusOverlay = touchTarget.overlayID;
|
|
Entities.keyboardFocusEntity = Uuid.NONE;
|
|
}
|
|
}
|
|
|
|
function sendHoverEnterEventToTouchTarget(hand, touchTarget) {
|
|
var pointerEvent = {
|
|
type: "Move",
|
|
id: hand + 1, // 0 is reserved for hardware mouse
|
|
pos2D: touchTarget.position2D,
|
|
pos3D: touchTarget.position,
|
|
normal: touchTarget.normal,
|
|
direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),
|
|
button: "None"
|
|
};
|
|
|
|
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {
|
|
Entities.sendHoverEnterEntity(touchTarget.entityID, pointerEvent);
|
|
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {
|
|
Overlays.sendHoverEnterOverlay(touchTarget.overlayID, pointerEvent);
|
|
}
|
|
}
|
|
|
|
function sendHoverOverEventToTouchTarget(hand, touchTarget) {
|
|
var pointerEvent = {
|
|
type: "Move",
|
|
id: hand + 1, // 0 is reserved for hardware mouse
|
|
pos2D: touchTarget.position2D,
|
|
pos3D: touchTarget.position,
|
|
normal: touchTarget.normal,
|
|
direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),
|
|
button: "None"
|
|
};
|
|
|
|
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {
|
|
Entities.sendMouseMoveOnEntity(touchTarget.entityID, pointerEvent);
|
|
Entities.sendHoverOverEntity(touchTarget.entityID, pointerEvent);
|
|
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {
|
|
Overlays.sendMouseMoveOnOverlay(touchTarget.overlayID, pointerEvent);
|
|
Overlays.sendHoverOverOverlay(touchTarget.overlayID, pointerEvent);
|
|
}
|
|
}
|
|
|
|
function sendTouchStartEventToTouchTarget(hand, touchTarget) {
|
|
var pointerEvent = {
|
|
type: "Press",
|
|
id: hand + 1, // 0 is reserved for hardware mouse
|
|
pos2D: touchTarget.position2D,
|
|
pos3D: touchTarget.position,
|
|
normal: touchTarget.normal,
|
|
direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),
|
|
button: "Primary",
|
|
isPrimaryHeld: true
|
|
};
|
|
|
|
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {
|
|
Entities.sendMousePressOnEntity(touchTarget.entityID, pointerEvent);
|
|
Entities.sendClickDownOnEntity(touchTarget.entityID, pointerEvent);
|
|
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {
|
|
Overlays.sendMousePressOnOverlay(touchTarget.overlayID, pointerEvent);
|
|
}
|
|
}
|
|
|
|
function sendTouchEndEventToTouchTarget(hand, touchTarget) {
|
|
var pointerEvent = {
|
|
type: "Release",
|
|
id: hand + 1, // 0 is reserved for hardware mouse
|
|
pos2D: touchTarget.position2D,
|
|
pos3D: touchTarget.position,
|
|
normal: touchTarget.normal,
|
|
direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),
|
|
button: "Primary"
|
|
};
|
|
|
|
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {
|
|
Entities.sendMouseReleaseOnEntity(touchTarget.entityID, pointerEvent);
|
|
Entities.sendClickReleaseOnEntity(touchTarget.entityID, pointerEvent);
|
|
Entities.sendHoverLeaveEntity(touchTarget.entityID, pointerEvent);
|
|
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {
|
|
Overlays.sendMouseReleaseOnOverlay(touchTarget.overlayID, pointerEvent);
|
|
}
|
|
}
|
|
|
|
function sendTouchMoveEventToTouchTarget(hand, touchTarget) {
|
|
var pointerEvent = {
|
|
type: "Move",
|
|
id: hand + 1, // 0 is reserved for hardware mouse
|
|
pos2D: touchTarget.position2D,
|
|
pos3D: touchTarget.position,
|
|
normal: touchTarget.normal,
|
|
direction: Vec3.subtract(controllerDispatcher.ZERO_VEC, touchTarget.normal),
|
|
button: "Primary",
|
|
isPrimaryHeld: true
|
|
};
|
|
|
|
if (touchTarget.entityID && touchTarget.entityID !== Uuid.NONE) {
|
|
Entities.sendMouseMoveOnEntity(touchTarget.entityID, pointerEvent);
|
|
Entities.sendHoldingClickOnEntity(touchTarget.entityID, pointerEvent);
|
|
} else if (touchTarget.overlayID && touchTarget.overlayID !== Uuid.NONE) {
|
|
Overlays.sendMouseMoveOnOverlay(touchTarget.overlayID, pointerEvent);
|
|
}
|
|
}
|
|
|
|
function composeTouchTargetFromIntersection(intersection) {
|
|
var isEntity = (intersection.type === Picks.INTERSECTED_ENTITY);
|
|
var objectID = intersection.objectID;
|
|
var worldPos = intersection.intersection;
|
|
var props = null;
|
|
if (isEntity) {
|
|
props = Entities.getProperties(intersection.objectID);
|
|
}
|
|
|
|
var position2D =(isEntity ? controllerDispatcher.projectOntoEntityXYPlane(objectID, worldPos, props) :
|
|
controllerDispatcher.projectOntoOverlayXYPlane(objectID, worldPos));
|
|
return {
|
|
entityID: isEntity ? objectID : null,
|
|
overlayID: isEntity ? null : objectID,
|
|
distance: intersection.distance,
|
|
position: worldPos,
|
|
position2D: position2D,
|
|
normal: intersection.surfaceNormal
|
|
};
|
|
}
|
|
|
|
// will return undefined if overlayID does not exist.
|
|
function calculateTouchTargetFromOverlay(touchTip, overlayID) {
|
|
var overlayPosition = Entities.getEntityProperties(overlayID, ["position"]).position;
|
|
if (overlayPosition === undefined) {
|
|
return;
|
|
}
|
|
|
|
// project touchTip onto overlay plane.
|
|
var overlayRotation = Entities.getEntityProperties(overlayID, ["rotation"]).rotation;
|
|
if (overlayRotation === undefined) {
|
|
return;
|
|
}
|
|
var normal = Vec3.multiplyQbyV(overlayRotation, {x: 0, y: 0, z: 1});
|
|
var distance = Vec3.dot(Vec3.subtract(touchTip.position, overlayPosition), normal);
|
|
var position = Vec3.subtract(touchTip.position, Vec3.multiply(normal, distance));
|
|
|
|
// calclulate normalized position
|
|
var invRot = Quat.inverse(overlayRotation);
|
|
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, overlayPosition));
|
|
|
|
// V8TODO: check if this is correct for entities
|
|
var dimensions = Entities.getEntityProperties(overlayID, ["dimensions"]).dimensions;
|
|
if (dimensions === undefined) {
|
|
return;
|
|
}
|
|
dimensions.z = 0.01; // we are projecting onto the XY plane of the overlay, so ignore the z dimension
|
|
var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z };
|
|
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT);
|
|
|
|
// 2D position on overlay plane in meters, relative to the bounding box upper-left hand corner.
|
|
var position2D = {
|
|
x: normalizedPosition.x * dimensions.x,
|
|
y: (1 - normalizedPosition.y) * dimensions.y // flip y-axis
|
|
};
|
|
|
|
return {
|
|
entityID: null,
|
|
overlayID: overlayID,
|
|
distance: distance,
|
|
position: position,
|
|
position2D: position2D,
|
|
normal: normal,
|
|
normalizedPosition: normalizedPosition,
|
|
dimensions: dimensions,
|
|
valid: true
|
|
};
|
|
}
|
|
|
|
// will return undefined if entity does not exist.
|
|
function calculateTouchTargetFromEntity(touchTip, props) {
|
|
if (props.rotation === undefined) {
|
|
// if rotation is missing from props object, then this entity has probably been deleted.
|
|
return;
|
|
}
|
|
|
|
// project touch tip onto entity plane.
|
|
var normal = Vec3.multiplyQbyV(props.rotation, {x: 0, y: 0, z: 1});
|
|
Vec3.multiplyQbyV(props.rotation, {x: 0, y: 1, z: 0});
|
|
var distance = Vec3.dot(Vec3.subtract(touchTip.position, props.position), normal);
|
|
var position = Vec3.subtract(touchTip.position, Vec3.multiply(normal, distance));
|
|
|
|
// generate normalized coordinates
|
|
var invRot = Quat.inverse(props.rotation);
|
|
var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, props.position));
|
|
var invDimensions = { x: 1 / props.dimensions.x, y: 1 / props.dimensions.y, z: 1 / props.dimensions.z };
|
|
var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint);
|
|
|
|
// 2D position on entity plane in meters, relative to the bounding box upper-left hand corner.
|
|
var position2D = {
|
|
x: normalizedPosition.x * props.dimensions.x,
|
|
y: (1 - normalizedPosition.y) * props.dimensions.y // flip y-axis
|
|
};
|
|
|
|
return {
|
|
entityID: props.id,
|
|
entityProps: props,
|
|
overlayID: null,
|
|
distance: distance,
|
|
position: position,
|
|
position2D: position2D,
|
|
normal: normal,
|
|
normalizedPosition: normalizedPosition,
|
|
dimensions: props.dimensions,
|
|
valid: true
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
calculateTouchTargetFromEntity: calculateTouchTargetFromEntity,
|
|
calculateTouchTargetFromOverlay: calculateTouchTargetFromOverlay,
|
|
touchTargetHasKeyboardFocus: touchTargetHasKeyboardFocus,
|
|
setKeyboardFocusOnTouchTarget: setKeyboardFocusOnTouchTarget,
|
|
sendHoverEnterEventToTouchTarget: sendHoverEnterEventToTouchTarget,
|
|
sendHoverOverEventToTouchTarget: sendHoverOverEventToTouchTarget,
|
|
sendTouchStartEventToTouchTarget: sendTouchStartEventToTouchTarget,
|
|
sendTouchEndEventToTouchTarget: sendTouchEndEventToTouchTarget,
|
|
sendTouchMoveEventToTouchTarget: sendTouchMoveEventToTouchTarget,
|
|
composeTouchTargetFromIntersection: composeTouchTargetFromIntersection
|
|
};
|