mirror of
https://github.com/overte-org/overte.git
synced 2025-08-14 14:07:59 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels
This commit is contained in:
commit
c65af33a6c
13 changed files with 650 additions and 97 deletions
|
@ -5,6 +5,19 @@
|
|||
// Created by Clément Brisset on 4/24/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// This script allows you to edit models either with the razor hydras or with your mouse
|
||||
//
|
||||
// If using the hydras :
|
||||
// grab grab models with the triggers, you can then move the models around or scale them with both hands.
|
||||
// You can switch mode using the bumpers so that you can move models roud more easily.
|
||||
//
|
||||
// If using the mouse :
|
||||
// - left click lets you move the model in the plane facing you.
|
||||
// If pressing shift, it will move on the horizontale plane it's in.
|
||||
// - right click lets you rotate the model. z and x give you access to more axix of rotation while shift allows for finer control.
|
||||
// - left + right click lets you scale the model.
|
||||
// - you can press r while holding the model to reset its rotation
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
@ -21,6 +34,8 @@ var LASER_COLOR = { red: 255, green: 0, blue: 0 };
|
|||
var LASER_LENGTH_FACTOR = 500
|
||||
;
|
||||
|
||||
var MAX_ANGULAR_SIZE = 45;
|
||||
|
||||
var LEFT = 0;
|
||||
var RIGHT = 1;
|
||||
|
||||
|
@ -263,6 +278,11 @@ function controller(wichSide) {
|
|||
var d = Vec3.length(Vec3.subtract(P, X));
|
||||
|
||||
if (0 < x && x < LASER_LENGTH_FACTOR) {
|
||||
if (2 * Math.atan(properties.radius / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14 > MAX_ANGULAR_SIZE) {
|
||||
print("Angular size too big: " + 2 * Math.atan(properties.radius / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14);
|
||||
return { valid: false };
|
||||
}
|
||||
|
||||
return { valid: true, x: x, y: y, z: z };
|
||||
}
|
||||
return { valid: false };
|
||||
|
@ -513,9 +533,13 @@ function controller(wichSide) {
|
|||
if (isLocked(newProperties)) {
|
||||
print("Model locked " + newProperties.id);
|
||||
} else {
|
||||
var check = this.checkModel(newProperties);
|
||||
if (!check.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.grab(newModel, newProperties);
|
||||
|
||||
var check = this.checkModel(newProperties);
|
||||
this.x = check.x;
|
||||
this.y = check.y;
|
||||
this.z = check.z;
|
||||
|
@ -653,16 +677,18 @@ function initToolBar() {
|
|||
}
|
||||
|
||||
function moveOverlays() {
|
||||
var newViewPort = Controller.getViewportDimensions();
|
||||
|
||||
if (typeof(toolBar) === 'undefined') {
|
||||
initToolBar();
|
||||
|
||||
} else if (windowDimensions.x == Controller.getViewportDimensions().x &&
|
||||
windowDimensions.y == Controller.getViewportDimensions().y) {
|
||||
} else if (windowDimensions.x == newViewPort.x &&
|
||||
windowDimensions.y == newViewPort.y) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
windowDimensions = Controller.getViewportDimensions();
|
||||
windowDimensions = newViewPort;
|
||||
var toolsX = windowDimensions.x - 8 - toolBar.width;
|
||||
var toolsY = (windowDimensions.y - toolBar.height) / 2;
|
||||
|
||||
|
@ -680,8 +706,6 @@ var intersection;
|
|||
|
||||
|
||||
var SCALE_FACTOR = 200.0;
|
||||
var TRANSLATION_FACTOR = 100.0;
|
||||
var ROTATION_FACTOR = 100.0;
|
||||
|
||||
function rayPlaneIntersection(pickRay, point, normal) {
|
||||
var d = -Vec3.dot(point, normal);
|
||||
|
@ -690,8 +714,50 @@ function rayPlaneIntersection(pickRay, point, normal) {
|
|||
return Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, t));
|
||||
}
|
||||
|
||||
function Tooltip() {
|
||||
this.x = 285;
|
||||
this.y = 115;
|
||||
this.width = 110;
|
||||
this.height = 115 ;
|
||||
this.margin = 5;
|
||||
this.decimals = 3;
|
||||
|
||||
this.textOverlay = Overlays.addOverlay("text", {
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
margin: this.margin,
|
||||
text: "",
|
||||
color: { red: 128, green: 128, blue: 128 },
|
||||
alpha: 0.2,
|
||||
visible: false
|
||||
});
|
||||
this.show = function(doShow) {
|
||||
Overlays.editOverlay(this.textOverlay, { visible: doShow });
|
||||
}
|
||||
this.updateText = function(properties) {
|
||||
var angles = Quat.safeEulerAngles(properties.modelRotation);
|
||||
var text = "Model Properties:\n"
|
||||
text += "x: " + properties.position.x.toFixed(this.decimals) + "\n"
|
||||
text += "y: " + properties.position.y.toFixed(this.decimals) + "\n"
|
||||
text += "z: " + properties.position.z.toFixed(this.decimals) + "\n"
|
||||
text += "pitch: " + angles.x.toFixed(this.decimals) + "\n"
|
||||
text += "yaw: " + angles.y.toFixed(this.decimals) + "\n"
|
||||
text += "roll: " + angles.z.toFixed(this.decimals) + "\n"
|
||||
text += "Scale: " + 2 * properties.radius.toFixed(this.decimals) + "\n"
|
||||
|
||||
Overlays.editOverlay(this.textOverlay, { text: text });
|
||||
}
|
||||
|
||||
this.cleanup = function() {
|
||||
Overlays.deleteOverlay(this.textOverlay);
|
||||
}
|
||||
}
|
||||
var tooltip = new Tooltip();
|
||||
|
||||
function mousePressEvent(event) {
|
||||
if (altIsPressed) {
|
||||
if (event.isAlt) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -760,12 +826,16 @@ function mousePressEvent(event) {
|
|||
var d = Vec3.length(Vec3.subtract(P, X));
|
||||
|
||||
if (0 < x && x < LASER_LENGTH_FACTOR) {
|
||||
modelSelected = true;
|
||||
selectedModelID = foundModel;
|
||||
selectedModelProperties = properties;
|
||||
|
||||
orientation = MyAvatar.orientation;
|
||||
intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation));
|
||||
if (2 * Math.atan(properties.radius / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14 < MAX_ANGULAR_SIZE) {
|
||||
modelSelected = true;
|
||||
selectedModelID = foundModel;
|
||||
selectedModelProperties = properties;
|
||||
|
||||
orientation = MyAvatar.orientation;
|
||||
intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation));
|
||||
} else {
|
||||
print("Angular size too big: " + 2 * Math.atan(properties.radius / Vec3.distance(Camera.getPosition(), properties.position)) * 180 / 3.14);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -786,6 +856,8 @@ function mousePressEvent(event) {
|
|||
selectedModelProperties.glowLevel = 0.0;
|
||||
|
||||
print("Clicked on " + selectedModelID.id + " " + modelSelected);
|
||||
tooltip.updateText(selectedModelProperties);
|
||||
tooltip.show(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,7 +866,7 @@ var oldModifier = 0;
|
|||
var modifier = 0;
|
||||
var wasShifted = false;
|
||||
function mouseMoveEvent(event) {
|
||||
if (altIsPressed) {
|
||||
if (event.isAlt) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -886,26 +958,54 @@ function mouseMoveEvent(event) {
|
|||
break;
|
||||
case 3:
|
||||
// Let's rotate
|
||||
var rotation = Quat.fromVec3Degrees({ x: event.y - mouseLastPosition.y, y: event.x - mouseLastPosition.x, z: 0 });
|
||||
if (event.isShifted) {
|
||||
rotation = Quat.fromVec3Degrees({ x: event.y - mouseLastPosition.y, y: 0, z: mouseLastPosition.x - event.x });
|
||||
if (somethingChanged) {
|
||||
selectedModelProperties.oldRotation.x = selectedModelProperties.modelRotation.x;
|
||||
selectedModelProperties.oldRotation.y = selectedModelProperties.modelRotation.y;
|
||||
selectedModelProperties.oldRotation.z = selectedModelProperties.modelRotation.z;
|
||||
selectedModelProperties.oldRotation.w = selectedModelProperties.modelRotation.w;
|
||||
mouseLastPosition.x = event.x;
|
||||
mouseLastPosition.y = event.y;
|
||||
somethingChanged = false;
|
||||
}
|
||||
|
||||
var newRotation = Quat.multiply(orientation, rotation);
|
||||
newRotation = Quat.multiply(newRotation, Quat.inverse(orientation));
|
||||
|
||||
selectedModelProperties.modelRotation = Quat.multiply(newRotation, selectedModelProperties.oldRotation);
|
||||
var pixelPerDegrees = windowDimensions.y / (1 * 360); // the entire height of the window allow you to make 2 full rotations
|
||||
|
||||
var STEP = 15;
|
||||
var delta = Math.floor((event.x - mouseLastPosition.x) / pixelPerDegrees);
|
||||
|
||||
if (!event.isShifted) {
|
||||
delta = Math.floor(delta / STEP) * STEP;
|
||||
}
|
||||
|
||||
var rotation = Quat.fromVec3Degrees({
|
||||
x: (!zIsPressed && xIsPressed) ? delta : 0, // z is pressed
|
||||
y: (!zIsPressed && !xIsPressed) ? delta : 0, // x is pressed
|
||||
z: (zIsPressed && !xIsPressed) ? delta : 0 // neither is pressed
|
||||
});
|
||||
rotation = Quat.multiply(selectedModelProperties.oldRotation, rotation);
|
||||
|
||||
selectedModelProperties.modelRotation.x = rotation.x;
|
||||
selectedModelProperties.modelRotation.y = rotation.y;
|
||||
selectedModelProperties.modelRotation.z = rotation.z;
|
||||
selectedModelProperties.modelRotation.w = rotation.w;
|
||||
break;
|
||||
}
|
||||
|
||||
Models.editModel(selectedModelID, selectedModelProperties);
|
||||
tooltip.updateText(selectedModelProperties);
|
||||
}
|
||||
|
||||
|
||||
function mouseReleaseEvent(event) {
|
||||
if (altIsPressed) {
|
||||
if (event.isAlt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (modelSelected) {
|
||||
tooltip.show(false);
|
||||
}
|
||||
|
||||
modelSelected = false;
|
||||
|
||||
glowedModelID.id = -1;
|
||||
|
@ -943,6 +1043,7 @@ function scriptEnding() {
|
|||
rightController.cleanup();
|
||||
toolBar.cleanup();
|
||||
cleanupModelMenus();
|
||||
tooltip.cleanup();
|
||||
}
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
||||
|
@ -974,16 +1075,36 @@ Menu.menuItemEvent.connect(function(menuItem){
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
// handling of inspect.js concurrence
|
||||
altIsPressed = false;
|
||||
var zIsPressed = false;
|
||||
var xIsPressed = false;
|
||||
var somethingChanged = false;
|
||||
Controller.keyPressEvent.connect(function(event) {
|
||||
if (event.text == "ALT") {
|
||||
altIsPressed = true;
|
||||
if ((event.text == "z" || event.text == "Z") && !zIsPressed) {
|
||||
zIsPressed = true;
|
||||
somethingChanged = true;
|
||||
}
|
||||
if ((event.text == "x" || event.text == "X") && !xIsPressed) {
|
||||
xIsPressed = true;
|
||||
somethingChanged = true;
|
||||
}
|
||||
|
||||
// resets model orientation when holding with mouse
|
||||
if (event.text == "r" && modelSelected) {
|
||||
selectedModelProperties.modelRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 0 });
|
||||
Models.editModel(selectedModelID, selectedModelProperties);
|
||||
tooltip.updateText(selectedModelProperties);
|
||||
somethingChanged = true;
|
||||
}
|
||||
});
|
||||
Controller.keyReleaseEvent.connect(function(event) {
|
||||
if (event.text == "ALT") {
|
||||
altIsPressed = false;
|
||||
if (event.text == "z" || event.text == "Z") {
|
||||
zIsPressed = false;
|
||||
somethingChanged = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (event.text == "x" || event.text == "X") {
|
||||
xIsPressed = false;
|
||||
somethingChanged = true;
|
||||
}
|
||||
});
|
119
examples/myBalance.js
Normal file
119
examples/myBalance.js
Normal file
|
@ -0,0 +1,119 @@
|
|||
//
|
||||
// myBalance.js
|
||||
// examples
|
||||
//
|
||||
// Created by Stojce Slavkovski on June 5, 2014
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Show wallet ₵ balance
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
var Controller = Controller || {};
|
||||
var Overlays = Overlays || {};
|
||||
var Script = Script || {};
|
||||
var Account = Account || {};
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
var iconUrl = 'http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/',
|
||||
overlayWidth = 150,
|
||||
overlayHeight = 50,
|
||||
overlayTopOffset = 15,
|
||||
overlayRightOffset = 140,
|
||||
textRightOffset = 105,
|
||||
maxIntegers = 5,
|
||||
downColor = {
|
||||
red: 0,
|
||||
green: 0,
|
||||
blue: 255
|
||||
},
|
||||
upColor = {
|
||||
red: 0,
|
||||
green: 255,
|
||||
blue: 0
|
||||
},
|
||||
normalColor = {
|
||||
red: 204,
|
||||
green: 204,
|
||||
blue: 204
|
||||
},
|
||||
balance = -1,
|
||||
walletBox = Overlays.addOverlay("image", {
|
||||
x: 0,
|
||||
y: overlayTopOffset,
|
||||
width: 122,
|
||||
height: 32,
|
||||
imageURL: iconUrl + "wallet.svg",
|
||||
alpha: 1
|
||||
}),
|
||||
textOverlay = Overlays.addOverlay("text", {
|
||||
x: 0,
|
||||
y: overlayTopOffset,
|
||||
topMargin: 10,
|
||||
font: {
|
||||
size: 16
|
||||
},
|
||||
color: normalColor
|
||||
});
|
||||
|
||||
function scriptEnding() {
|
||||
Overlays.deleteOverlay(walletBox);
|
||||
Overlays.deleteOverlay(textOverlay);
|
||||
}
|
||||
|
||||
function update(deltaTime) {
|
||||
var xPos = Controller.getViewportDimensions().x;
|
||||
Overlays.editOverlay(walletBox, {
|
||||
x: xPos - overlayRightOffset,
|
||||
visible: Account.isLoggedIn()
|
||||
});
|
||||
|
||||
Overlays.editOverlay(textOverlay, {
|
||||
x: xPos - textRightOffset,
|
||||
visible: Account.isLoggedIn()
|
||||
});
|
||||
}
|
||||
|
||||
function formatedBalance() {
|
||||
var integers = balance.toFixed(0).length,
|
||||
decimals = Math.abs(maxIntegers - integers) + 2;
|
||||
|
||||
var x = balance.toFixed(decimals).split('.'),
|
||||
x1 = x[0],
|
||||
x2 = x.length > 1 ? '.' + x[1] : '';
|
||||
var rgx = /(\d+)(\d{3})/;
|
||||
while (rgx.test(x1)) {
|
||||
x1 = x1.replace(rgx, '$1' + ',' + '$2');
|
||||
}
|
||||
return x1 + x2;
|
||||
}
|
||||
|
||||
function updateBalance(newBalance) {
|
||||
if (balance === newBalance) {
|
||||
return;
|
||||
}
|
||||
|
||||
var change = newBalance - balance,
|
||||
textColor = change < 0 ? downColor : upColor;
|
||||
|
||||
balance = newBalance;
|
||||
Overlays.editOverlay(textOverlay, {
|
||||
text: formatedBalance(),
|
||||
color: textColor
|
||||
});
|
||||
|
||||
Script.setTimeout(function () {
|
||||
Overlays.editOverlay(textOverlay, {
|
||||
color: normalColor
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
updateBalance(Account.getBalance());
|
||||
Account.balanceChanged.connect(updateBalance);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
Script.update.connect(update);
|
||||
}());
|
|
@ -73,6 +73,7 @@
|
|||
#include "devices/TV3DManager.h"
|
||||
#include "renderer/ProgramObject.h"
|
||||
|
||||
#include "scripting/AccountScriptingInterface.h"
|
||||
#include "scripting/AudioDeviceScriptingInterface.h"
|
||||
#include "scripting/ClipboardScriptingInterface.h"
|
||||
#include "scripting/MenuScriptingInterface.h"
|
||||
|
@ -654,7 +655,14 @@ void Application::paintGL() {
|
|||
|
||||
{
|
||||
PerformanceTimer perfTimer("paintGL/renderOverlay");
|
||||
_applicationOverlay.renderOverlay();
|
||||
//If alpha is 1, we can render directly to the screen.
|
||||
if (_applicationOverlay.getAlpha() == 1.0f) {
|
||||
_applicationOverlay.renderOverlay();
|
||||
} else {
|
||||
//Render to to texture so we can fade it
|
||||
_applicationOverlay.renderOverlay(true);
|
||||
_applicationOverlay.displayOverlayTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3572,6 +3580,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
|
|||
scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance());
|
||||
scriptEngine->registerGlobalObject("AnimationCache", &_animationCache);
|
||||
scriptEngine->registerGlobalObject("AudioReflector", &_audioReflector);
|
||||
scriptEngine->registerGlobalObject("Account", AccountScriptingInterface::getInstance());
|
||||
|
||||
QThread* workerThread = new QThread(this);
|
||||
|
||||
|
|
|
@ -341,8 +341,9 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
|
|||
|
||||
//Injecting mouse movements and clicks
|
||||
void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
||||
MyAvatar* avatar = Application::getInstance()->getAvatar();
|
||||
QGLWidget* widget = Application::getInstance()->getGLWidget();
|
||||
Application* application = Application::getInstance();
|
||||
MyAvatar* avatar = application->getAvatar();
|
||||
QGLWidget* widget = application->getGLWidget();
|
||||
QPoint pos;
|
||||
// Get directon relative to avatar orientation
|
||||
glm::vec3 direction = glm::inverse(avatar->getOrientation()) * palm->getFingerDirection();
|
||||
|
@ -374,14 +375,14 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
|||
if (_bumperPressed[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, bumperButton, bumperButton, 0);
|
||||
|
||||
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
|
||||
application->mouseReleaseEvent(&mouseEvent);
|
||||
|
||||
_bumperPressed[index] = false;
|
||||
}
|
||||
if (_triggerPressed[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, triggerButton, triggerButton, 0);
|
||||
|
||||
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
|
||||
application->mouseReleaseEvent(&mouseEvent);
|
||||
|
||||
_triggerPressed[index] = false;
|
||||
}
|
||||
|
@ -396,17 +397,28 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
|||
//This is specifically for edit voxels
|
||||
if (triggerButton == Qt::LeftButton) {
|
||||
if (!_triggerPressed[(int)(!index)]) {
|
||||
Application::getInstance()->mouseMoveEvent(&mouseEvent);
|
||||
application->mouseMoveEvent(&mouseEvent);
|
||||
}
|
||||
} else {
|
||||
if (!_bumperPressed[(int)(!index)]) {
|
||||
Application::getInstance()->mouseMoveEvent(&mouseEvent);
|
||||
application->mouseMoveEvent(&mouseEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
_oldX[index] = pos.x();
|
||||
_oldY[index] = pos.y();
|
||||
|
||||
|
||||
//We need separate coordinates for clicks, since we need to check if
|
||||
//a magnification window was clicked on
|
||||
int clickX = pos.x();
|
||||
int clickY = pos.y();
|
||||
//Checks for magnification window click
|
||||
application->getApplicationOverlay().getClickLocation(clickX, clickY);
|
||||
//Set pos to the new click location, which may be the same if no magnification window is open
|
||||
pos.setX(clickX);
|
||||
pos.setY(clickY);
|
||||
|
||||
//Check for bumper press ( Right Click )
|
||||
if (palm->getControllerButtons() & BUTTON_FWD) {
|
||||
if (!_bumperPressed[index]) {
|
||||
|
@ -414,12 +426,12 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
|||
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, bumperButton, bumperButton, 0);
|
||||
|
||||
Application::getInstance()->mousePressEvent(&mouseEvent);
|
||||
application->mousePressEvent(&mouseEvent);
|
||||
}
|
||||
} else if (_bumperPressed[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, bumperButton, bumperButton, 0);
|
||||
|
||||
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
|
||||
application->mouseReleaseEvent(&mouseEvent);
|
||||
|
||||
_bumperPressed[index] = false;
|
||||
}
|
||||
|
@ -431,12 +443,12 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
|
|||
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, triggerButton, triggerButton, 0);
|
||||
|
||||
Application::getInstance()->mousePressEvent(&mouseEvent);
|
||||
application->mousePressEvent(&mouseEvent);
|
||||
}
|
||||
} else if (_triggerPressed[index]) {
|
||||
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, triggerButton, triggerButton, 0);
|
||||
|
||||
Application::getInstance()->mouseReleaseEvent(&mouseEvent);
|
||||
application->mouseReleaseEvent(&mouseEvent);
|
||||
|
||||
_triggerPressed[index] = false;
|
||||
}
|
||||
|
|
41
interface/src/scripting/AccountScriptingInterface.cpp
Normal file
41
interface/src/scripting/AccountScriptingInterface.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// AccountScriptingInterface.cpp
|
||||
// interface/src/scripting
|
||||
//
|
||||
// Created by Stojce Slavkovski on 6/07/14.
|
||||
// Copyright 2014 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
|
||||
//
|
||||
|
||||
#include "AccountManager.h"
|
||||
|
||||
#include "AccountScriptingInterface.h"
|
||||
|
||||
AccountScriptingInterface::AccountScriptingInterface() {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
connect(&accountManager, &AccountManager::balanceChanged, this,
|
||||
&AccountScriptingInterface::updateBalance);
|
||||
|
||||
}
|
||||
|
||||
AccountScriptingInterface* AccountScriptingInterface::getInstance() {
|
||||
static AccountScriptingInterface sharedInstance;
|
||||
return &sharedInstance;
|
||||
}
|
||||
|
||||
float AccountScriptingInterface::getBalance() {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
return accountManager.getAccountInfo().getBalanceInSatoshis();
|
||||
}
|
||||
|
||||
bool AccountScriptingInterface::isLoggedIn() {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
return accountManager.isLoggedIn();
|
||||
}
|
||||
|
||||
void AccountScriptingInterface::updateBalance() {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
emit balanceChanged(accountManager.getAccountInfo().getBalanceInSatoshis());
|
||||
}
|
31
interface/src/scripting/AccountScriptingInterface.h
Normal file
31
interface/src/scripting/AccountScriptingInterface.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// AccountScriptingInterface.h
|
||||
// interface/src/scripting
|
||||
//
|
||||
// Created by Stojce Slavkovski on 6/07/14.
|
||||
// Copyright 2014 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
|
||||
//
|
||||
|
||||
#ifndef hifi_AccountScriptingInterface_h
|
||||
#define hifi_AccountScriptingInterface_h
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class AccountScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
AccountScriptingInterface();
|
||||
|
||||
signals:
|
||||
void balanceChanged(float newBalance);
|
||||
|
||||
public slots:
|
||||
static AccountScriptingInterface* getInstance();
|
||||
float getBalance();
|
||||
bool isLoggedIn();
|
||||
void updateBalance();
|
||||
};
|
||||
|
||||
#endif // hifi_AccountScriptingInterface_h
|
|
@ -20,6 +20,13 @@
|
|||
|
||||
#include "ui/Stats.h"
|
||||
|
||||
// Used to fade the UI
|
||||
const float FADE_SPEED = 0.08f;
|
||||
// Used to animate the magnification windows
|
||||
const float MAG_SPEED = 0.08f;
|
||||
|
||||
const quint64 MSECS_TO_USECS = 1000ULL;
|
||||
|
||||
// Fast helper functions
|
||||
inline float max(float a, float b) {
|
||||
return (a > b) ? a : b;
|
||||
|
@ -31,11 +38,14 @@ inline float min(float a, float b) {
|
|||
|
||||
ApplicationOverlay::ApplicationOverlay() :
|
||||
_framebufferObject(NULL),
|
||||
_oculusAngle(65.0f * RADIANS_PER_DEGREE),
|
||||
_distance(0.5f),
|
||||
_textureFov(DEFAULT_OCULUS_UI_ANGULAR_SIZE * RADIANS_PER_DEGREE),
|
||||
_crosshairTexture(0) {
|
||||
_crosshairTexture(0),
|
||||
_alpha(1.0f),
|
||||
_active(true) {
|
||||
|
||||
memset(_reticleActive, 0, sizeof(_reticleActive));
|
||||
memset(_magActive, 0, sizeof(_reticleActive));
|
||||
memset(_magSizeMult, 0, sizeof(_magSizeMult));
|
||||
}
|
||||
|
||||
ApplicationOverlay::~ApplicationOverlay() {
|
||||
|
@ -45,11 +55,11 @@ ApplicationOverlay::~ApplicationOverlay() {
|
|||
}
|
||||
|
||||
const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f };
|
||||
|
||||
const float RETICLE_COLOR[] = { 0.0f, 198.0f / 255.0f, 244.0f / 255.0f };
|
||||
|
||||
// Renders the overlays either to a texture or to the screen
|
||||
void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
||||
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
||||
|
||||
_textureFov = Menu::getInstance()->getOculusUIAngularSize() * RADIANS_PER_DEGREE;
|
||||
|
@ -60,6 +70,19 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
QGLWidget* glWidget = application->getGLWidget();
|
||||
MyAvatar* myAvatar = application->getAvatar();
|
||||
|
||||
//Handle fadeing and deactivation/activation of UI
|
||||
if (_active) {
|
||||
_alpha += FADE_SPEED;
|
||||
if (_alpha > 1.0f) {
|
||||
_alpha = 1.0f;
|
||||
}
|
||||
} else {
|
||||
_alpha -= FADE_SPEED;
|
||||
if (_alpha <= 0.0f) {
|
||||
_alpha = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (renderToTexture) {
|
||||
getFramebufferObject()->bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
@ -67,6 +90,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
// Render 2D overlay
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
|
@ -93,6 +117,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
|
@ -104,7 +129,11 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
}
|
||||
|
||||
// Draws the FBO texture for the screen
|
||||
void ApplicationOverlay::displayOverlayTexture(Camera& whichCamera) {
|
||||
void ApplicationOverlay::displayOverlayTexture() {
|
||||
|
||||
if (_alpha == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Application* application = Application::getInstance();
|
||||
QGLWidget* glWidget = application->getGLWidget();
|
||||
|
@ -120,13 +149,16 @@ void ApplicationOverlay::displayOverlayTexture(Camera& whichCamera) {
|
|||
gluOrtho2D(0, glWidget->width(), glWidget->height(), 0);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, _alpha);
|
||||
glTexCoord2f(0, 0); glVertex2i(0, glWidget->height());
|
||||
glTexCoord2f(1, 0); glVertex2i(glWidget->width(), glWidget->height());
|
||||
glTexCoord2f(1, 1); glVertex2i(glWidget->width(), 0);
|
||||
glTexCoord2f(0, 1); glVertex2i(0, 0);
|
||||
glEnd();
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
glPopMatrix();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
@ -149,15 +181,42 @@ void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& direc
|
|||
direction = glm::normalize(rot * glm::vec3(x, y, z));
|
||||
}
|
||||
|
||||
// Calculates the click location on the screen by taking into account any
|
||||
// opened magnification windows.
|
||||
void ApplicationOverlay::getClickLocation(int &x, int &y) const {
|
||||
int dx;
|
||||
int dy;
|
||||
const float xRange = MAGNIFY_WIDTH * MAGNIFY_MULT / 2.0f;
|
||||
const float yRange = MAGNIFY_WIDTH * MAGNIFY_MULT / 2.0f;
|
||||
|
||||
//Loop through all magnification windows
|
||||
for (int i = 0; i < NUMBER_OF_MAGNIFIERS; i++) {
|
||||
if (_magActive[i]) {
|
||||
dx = x - _magX[i];
|
||||
dy = y - _magY[i];
|
||||
//Check to see if they clicked inside a mag window
|
||||
if (abs(dx) <= xRange && abs(dy) <= yRange) {
|
||||
//Move the click to the actual UI location by inverting the magnification
|
||||
x = dx / MAGNIFY_MULT + _magX[i];
|
||||
y = dy / MAGNIFY_MULT + _magY[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draws the FBO texture for Oculus rift. TODO: Draw a curved texture instead of plane.
|
||||
void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
||||
|
||||
if (_alpha == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Application* application = Application::getInstance();
|
||||
|
||||
MyAvatar* myAvatar = application->getAvatar();
|
||||
const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation();
|
||||
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
@ -185,21 +244,37 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
|||
glTranslatef(pos.x, pos.y, pos.z);
|
||||
glRotatef(glm::degrees(glm::angle(rot)), axis.x, axis.y, axis.z);
|
||||
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.01f);
|
||||
|
||||
//Draw the magnifiers
|
||||
for (int i = 0; i < _numMagnifiers; i++) {
|
||||
renderMagnifier(_mouseX[i], _mouseY[i]);
|
||||
//Update and draw the magnifiers
|
||||
for (int i = 0; i < NUMBER_OF_MAGNIFIERS; i++) {
|
||||
|
||||
if (_magActive[i]) {
|
||||
_magSizeMult[i] += MAG_SPEED;
|
||||
if (_magSizeMult[i] > 1.0f) {
|
||||
_magSizeMult[i] = 1.0f;
|
||||
}
|
||||
} else {
|
||||
_magSizeMult[i] -= MAG_SPEED;
|
||||
if (_magSizeMult[i] < 0.0f) {
|
||||
_magSizeMult[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (_magSizeMult[i] > 0.0f) {
|
||||
//Render magnifier, but dont show border for mouse magnifier
|
||||
renderMagnifier(_magX[i], _magY[i], _magSizeMult[i], i != MOUSE);
|
||||
}
|
||||
}
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, _alpha);
|
||||
|
||||
renderTexturedHemisphere();
|
||||
|
||||
renderControllerPointersOculus();
|
||||
|
@ -213,13 +288,13 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
|||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
}
|
||||
|
||||
//Renders optional pointers
|
||||
void ApplicationOverlay::renderPointers() {
|
||||
Application* application = Application::getInstance();
|
||||
// Render a crosshair over the mouse when in Oculus
|
||||
_numMagnifiers = 0;
|
||||
|
||||
//lazily load crosshair texture
|
||||
if (_crosshairTexture == 0) {
|
||||
|
@ -233,11 +308,20 @@ void ApplicationOverlay::renderPointers() {
|
|||
|
||||
if (OculusManager::isConnected() && application->getLastMouseMoveType() == QEvent::MouseMove) {
|
||||
//If we are in oculus, render reticle later
|
||||
_numMagnifiers = 1;
|
||||
_mouseX[0] = application->getMouseX();
|
||||
_mouseY[0] = application->getMouseY();
|
||||
_reticleActive[MOUSE] = true;
|
||||
_magActive[MOUSE] = true;
|
||||
_mouseX[MOUSE] = application->getMouseX();
|
||||
_mouseY[MOUSE] = application->getMouseY();
|
||||
_magX[MOUSE] = _mouseX[MOUSE];
|
||||
_magY[MOUSE] = _mouseY[MOUSE];
|
||||
|
||||
_reticleActive[LEFT_CONTROLLER] = false;
|
||||
_reticleActive[RIGHT_CONTROLLER] = false;
|
||||
|
||||
} else if (application->getLastMouseMoveType() == CONTROLLER_MOVE_EVENT && Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) {
|
||||
//only render controller pointer if we aren't already rendering a mouse pointer
|
||||
_reticleActive[MOUSE] = false;
|
||||
_magActive[MOUSE] = false;
|
||||
renderControllerPointers();
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
@ -250,9 +334,18 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
QGLWidget* glWidget = application->getGLWidget();
|
||||
MyAvatar* myAvatar = application->getAvatar();
|
||||
|
||||
//Static variables used for storing controller state
|
||||
static quint64 pressedTime[NUMBER_OF_MAGNIFIERS] = { 0ULL, 0ULL, 0ULL };
|
||||
static bool isPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
||||
static bool stateWhenPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
||||
static bool triggerPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
||||
static bool bumperPressed[NUMBER_OF_MAGNIFIERS] = { false, false, false };
|
||||
|
||||
const HandData* handData = Application::getInstance()->getAvatar()->getHandData();
|
||||
|
||||
for (unsigned int palmIndex = 2; palmIndex < 4; palmIndex++) {
|
||||
const int index = palmIndex - 1;
|
||||
|
||||
const PalmData* palmData = NULL;
|
||||
|
||||
if (palmIndex >= handData->getPalms().size()) {
|
||||
|
@ -265,6 +358,51 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
continue;
|
||||
}
|
||||
|
||||
int controllerButtons = palmData->getControllerButtons();
|
||||
|
||||
//Check for if we should toggle or drag the magnification window
|
||||
if (controllerButtons & BUTTON_3) {
|
||||
if (isPressed[index] == false) {
|
||||
//We are now dragging the window
|
||||
isPressed[index] = true;
|
||||
//set the pressed time in us
|
||||
pressedTime[index] = usecTimestampNow();
|
||||
stateWhenPressed[index] = _magActive[index];
|
||||
}
|
||||
} else if (isPressed[index]) {
|
||||
isPressed[index] = false;
|
||||
//If the button was only pressed for < 250 ms
|
||||
//then disable it.
|
||||
|
||||
const int MAX_BUTTON_PRESS_TIME = 250 * MSECS_TO_USECS;
|
||||
if (usecTimestampNow() - pressedTime[index] < MAX_BUTTON_PRESS_TIME) {
|
||||
_magActive[index] = !stateWhenPressed[index];
|
||||
}
|
||||
}
|
||||
|
||||
//Check for UI active toggle
|
||||
if (palmData->getTrigger() == 1.0f) {
|
||||
if (!triggerPressed[index]) {
|
||||
if (bumperPressed[index]) {
|
||||
_active = !_active;
|
||||
}
|
||||
triggerPressed[index] = true;
|
||||
}
|
||||
} else {
|
||||
triggerPressed[index] = false;
|
||||
}
|
||||
if ((controllerButtons & BUTTON_FWD)) {
|
||||
if (!bumperPressed[index]) {
|
||||
if (triggerPressed[index]) {
|
||||
_active = !_active;
|
||||
}
|
||||
bumperPressed[index] = true;
|
||||
}
|
||||
} else {
|
||||
bumperPressed[index] = false;
|
||||
}
|
||||
|
||||
|
||||
// Get directon relative to avatar orientation
|
||||
glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * palmData->getFingerDirection();
|
||||
|
||||
|
@ -280,34 +418,42 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
|
||||
//If the cursor is out of the screen then don't render it
|
||||
if (mouseX < 0 || mouseX >= glWidget->width() || mouseY < 0 || mouseY >= glWidget->height()) {
|
||||
_reticleActive[index] = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
float pointerWidth = 40;
|
||||
float pointerHeight = 40;
|
||||
_reticleActive[index] = true;
|
||||
|
||||
//if we have the oculus, we should make the cursor smaller since it will be
|
||||
//magnified
|
||||
if (OculusManager::isConnected()) {
|
||||
|
||||
_mouseX[index] = mouseX;
|
||||
_mouseY[index] = mouseY;
|
||||
|
||||
_mouseX[_numMagnifiers] = mouseX;
|
||||
_mouseY[_numMagnifiers] = mouseY;
|
||||
_numMagnifiers++;
|
||||
//If oculus is enabled, we draw the crosshairs later
|
||||
//When button 2 is pressed we drag the mag window
|
||||
if (isPressed[index]) {
|
||||
_magActive[index] = true;
|
||||
_magX[index] = mouseX;
|
||||
_magY[index] = mouseY;
|
||||
}
|
||||
|
||||
// If oculus is enabled, we draw the crosshairs later
|
||||
continue;
|
||||
}
|
||||
|
||||
mouseX -= pointerWidth / 2.0f;
|
||||
mouseY += pointerHeight / 2.0f;
|
||||
const float reticleSize = 40.0f;
|
||||
|
||||
mouseX -= reticleSize / 2.0f;
|
||||
mouseY += reticleSize / 2.0f;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2]);
|
||||
|
||||
glTexCoord2d(0.0f, 0.0f); glVertex2i(mouseX, mouseY);
|
||||
glTexCoord2d(1.0f, 0.0f); glVertex2i(mouseX + pointerWidth, mouseY);
|
||||
glTexCoord2d(1.0f, 1.0f); glVertex2i(mouseX + pointerWidth, mouseY - pointerHeight);
|
||||
glTexCoord2d(0.0f, 1.0f); glVertex2i(mouseX, mouseY - pointerHeight);
|
||||
glTexCoord2d(1.0f, 0.0f); glVertex2i(mouseX + reticleSize, mouseY);
|
||||
glTexCoord2d(1.0f, 1.0f); glVertex2i(mouseX + reticleSize, mouseY - reticleSize);
|
||||
glTexCoord2d(0.0f, 1.0f); glVertex2i(mouseX, mouseY - reticleSize);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
@ -325,7 +471,12 @@ void ApplicationOverlay::renderControllerPointersOculus() {
|
|||
glBindTexture(GL_TEXTURE_2D, _crosshairTexture);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
for (int i = 0; i < _numMagnifiers; i++) {
|
||||
for (int i = 0; i < NUMBER_OF_MAGNIFIERS; i++) {
|
||||
|
||||
//Dont render the reticle if its inactive
|
||||
if (!_reticleActive[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float mouseX = (float)_mouseX[i];
|
||||
float mouseY = (float)_mouseY[i];
|
||||
|
@ -360,7 +511,7 @@ void ApplicationOverlay::renderControllerPointersOculus() {
|
|||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2]);
|
||||
glColor4f(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], _alpha);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(lX, tY, -tlZ);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex3f(rX, tY, -trZ);
|
||||
|
@ -374,24 +525,22 @@ void ApplicationOverlay::renderControllerPointersOculus() {
|
|||
}
|
||||
|
||||
//Renders a small magnification of the currently bound texture at the coordinates
|
||||
void ApplicationOverlay::renderMagnifier(int mouseX, int mouseY)
|
||||
void ApplicationOverlay::renderMagnifier(int mouseX, int mouseY, float sizeMult, bool showBorder) const
|
||||
{
|
||||
Application* application = Application::getInstance();
|
||||
QGLWidget* glWidget = application->getGLWidget();
|
||||
|
||||
|
||||
const int widgetWidth = glWidget->width();
|
||||
const int widgetHeight = glWidget->height();
|
||||
const float magnification = 4.0f;
|
||||
|
||||
float magnifyWidth = 80.0f;
|
||||
float magnifyHeight = 60.0f;
|
||||
const float magnifyWidth = MAGNIFY_WIDTH * sizeMult;
|
||||
const float magnifyHeight = MAGNIFY_HEIGHT * sizeMult;
|
||||
|
||||
mouseX -= magnifyWidth / 2;
|
||||
mouseY -= magnifyHeight / 2;
|
||||
|
||||
float newWidth = magnifyWidth * magnification;
|
||||
float newHeight = magnifyHeight * magnification;
|
||||
float newWidth = magnifyWidth * MAGNIFY_MULT;
|
||||
float newHeight = magnifyHeight * MAGNIFY_MULT;
|
||||
|
||||
// Magnification Texture Coordinates
|
||||
float magnifyULeft = mouseX / (float)widgetWidth;
|
||||
|
@ -417,19 +566,60 @@ void ApplicationOverlay::renderMagnifier(int mouseX, int mouseY)
|
|||
float bY = sin((newVBottom - 0.5f) * _textureFov);
|
||||
float tY = sin((newVTop - 0.5f) * _textureFov);
|
||||
|
||||
float blZ, tlZ, brZ, trZ;
|
||||
|
||||
float dist;
|
||||
float discriminant;
|
||||
//Bottom Left
|
||||
dist = sqrt(lX * lX + bY * bY);
|
||||
float blZ = sqrt(1.0f - dist * dist);
|
||||
discriminant = 1.0f - dist * dist;
|
||||
if (discriminant > 0) {
|
||||
blZ = sqrt(discriminant);
|
||||
} else {
|
||||
blZ = 0;
|
||||
}
|
||||
//Top Left
|
||||
dist = sqrt(lX * lX + tY * tY);
|
||||
float tlZ = sqrt(1.0f - dist * dist);
|
||||
discriminant = 1.0f - dist * dist;
|
||||
if (discriminant > 0) {
|
||||
tlZ = sqrt(discriminant);
|
||||
} else {
|
||||
tlZ = 0;
|
||||
}
|
||||
//Bottom Right
|
||||
dist = sqrt(rX * rX + bY * bY);
|
||||
float brZ = sqrt(1.0f - dist * dist);
|
||||
discriminant = 1.0f - dist * dist;
|
||||
if (discriminant > 0) {
|
||||
brZ = sqrt(discriminant);
|
||||
} else {
|
||||
brZ = 0;
|
||||
}
|
||||
//Top Right
|
||||
dist = sqrt(rX * rX + tY * tY);
|
||||
float trZ = sqrt(1.0f - dist * dist);
|
||||
discriminant = 1.0f - dist * dist;
|
||||
if (discriminant > 0) {
|
||||
trZ = sqrt(discriminant);
|
||||
} else {
|
||||
trZ = 0;
|
||||
}
|
||||
|
||||
if (showBorder) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glLineWidth(1.0f);
|
||||
//Outer Line
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glColor4f(1.0f, 0.0f, 0.0f, _alpha);
|
||||
|
||||
glVertex3f(lX, tY, -tlZ);
|
||||
glVertex3f(rX, tY, -trZ);
|
||||
glVertex3f(rX, bY, -brZ);
|
||||
glVertex3f(lX, bY, -blZ);
|
||||
glVertex3f(lX, tY, -tlZ);
|
||||
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
glColor4f(1.0f, 1.0f, 1.0f, _alpha);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
class Overlays;
|
||||
class QOpenGLFramebufferObject;
|
||||
|
||||
const float MAGNIFY_WIDTH = 160.0f;
|
||||
const float MAGNIFY_HEIGHT = 80.0f;
|
||||
const float MAGNIFY_MULT = 4.0f;
|
||||
|
||||
// Handles the drawing of the overlays to the screen
|
||||
class ApplicationOverlay {
|
||||
public:
|
||||
|
@ -23,12 +27,14 @@ public:
|
|||
~ApplicationOverlay();
|
||||
|
||||
void renderOverlay(bool renderToTexture = false);
|
||||
void displayOverlayTexture(Camera& whichCamera);
|
||||
void displayOverlayTexture();
|
||||
void displayOverlayTextureOculus(Camera& whichCamera);
|
||||
void computeOculusPickRay(float x, float y, glm::vec3& direction) const;
|
||||
void getClickLocation(int &x, int &y) const;
|
||||
|
||||
// Getters
|
||||
QOpenGLFramebufferObject* getFramebufferObject();
|
||||
float getAlpha() const { return _alpha; }
|
||||
|
||||
private:
|
||||
// Interleaved vertex data
|
||||
|
@ -42,20 +48,27 @@ private:
|
|||
void renderPointers();
|
||||
void renderControllerPointers();
|
||||
void renderControllerPointersOculus();
|
||||
void renderMagnifier(int mouseX, int mouseY);
|
||||
void renderMagnifier(int mouseX, int mouseY, float sizeMult, bool showBorder) const;
|
||||
void renderAudioMeter();
|
||||
void renderStatsAndLogs();
|
||||
void renderTexturedHemisphere();
|
||||
|
||||
QOpenGLFramebufferObject* _framebufferObject;
|
||||
float _trailingAudioLoudness;
|
||||
float _oculusAngle;
|
||||
float _distance;
|
||||
float _textureFov;
|
||||
int _mouseX[2];
|
||||
int _mouseY[2];
|
||||
int _numMagnifiers;
|
||||
|
||||
enum MagnifyDevices { MOUSE, LEFT_CONTROLLER, RIGHT_CONTROLLER, NUMBER_OF_MAGNIFIERS = RIGHT_CONTROLLER + 1 };
|
||||
bool _reticleActive[NUMBER_OF_MAGNIFIERS];
|
||||
int _mouseX[NUMBER_OF_MAGNIFIERS];
|
||||
int _mouseY[NUMBER_OF_MAGNIFIERS];
|
||||
bool _magActive[NUMBER_OF_MAGNIFIERS];
|
||||
int _magX[NUMBER_OF_MAGNIFIERS];
|
||||
int _magY[NUMBER_OF_MAGNIFIERS];
|
||||
float _magSizeMult[NUMBER_OF_MAGNIFIERS];
|
||||
|
||||
float _alpha;
|
||||
bool _active;
|
||||
|
||||
GLuint _crosshairTexture;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ Glyph::Glyph(int textureID, const QPoint& location, const QRect& bounds, int wid
|
|||
}
|
||||
|
||||
TextRenderer::TextRenderer(const char* family, int pointSize, int weight,
|
||||
bool italic, EffectType effectType, int effectThickness)
|
||||
bool italic, EffectType effectType, int effectThickness, QColor color)
|
||||
: _font(family, pointSize, weight, italic), _metrics(_font), _effectType(effectType),
|
||||
_effectThickness(effectThickness), _x(IMAGE_SIZE), _y(IMAGE_SIZE), _rowHeight(0) {
|
||||
_effectThickness(effectThickness), _x(IMAGE_SIZE), _y(IMAGE_SIZE), _rowHeight(0), _color(color) {
|
||||
_font.setKerning(false);
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ const Glyph& TextRenderer::getGlyph(char c) {
|
|||
// render the glyph into an image and copy it into the texture
|
||||
QImage image(bounds.width(), bounds.height(), QImage::Format_ARGB32);
|
||||
if (c == SOLID_BLOCK_CHAR) {
|
||||
image.fill(QColor(255, 255, 255));
|
||||
image.fill(_color);
|
||||
|
||||
} else {
|
||||
image.fill(0);
|
||||
|
@ -180,7 +180,7 @@ const Glyph& TextRenderer::getGlyph(char c) {
|
|||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.drawPath(path);
|
||||
}
|
||||
painter.setPen(QColor(255, 255, 255));
|
||||
painter.setPen(_color);
|
||||
painter.drawText(-bounds.x(), -bounds.y(), ch);
|
||||
}
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, _x, _y, bounds.width(), bounds.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef hifi_TextRenderer_h
|
||||
#define hifi_TextRenderer_h
|
||||
|
||||
#include <QColor>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QHash>
|
||||
|
@ -41,7 +42,8 @@ public:
|
|||
enum EffectType { NO_EFFECT, SHADOW_EFFECT, OUTLINE_EFFECT };
|
||||
|
||||
TextRenderer(const char* family, int pointSize = -1, int weight = -1, bool italic = false,
|
||||
EffectType effect = NO_EFFECT, int effectThickness = 1);
|
||||
EffectType effect = NO_EFFECT, int effectThickness = 1,
|
||||
QColor color = QColor(255, 255, 255));
|
||||
~TextRenderer();
|
||||
|
||||
const QFontMetrics& metrics() const { return _metrics; }
|
||||
|
@ -85,6 +87,9 @@ private:
|
|||
|
||||
// the list of all texture ids for which we're responsible
|
||||
QVector<GLuint> _allTextureIDs;
|
||||
|
||||
// text color
|
||||
QColor _color;
|
||||
};
|
||||
|
||||
class Glyph {
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
TextOverlay::TextOverlay() :
|
||||
_leftMargin(DEFAULT_MARGIN),
|
||||
_topMargin(DEFAULT_MARGIN)
|
||||
_topMargin(DEFAULT_MARGIN),
|
||||
_fontSize(DEFAULT_FONTSIZE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -32,7 +33,7 @@ void TextOverlay::render() {
|
|||
}
|
||||
|
||||
const float MAX_COLOR = 255;
|
||||
glColor4f(_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, _alpha);
|
||||
glColor4f(0 / MAX_COLOR, 0 / MAX_COLOR, 0 / MAX_COLOR, _alpha);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(_bounds.left(), _bounds.top());
|
||||
|
@ -43,8 +44,9 @@ void TextOverlay::render() {
|
|||
|
||||
//TextRenderer(const char* family, int pointSize = -1, int weight = -1, bool italic = false,
|
||||
// EffectType effect = NO_EFFECT, int effectThickness = 1);
|
||||
|
||||
TextRenderer textRenderer(SANS_FONT_FAMILY, 11, 50);
|
||||
TextRenderer textRenderer(SANS_FONT_FAMILY, _fontSize, 50, false, TextRenderer::NO_EFFECT, 1,
|
||||
QColor(_color.red, _color.green, _color.blue));
|
||||
|
||||
const int leftAdjust = -1; // required to make text render relative to left edge of bounds
|
||||
const int topAdjust = -2; // required to make text render relative to top edge of bounds
|
||||
int x = _bounds.left() + _leftMargin + leftAdjust;
|
||||
|
@ -67,6 +69,13 @@ void TextOverlay::render() {
|
|||
|
||||
void TextOverlay::setProperties(const QScriptValue& properties) {
|
||||
Overlay2D::setProperties(properties);
|
||||
|
||||
QScriptValue font = properties.property("font");
|
||||
if (font.isObject()) {
|
||||
if (font.property("size").isValid()) {
|
||||
setFontSize(font.property("size").toInt32());
|
||||
}
|
||||
}
|
||||
|
||||
QScriptValue text = properties.property("text");
|
||||
if (text.isValid()) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "Overlay2D.h"
|
||||
|
||||
const int DEFAULT_MARGIN = 10;
|
||||
const int DEFAULT_FONTSIZE = 11;
|
||||
|
||||
class TextOverlay : public Overlay2D {
|
||||
Q_OBJECT
|
||||
|
@ -47,6 +48,7 @@ public:
|
|||
void setText(const QString& text) { _text = text; }
|
||||
void setLeftMargin(int margin) { _leftMargin = margin; }
|
||||
void setTopMargin(int margin) { _topMargin = margin; }
|
||||
void setFontSize(int fontSize) { _fontSize = fontSize; }
|
||||
|
||||
virtual void setProperties(const QScriptValue& properties);
|
||||
|
||||
|
@ -55,7 +57,7 @@ private:
|
|||
QString _text;
|
||||
int _leftMargin;
|
||||
int _topMargin;
|
||||
|
||||
int _fontSize;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
void setDiscourseApiKey(const QString& discourseApiKey);
|
||||
|
||||
qint64 getBalance() const { return _balance; }
|
||||
float getBalanceInSatoshis() const { return _balance / SATOSHIS_PER_CREDIT; }
|
||||
void setBalance(qint64 balance);
|
||||
bool hasBalance() const { return _hasBalance; }
|
||||
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
|
||||
|
|
Loading…
Reference in a new issue