mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 19:52:46 +02:00
509 lines
24 KiB
JavaScript
509 lines
24 KiB
JavaScript
//
|
|
// Created by Luis Cuenca on 11/14/19
|
|
// Copyright 2019 High Fidelity, Inc.
|
|
//
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
(function() {
|
|
var ZoomStatus = {
|
|
"zoomingIn" : 0, // The camera is moving towards the selected entity
|
|
"zoomingOut" : 1, // The camera is moving away from the selected entity
|
|
"zoomedIn" : 2, // The camera is locked looking at the selected entity
|
|
"zoomedOut" : 4, // The camera is on its initial position and mode
|
|
"consumed" : 5 // The zooming loop has been completed
|
|
}
|
|
|
|
var FocusType = {
|
|
"avatar" : 0,
|
|
"entity" : 1
|
|
}
|
|
|
|
var EasingFunctions = {
|
|
easeInOutQuad: function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t },
|
|
// accelerating from zero velocity
|
|
easeInCubic: function (t) { return t*t*t },
|
|
// decelerating to zero velocity
|
|
easeOutCubic: function (t) { return (--t)*t*t+1 },
|
|
// acceleration until halfway, then deceleration
|
|
easeInOutCubic: function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 },
|
|
// accelerating from zero velocity
|
|
easeInQuart: function (t) { return t*t*t*t },
|
|
// decelerating to zero velocity
|
|
easeOutQuart: function (t) { return 1-(--t)*t*t*t },
|
|
// acceleration until halfway, then deceleration
|
|
easeInOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t },
|
|
// accelerating from zero velocity
|
|
easeInQuint: function (t) { return t*t*t*t*t },
|
|
// decelerating to zero velocity
|
|
easeOutQuint: function (t) { return 1+(--t)*t*t*t*t },
|
|
// acceleration until halfway, then deceleration
|
|
easeInOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t }
|
|
};
|
|
// Class that manages the zoom effect
|
|
var ZoomData = function(type, lookAt, focusNormal, focusDimensions, velocity, maxDuration) {
|
|
var self = this;
|
|
|
|
this.focusType = type;
|
|
this.lookAt = lookAt; // Look at 3d point in world coordinates
|
|
this.focusDimensions = focusDimensions; // 2d dimensions of the bounding box projection approximation of the selected entity
|
|
this.focusNormal = focusNormal; // The normal vector provided by the ray intersection used to initialize the zoom
|
|
this.velocity = velocity; // Max velocity of the camera zoom effect
|
|
this.maxDuration = maxDuration; // Max duration of the camera zoom effect
|
|
|
|
this.initialPos = Camera.getPosition();
|
|
this.initialRot = Camera.getOrientation();
|
|
this.interpolatedPos = this.initialPos;
|
|
this.interpolatedRot = this.initialRot;
|
|
this.initialMode = Camera.mode;
|
|
this.initialOffset = Vec3.distance(self.initialPos, MyAvatar.getDefaultEyePosition()); // Save the offset distance from the camera to the avatar eyes (boom)
|
|
|
|
this.finalPos = Vec3.ZERO;
|
|
this.finalRot = Quat.IDENTITY;
|
|
this.direction = Vec3.ZERO; // Direction vector for the camera path
|
|
this.distance = Vec3.ZERO; // Total distance that the camera needs to cover to zoom in along the path
|
|
this.totalTime = 0.0; // Total time needed to cover the zoom path
|
|
this.elapsedTime = 0.0;
|
|
|
|
var MAX_ZOOM_IN_AMOUNT = 0.6; // Maximum percentage of camera proximity to the selected entity from the look at point
|
|
var MAX_ZOOM_OUT_AMOUNT = 0.2; // Maximum percentage of camera remoteness to the selected entity from the look at point
|
|
|
|
this.maxZoomInAmount = MAX_ZOOM_IN_AMOUNT;
|
|
this.maxZoomOutAmount = MAX_ZOOM_OUT_AMOUNT;
|
|
this.currentZoomAmount = 0.0;
|
|
|
|
this.zoomPanOffset = {x: 0.5 * Window.innerWidth, y: 0.5 * Window.innerHeight};
|
|
this.zoomPanDelta = {x: 0.0, y: 0.0};
|
|
|
|
this.status = ZoomStatus.zoomedOut;
|
|
|
|
var OWN_CAMERA_CHANGE_MAX_FRAMES = 30;
|
|
this.ownCameraChangeElapseTime = 0.0; // Variables used to track if the camera mode change is triggered by this script
|
|
this.ownCameraChange = false; // or by user input, since the later needs to abort the zoom loop
|
|
|
|
|
|
// Function called when the user release the mouse while panning the camera when using the secondary zoom
|
|
this.applyZoomPan = function() {
|
|
self.zoomPanOffset.x += self.zoomPanDelta.x;
|
|
self.zoomPanOffset.y += self.zoomPanDelta.y;
|
|
}
|
|
|
|
// Function called when the user moves the mouse while panning the camera when using the secondary zoom
|
|
this.setZoomPanDelta = function(x, y) {
|
|
self.zoomPanDelta.x = x;
|
|
self.zoomPanDelta.y = y;
|
|
var totalX = self.zoomPanOffset.x + self.zoomPanDelta.x;
|
|
var totalY = self.zoomPanOffset.y + self.zoomPanDelta.y;
|
|
totalX = Math.min(Math.max(totalX, 0.0), Window.innerWidth);
|
|
totalY = Math.min(Math.max(totalY, 0.0), Window.innerHeight);
|
|
self.zoomPanDelta.x = totalX - self.zoomPanOffset.x;
|
|
self.zoomPanDelta.y = totalY - self.zoomPanOffset.y;
|
|
self.updateSuperPan(totalX, totalY);
|
|
}
|
|
|
|
// This function computes the correct distance to the selected entity so it ends up fitted on the screen
|
|
this.getFocusDistance = function(zoomDims) {
|
|
var objAspect = zoomDims.x / zoomDims.y;
|
|
var camAspect = Camera.frustum.aspectRatio;
|
|
var m = 0.0;
|
|
if (objAspect < camAspect) {
|
|
m = zoomDims.y;
|
|
} else {
|
|
m = zoomDims.x / camAspect;
|
|
}
|
|
var DEGREE_TO_RADIAN = 0.0174533;
|
|
var fov = DEGREE_TO_RADIAN * Camera.frustum.fieldOfView;
|
|
return (0.5 * m) / Math.tan(0.5 * fov);
|
|
}
|
|
|
|
// This function computes the final camera position and rotation
|
|
this.computeFinalForm = function() {
|
|
self.finalPos = Vec3.sum(self.lookAt, Vec3.multiply(self.getFocusDistance(self.focusDimensions), self.focusNormal));
|
|
self.finalRot = Quat.lookAtSimple(self.finalPos, self.lookAt);
|
|
}
|
|
|
|
// Function that computes the time and path information for the camera zoom in
|
|
this.computeRouteIn = function() {
|
|
var railVector = Vec3.subtract(self.finalPos, self.initialPos);
|
|
self.direction = Vec3.normalize(railVector);
|
|
self.distance = Vec3.length(railVector);
|
|
self.totalTime = self.distance / self.velocity;
|
|
self.totalTime = self.totalTime > self.maxDuration ? self.maxDuration : self.totalTime;
|
|
}
|
|
|
|
// Function that computes the time and path information for the camera zoom out
|
|
// Since the camera orientation and position gets reset when changing camera modes,
|
|
// the camera path while zooming out is different from the path zooming in.
|
|
this.computeRouteOut = function() {
|
|
self.finalPos = Camera.getPosition();
|
|
var camOffset = Vec3.ZERO;
|
|
var myAvatarRotation = MyAvatar.orientation;
|
|
if (self.initialMode.indexOf("first") != -1) {
|
|
self.initialRot = myAvatarRotation;
|
|
} else {
|
|
var lookAtPoint = MyAvatar.getDefaultEyePosition();
|
|
var lookFromSign = self.initialMode.indexOf("selfie") != -1 ? 1 : -1;
|
|
var lookFromPoint = Vec3.sum(lookAtPoint, Vec3.multiply(self.initialOffset * lookFromSign, Quat.getFront(myAvatarRotation)));
|
|
self.initialRot = Quat.lookAtSimple(lookFromPoint, lookAtPoint);
|
|
self.initialPos = lookFromPoint;
|
|
}
|
|
self.computeRouteIn();
|
|
}
|
|
|
|
// This function initiate the camera zoom in
|
|
this.initZoomIn = function() {
|
|
if (self.status === ZoomStatus.zoomedOut) {
|
|
self.computeRouteIn();
|
|
self.status = ZoomStatus.zoomingIn;
|
|
self.changeCameraMode("independent");
|
|
self.elapsedTime = 0.0;
|
|
}
|
|
}
|
|
|
|
// This function initiate the camera zoom in
|
|
this.initZoomOut = function() {
|
|
if (self.status === ZoomStatus.zoomedIn) {
|
|
self.computeRouteOut();
|
|
self.status = ZoomStatus.zoomingOut;
|
|
self.changeCameraMode("independent");
|
|
self.elapsedTime = 0.0;
|
|
}
|
|
}
|
|
|
|
// This function checks if the zoom loop needs update
|
|
this.needsUpdate = function() {
|
|
return self.status === ZoomStatus.zoomingIn || self.status === ZoomStatus.zoomingOut;
|
|
}
|
|
|
|
// This function connects to the update signal only when zoom in or zoom out is needed
|
|
this.updateZoom = function(deltaTime) {
|
|
if (self.ownCameraChange) {
|
|
self.ownCameraChange = self.ownCameraChangeElapseTime < OWN_CAMERA_CHANGE_MAX_FRAMES * deltaTime;
|
|
self.ownCameraChangeElapseTime += deltaTime;
|
|
}
|
|
if (!self.needsUpdate) {
|
|
return;
|
|
}
|
|
if (self.elapsedTime < self.totalTime) {
|
|
var ratio = EasingFunctions.easeInOutQuart(self.elapsedTime / self.totalTime);
|
|
|
|
if (self.status === ZoomStatus.zoomingIn) {
|
|
var curDist = self.distance * ratio;
|
|
var addition = Vec3.multiply(curDist, self.direction);
|
|
self.interpolatedPos = Vec3.sum(self.initialPos, addition);
|
|
self.interpolatedRot = Quat.mix(self.initialRot, self.finalRot, ratio);
|
|
} else if (self.status === ZoomStatus.zoomingOut) {
|
|
self.interpolatedPos = Vec3.sum(self.finalPos, Vec3.multiply(self.distance * ratio, Vec3.multiply(-1, self.direction)));
|
|
self.interpolatedRot = Quat.mix(self.finalRot, self.initialRot, ratio);
|
|
}
|
|
self.elapsedTime += deltaTime;
|
|
Camera.setPosition(self.interpolatedPos);
|
|
Camera.setOrientation(self.interpolatedRot);
|
|
} else {
|
|
Camera.setPosition(self.finalPos);
|
|
Camera.setOrientation(self.finalRot);
|
|
if (self.status === ZoomStatus.zoomingIn) {
|
|
self.status = ZoomStatus.zoomedIn;
|
|
} else if (self.status === ZoomStatus.zoomingOut) {
|
|
self.status = ZoomStatus.consumed;
|
|
self.changeCameraMode(self.initialMode);
|
|
}
|
|
}
|
|
}
|
|
|
|
// This function recomputes the camera distance to the selected item in order to fit it on the screen
|
|
this.resetZoomAspect = function() {
|
|
self.computeFinalForm();
|
|
self.computeRouteIn();
|
|
Camera.setPosition(self.finalPos);
|
|
}
|
|
|
|
// This function updates the secondary zoom distance to the selected entity according to the mouse wheel event
|
|
this.updateSuperZoom = function(delta) {
|
|
var ZOOM_STEP = 0.1;
|
|
self.currentZoomAmount = self.currentZoomAmount + (delta < 0.0 ? -1 : 1) * ZOOM_STEP;
|
|
self.currentZoomAmount = Math.min(Math.max(self.currentZoomAmount, -self.maxZoomOutAmount), self.maxZoomInAmount);
|
|
self.updateSuperPan(self.zoomPanOffset.x, self.zoomPanOffset.y);
|
|
}
|
|
|
|
// This function updates the secondary zoom panning according to the mouse move event
|
|
this.updateSuperPan = function(x, y) {
|
|
var zoomOffset = Vec3.multiply(self.currentZoomAmount, Vec3.subtract(self.lookAt, self.finalPos));
|
|
var xRatio = 0.5 - x / Window.innerWidth;
|
|
var yRatio = 0.5 - y / Window.innerHeight;
|
|
var cameraOrientation = Camera.getOrientation();
|
|
var cameraY = Quat.getUp(cameraOrientation);
|
|
var cameraX = Vec3.multiply(-1, Quat.getRight(cameraOrientation));
|
|
var xOffset = Vec3.multiply(xRatio * self.focusDimensions.x, cameraX);
|
|
var yOffset = Vec3.multiply(yRatio * self.focusDimensions.y, cameraY);
|
|
zoomOffset = Vec3.sum(zoomOffset, xOffset);
|
|
zoomOffset = Vec3.sum(zoomOffset, yOffset);
|
|
Camera.setPosition(Vec3.sum(self.finalPos, zoomOffset));
|
|
}
|
|
|
|
// This function aborts the zoom loop when the user changes the camera mode
|
|
this.abort = function() {
|
|
self.changeCameraMode(self.initialMode);
|
|
}
|
|
|
|
// This function changes the camera mode
|
|
this.changeCameraMode = function(mode) {
|
|
self.ownCameraChange = true;
|
|
self.ownCameraChangeElapseTime = 0.0;
|
|
Camera.mode = mode;
|
|
}
|
|
|
|
this.computeFinalForm();
|
|
}
|
|
|
|
// Class that manages the mouse events and computes the 3d structure data of the selected entity or avatar
|
|
var ZoomOnAnything = function() {
|
|
var self = this;
|
|
this.zoomEntityData; // The selected entity's data
|
|
this.zoomCameraPos;
|
|
var ZOOM_MAX_VELOCITY = 15.0; // meters per second
|
|
var ZOOM_MAX_DURATION = 1.0; // seconds
|
|
this.zoomDelta = {x: 0.0, y: 0.0}; // mouse move delta while panning
|
|
this.isPanning = false;
|
|
this.screenPointRef = {x: 0.0, y: 0.0}; // Screen pixels reference used to compute the zoomDelta
|
|
this.connected = false;
|
|
|
|
// This function estimates the projection axis and the dimensions along that axis of the selected entity
|
|
this.getEntityDimsFromNormal = function(dims, rot, normal) {
|
|
var zoomXNormal = Vec3.multiplyQbyV(rot, Vec3.UNIT_X);
|
|
var zoomYNormal = Vec3.multiplyQbyV(rot, Vec3.UNIT_Y);
|
|
var zoomZNormal = Vec3.multiplyQbyV(rot, Vec3.UNIT_Z);
|
|
var affinities = [
|
|
{axis: "x", normal: zoomXNormal, affin: Math.abs(Vec3.dot(zoomXNormal, normal)), dims: {x: dims.z, y: dims.y}},
|
|
{axis: "y", normal: zoomYNormal, affin: Math.abs(Vec3.dot(zoomYNormal, normal)), dims: {x: dims.x, y: dims.z}},
|
|
{axis: "z", normal: zoomZNormal, affin: Math.abs(Vec3.dot(zoomZNormal, normal)), dims: {x: dims.x, y: dims.y}}
|
|
];
|
|
affinities.sort(function(a, b) {
|
|
return b.affin - a.affin;
|
|
});
|
|
return affinities[0];
|
|
}
|
|
|
|
// This function estimates the appropriate focus point when the selected entity is an avatar
|
|
this.getAvatarFocusPoint = function(avatar) {
|
|
var rEyeIndex = avatar.getJointIndex("RightEye");
|
|
var lEyeIndex = avatar.getJointIndex("LeftEye");
|
|
var headIndex = avatar.getJointIndex("Head");
|
|
var focusPoint = Vec3.ZERO;
|
|
var validPoint = false;
|
|
var count = 0;
|
|
if (rEyeIndex != -1) {
|
|
focusPoint = Vec3.sum(focusPoint, avatar.getJointPosition(rEyeIndex));
|
|
validPoint = true;
|
|
count++;
|
|
}
|
|
if (lEyeIndex != -1) {
|
|
var leftEyePos = avatar.getJointPosition(lEyeIndex);
|
|
var NORMAL_EYE_DISTANCE = 0.1;
|
|
focusPoint = Vec3.sum(focusPoint, leftEyePos);
|
|
validPoint = true;
|
|
count++;
|
|
}
|
|
if (headIndex != -1) {
|
|
focusPoint = Vec3.sum(focusPoint, avatar.getJointPosition(headIndex));
|
|
validPoint = true;
|
|
count++;
|
|
}
|
|
if (!validPoint) {
|
|
focusPoint = avatar.getJointPosition("Hips");
|
|
count++;
|
|
}
|
|
return Vec3.multiply(1.0/count, focusPoint);
|
|
}
|
|
|
|
// This function sets the data needed to zoom in on an avatar
|
|
this.getZoomDataFromAvatar = function(avatarID, skinToBoneDist, zoomVelocity, maxDuration) {
|
|
var headDiam = 2.0 * skinToBoneDist; // Head diameter is estimated based on the distance to the bone
|
|
headDiam = headDiam < 0.5 ? 0.5 : headDiam;
|
|
var avatar = AvatarList.getAvatar(avatarID);
|
|
var focusPoint = self.getAvatarFocusPoint(avatar);
|
|
var focusDims = {x: headDiam, y: headDiam};
|
|
var focusNormal = Quat.getFront(avatar.orientation);
|
|
var zoomData = new ZoomData(FocusType.avatar, focusPoint, focusNormal, focusDims, zoomVelocity, maxDuration);
|
|
return zoomData;
|
|
}
|
|
|
|
// This function sets the data needed to zoom in on an entity
|
|
this.getZoomDataFromEntity = function(intersection, objectProps, zoomVelocity, maxDuration) {
|
|
var position = objectProps.position;
|
|
var dimensions = objectProps.dimensions;
|
|
var rotation = objectProps.rotation;
|
|
var focusNormal = intersection.surfaceNormal;
|
|
var dimsResult = self.getEntityDimsFromNormal(dimensions, rotation, focusNormal);
|
|
var focusDims = dimsResult.dims;
|
|
var focusDepth = Vec3.dot(Vec3.subtract(intersection.intersection, position), dimsResult.normal);
|
|
var newPosition = Vec3.sum(position, Vec3.multiply(focusDepth, dimsResult.normal));
|
|
var zoomData = new ZoomData(FocusType.entity, newPosition, focusNormal, focusDims, zoomVelocity, maxDuration);
|
|
return zoomData;
|
|
}
|
|
|
|
// This function initiate the zoom loop on the selected entity
|
|
this.zoomOnEntity = function(intersection, objectProps) {
|
|
self.zoomEntityData = self.getZoomDataFromEntity(intersection, objectProps, ZOOM_MAX_VELOCITY, ZOOM_MAX_DURATION);
|
|
self.zoomEntityData.initZoomIn();
|
|
}
|
|
|
|
// This function initiates the zoom loop on the selected avatar
|
|
this.zoomOnAvatar = function(avatarID, skinToBoneDist) {
|
|
self.zoomEntityData = self.getZoomDataFromAvatar(avatarID, skinToBoneDist, ZOOM_MAX_VELOCITY, ZOOM_MAX_DURATION);
|
|
self.zoomEntityData.initZoomIn();
|
|
}
|
|
|
|
// This function connects to the Script.update signal
|
|
this.connect = function() {
|
|
self.connected = true;
|
|
Script.update.connect(self.updateZoom);
|
|
}
|
|
|
|
// This function disconnects to the Script.update signal
|
|
this.disconnect = function() {
|
|
self.connected = false;
|
|
Script.update.disconnect(self.updateZoom);
|
|
}
|
|
|
|
// This function get connected to the Script.update signal
|
|
this.updateZoom = function(deltaTime) {
|
|
if (self.zoomEntityData) {
|
|
if (self.zoomEntityData.needsUpdate()) {
|
|
self.zoomEntityData.updateZoom(deltaTime);
|
|
if (self.zoomEntityData.status === ZoomStatus.consumed) {
|
|
self.disconnect();
|
|
self.zoomEntityData = undefined;
|
|
}
|
|
} else {
|
|
self.disconnect();
|
|
}
|
|
} else if (self.connected) {
|
|
self.disconnect();
|
|
}
|
|
}
|
|
|
|
// This function listen to the mouse double click that evaluates the selected entity and the intersection data that initiates the zoom loop
|
|
this.mouseDoublePressEvent = function(event) {
|
|
if (event.isLeftButton) {
|
|
self.connect();
|
|
if (!self.zoomEntityData) {
|
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
|
var intersection = AvatarManager.findRayIntersection({origin: pickRay.origin, direction: pickRay.direction}, [], [MyAvatar.sessionUUID], false);
|
|
if (!intersection.intersects) {
|
|
intersection = Entities.findRayIntersection({origin: pickRay.origin, direction: pickRay.direction}, true);
|
|
var entityProps = Entities.getEntityProperties(intersection.entityID);
|
|
if (entityProps.type === "Shape") {
|
|
var FIND_SHAPES_DISTANCE = 10.0;
|
|
var shapes = Entities.findEntitiesByType("Shape", intersection.intersection, FIND_SHAPES_DISTANCE);
|
|
intersection = Entities.findRayIntersection({origin: pickRay.origin, direction: pickRay.direction}, true, [], shapes);
|
|
entityProps = Entities.getEntityProperties(intersection.entityID);
|
|
}
|
|
if (!entityProps.dimensions) {
|
|
return;
|
|
}
|
|
self.zoomOnEntity(intersection, entityProps);
|
|
} else {
|
|
var avatar = AvatarList.getAvatar(intersection.avatarID);
|
|
var skinToBoneDist = Vec3.distance(intersection.intersection, avatar.getJointPosition(intersection.jointIndex));
|
|
self.zoomOnAvatar(intersection.avatarID, skinToBoneDist);
|
|
}
|
|
} else if (!self.zoomEntityData.needsUpdate()){
|
|
self.zoomEntityData.initZoomOut();
|
|
}
|
|
}
|
|
}
|
|
|
|
// This function listen to the mouse press event to initiate panning while on secondary zoom
|
|
this.mousePressEvent = function(event) {
|
|
if (event.isRightButton) {
|
|
self.isPanning = true;
|
|
self.screenPointRef = {x: event.x, y: event.y};
|
|
}
|
|
}
|
|
|
|
// This function listen to the mouse release event to apply the pan delta while on secondary zoom
|
|
this.mouseReleaseEvent = function(event) {
|
|
if (event.isRightButton) {
|
|
if (self.zoomEntityData) {
|
|
self.zoomEntityData.applyZoomPan();
|
|
self.isPanning = false;
|
|
self.screenPointRef = {x: 0, y: 0};
|
|
}
|
|
}
|
|
}
|
|
|
|
// This function listen to the mouse move event to modify the pan delta coordenates while on secondary zoom
|
|
this.mouseMoveEvent = function(event) {
|
|
if (event.isRightButton) {
|
|
if (self.isPanning && self.zoomEntityData) {
|
|
self.zoomEntityData.setZoomPanDelta(event.x - self.screenPointRef.x, event.y - self.screenPointRef.y);
|
|
}
|
|
}
|
|
}
|
|
|
|
// This function listen to the mouse wheel event to modify the ammount of secondary zoom
|
|
this.mouseWheel = function(event) {
|
|
if (self.zoomEntityData) {
|
|
self.zoomEntityData.updateSuperZoom(event.delta);
|
|
}
|
|
}
|
|
|
|
// This function aborts the zoom loop
|
|
this.abort = function() {
|
|
self.zoomEntityData.abort();
|
|
self.zoomEntityData = undefined;
|
|
if (self.connected) {
|
|
self.disconnect();
|
|
}
|
|
}
|
|
|
|
// This function refits the selected entity on the screen when the screen dimensions change
|
|
this.geometryChanged = function() {
|
|
if (self.zoomEntityData !== undefined){
|
|
self.zoomEntityData.resetZoomAspect();
|
|
}
|
|
}
|
|
|
|
// This function aborts the zoom loop if the camera mode is set by the user
|
|
this.modeUpdated = function(mode) {
|
|
if (self.zoomEntityData && !self.zoomEntityData.ownCameraChange) {
|
|
self.abort();
|
|
}
|
|
}
|
|
|
|
// This function initiate the connections
|
|
this.init = function() {
|
|
// Connect signals
|
|
Window.geometryChanged.connect(self.geometryChanged);
|
|
Camera.modeUpdated.connect(self.modeUpdated);
|
|
Controller.mousePressEvent.connect(self.mousePressEvent);
|
|
Controller.mouseDoublePressEvent.connect(self.mouseDoublePressEvent);
|
|
Controller.mouseMoveEvent.connect(self.mouseMoveEvent);
|
|
Controller.mouseReleaseEvent.connect(self.mouseReleaseEvent);
|
|
Controller.wheelEvent.connect(self.mouseWheel);
|
|
}
|
|
|
|
// This function finish the connections
|
|
this.scriptEnding = function() {
|
|
// Disconnect on exit
|
|
Window.geometryChanged.disconnect(self.geometryChanged);
|
|
Camera.modeUpdated.disconnect(self.modeUpdated);
|
|
Controller.mousePressEvent.disconnect(self.mousePressEvent);
|
|
Controller.mouseDoublePressEvent.disconnect(self.mouseDoublePressEvent);
|
|
Controller.mouseMoveEvent.disconnect(self.mouseMoveEvent);
|
|
Controller.mouseReleaseEvent.disconnect(self.mouseReleaseEvent);
|
|
Controller.wheelEvent.disconnect(self.mouseWheel);
|
|
if (self.zoomEntityData) {
|
|
self.abort();
|
|
}
|
|
}
|
|
}
|
|
|
|
var zoomOE = new ZoomOnAnything();
|
|
zoomOE.init();
|
|
Script.scriptEnding.connect(zoomOE.scriptEnding);
|
|
|
|
})();
|